java基础学习之包及访问控制权限(四)

基本概念

  • 包及访问控制权限
    • 包的定义
    • 包的导入
    • 访问控制权限
    • 单例设计模式(Singleton)
    • 多例设计模式

包及访问控制权限

包的定义

所谓的包实际上指的就是文件夹。
定义包

// An highlighted block
package com.yootk.demo;
public class Hello{
     
	public static void main(String args[]){
     
		System.out.println("hello world");
	}
}

由上可知,Hello类定义在了一个com.yootk.demo包中
打包编译:javac -d .Hello.java

  • “-d”:生成目录,根据package的定义生成;
  • “.”:设置保存路径,表示在当前所在路径下生成。
    解释运行:java com.yootk.Hello
    注意:在解释运行程序的时候不要进入到包里面,应该在包外面输入类的完整名称(包.类)。

包的导入

使用import

// An highlighted block
package com.yootk.demo;
import com.yootk.util.Message;
public class Hello{
     
	public static void main(String args[]){
     
		System.out.println("hello world");
	}
}

如果存在多个*.java 文件中的类相互引用的情况,为了解决编译顺序的问题,提供了通配符 的操作:javac -d ..java,这样就会自动根据代码的调用顺序进行程序编译。
如果不使用通配符*,则进行二步操作

  • 第一步:首先编译Message.java文件,执行:javac -d .Message.java
  • 第二步:编译Hello.java文件,执行:javac -d .Hello.java
    导入一个包中的多个类
    import com.yootk.util.;
    导入一个包中的全部静态属性和方法
    import static com.yootk.util.
    ;
    注意:以上做法并不会导致性能问题,因为类加载时也只是加载所需要的类,不使用的类不会被加载,所以import com.yootk.util.Message 和 import com.yootk.util.*性能是一样的。

访问控制权限

NO. 范围 private default protected public
1 在同一个包的同一个类
2 同一包的不同类
3 不同包的子类
4 不同包的非子类

简单理解为:private只能在一个类中访问;default只能在一个包中访问;protected在不同包的子类中;public为所有都可以。

定义com.yootk.demoa.A类

// An highlighted block
package com.yootk.demoa;
public class A{
     
	protected String info = "Hello";
}

定义com.yootk.demoa.B类

// An highlighted block
package com.yootk.demoa;
import com.yootk.demoa.A
public class B extends A{
     
	public void print(){
     
		System.out.println("A类的info = "+super.info);
	}
}

那么一般情况下如何去选择权限呢?
答:属性声明主要使用private权限;方法声明主要使用public权限。

单例设计模式(Singleton)

在之前大部分的属性定义时都使用了private进行声明,而对于构造方法也可以使用private声明,则此时的构造方法就被私有化了。
构造方法非私有化

// An highlighted block
class Singleton{
     
    public void print(){
     
        System.out.println("Hello");
    }
}
public class Test {
     
    public static void main(String[] args) {
     
        Singleton singleton = null;
        singleton = new Singleton();
        singleton.print();
    }
}

私有化构造方法

// An highlighted block
package chapter5;
class Singleton{
     
    private Singleton(){
     
        
    }
    public void print(){
     
        System.out.println("Hello");
    }
}
public class Test {
     
    public static void main(String[] args) {
     
        Singleton singleton = null;
        singleton = new Singleton();
        singleton.print();
    }
}
程序出现了编译错误,因为构造方法被私有化了,无法在外部调用,即无法在外部实例化Singleton类的对象。

现在就需要思考:在保证Singleton类中的构造方法不修改不增加,以及print()方法不修改的情况下,如何操作才可以让类的外部通过实例化对象去调用print()方法?
思考过程一:使用private 访问权限定义的操作只能被本类所访问,外部无法调用,现在既然构造方法被私有化,就证明,这个类的构造方法只能被本类所调用,即只能在本类中产生本类实例化对象

// An highlighted block
package chapter5;
class Singleton{
     
	Singleton instance = new Singleton();
    private Singleton(){
     
       }
    public void print(){
     
        System.out.println("Hello");
    }
}

