如果希望一个类在软件内只能有一个对象,则可以使用单例模式;
其实单例模式有点类似封装,但不同点在于,单例模式的实例化的代码在类里面就写好了
设计单例模式步骤:
第一步:将类的构造方法私有化(用private来修饰构造方法);
第二步:私有了构造方法,外部就不能通过构造方法来创建这个类的实例,这也是我们希望的,我们通过在内部创建一个实例;可以是直接创建实例(直接法);也可以是在调用获取对象的方法时创建这个实例(条件法);
第三步:写一个第二步中所说的获取对象的方法,用来外部来获得内部创建的实例;这个方法的要求:①不能私有化②返回值类型是这个类,即返回的是一个对象;③必须是静态的;ps:为什么必须是静态的?因为没有构造器,外部没法通过创建对象来调用非静态方法,只能通过类来调静态方法;
例01:(直接法)
class Person {
private Person(){} //私有化构造器
private static Person LIU=new Person(); //在声明时直接创建一个对象
public static Person getObject(){ //这个方法就是外部来获得对象的方法
return LIU;
}
//写一个非晶态方法,只能通过对象调用
void eat(){
System.out.println("I can eat.");
}
}
//测试类
public class TestDome {
public static void main(String[] args) {
Person p1;
p1=Person.getObject(); //静态调用getObject()方法来获得对象,此时p1成为一个对象,它的地址与 Person类中的LIU一样
p1.eat(); //可以通过对象来调用非静态方法了
Person p2=Person.getObject(); //再创建一个p2来验证Person类是单例的
System.out.println(p1.equals(p2)); //返回true,说明p1与p2地址是一样的,也就是说都是Person类中的单例
}
}
输出结果:
I can eat.
true
例02(条件法)
//条件法基本原理与直接法相同,只是在类中实例化的地方不同,我们把实例化的代码放在getObject()中,用一个if体包装,这样只有在调用的时候才会创建实例化对象,避免了直接法一上来就实例化对象占用内存,代码更灵活;
只需要把例01(直接法)中的Person类改为如下:
public class Person {
private Person(){}
private static Person LIU; //只声明,不创建对象,此时LIU中为空
public static Person getObject(){
if(LIU==null){ //if条件语句包装,外部调用getObject()方法时因为LIU是空,所以进入if实例化
LIU=new Person();
}
return LIU;
}
void eat(){
System.out.println("I can eat.");
}
}
Test Dome的执行结果与例01相同:
I can eat.
true