思考过程二:对于一个类中的普通属性,默认情况下一定要在本类存在实例化对象后才可以进行调用,可是本程序在Singleton类的外部无法产生实例化对象,就必须想一个办法,让Singleton类中的instance属性可以在没有Singleton类实例化对象时来进行调用。因此想到可以使用static完成。

// An highlighted block
package chapter5;
class Singleton{
     
    static Singleton instance = new Singleton();
    private Singleton(){
     

    }
    public void print(){
     
        System.out.println("Hello");
    }
}
public class Test {
     
    public static void main(String[] args) {
     
        Singleton singleton = null;
        singleton = Singleton.instance;			直接这样获得类的实例化对象
        singleton.print();
    }
}
结果:Hello

思考过程三:首先按之前的学习,类中的全部属性都应该封装,然后通过getter、setter去访问获取,只不过getter方法也定义为static型。

// An highlighted block
package chapter5;
class Singleton{
     
    static Singleton instance = new Singleton();
    private Singleton(){
     

    }
    public void print(){
     
        System.out.println("Hello");
    }
    public static Singleton getInstance(){
     
    	return instance;
    }
}
public class Test {
     
    public static void main(String[] args) {
     
        Singleton singleton = null;
        singleton = Singleton.getInstance();			直接这样获得类的实例化对象
        singleton.print();
    }
}

如果要调用类中定义的操作,那么很显然需要一个实例化对象,这时就可以在类的内部使用static方式来定义一个公共的对象,并且每一次通过static方法返回唯一的一个对象,这样外部不管有多少次调用,最终一个类只能产生唯一的一个对象,这样的设计就属于单例设计模式。

不过现在还有一个小问题,就是以下代码也可以使用

// An highlighted block
class Singleton{
     
    private static Singleton instance = new Singleton();
    private Singleton(){
     

    }
    public void print(){
     
        System.out.println("Hello");
    }
    public static Singleton getInstance(){
     
        instance = new Singleton();			//重新实例化对象
        return instance;
    }
}
public class Test {
     
    public static void main(String[] args) {
     
        Singleton singleton = null;
        singleton = Singleton.getInstance();
        singleton.print();
    }
}

所以可以尝试加一个final关键字

// An highlighted block
class Singleton{
     
    private final static Singleton instance = new Singleton();   //在这一行加就好了
    private Singleton(){
     

    }
    public void print(){
     
        System.out.println("Hello");
    }
    public static Singleton getInstance(){
     
        return instance;
    }
}
结果:Hello

多例设计模式

多例设计模式其实就是有限的定义多个对象。不管是单例设计还是多例设计,有一个核心不可动摇,就是构造方法私有化。

// An highlighted block
class Sex{
     
    private String title;
    private static final Sex MALE = new Sex("男");
    private static final Sex FEMALE = new Sex("女");
    private Sex(String title){
     
        this.title = title;
    }
    @Override
    public String toString(){
     
        return this.title;
    }
    
    public static Sex getInstance(int ch){
     
        switch (ch){
     
            case 1:
                return MALE;
            case 2:
                return FEMALE;
            default:
                return null;
        }
    }
}
public class Test {
     
    public static void main(String[] args) {
     
        Sex sex = null;
        sex = Sex.getInstance(2);
        System.out.println(sex);
    }
}
执行结果:女

在JDK1.7之前,switch只能利用int或者char进行判断,正因为如果纯粹是数字或字符意义不明确,所以增加了String的支持。

// An highlighted block
class Sex{
     
    private String title;
    private static final Sex MALE = new Sex("男");
    private static final Sex FEMALE = new Sex("女");
    private Sex(String title){
     
        this.title = title;
    }
    @Override
    public String toString(){
     
        return this.title;
    }
    
    public static Sex getInstance(String ch){
     
        switch (ch){
     
            case "man":
                return MALE;
            case "woman":
                return FEMALE;
            default:
                return null;
        }
    }
}
public class Test {
     
    public static void main(String[] args) {
     
        Sex sex = null;
        sex = Sex.getInstance("man");
        System.out.println(sex);
    }
}
执行结果:男

你可能感兴趣的:(JavaSE)