所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法
public class instance {
public static void main(String[] args) {
System.out.println(Singleton.getInstance());
//在调用Singleton中的age时,
// private static Singleton person = new Singleton("xx")中的person没有被使用
// 但是已经被创建(对象的创建供大于求,造成对象浪费)
System.out.println(Singleton.age);
//验证是否只创建了一个对象
}
}
class Singleton{
private String name;
public static int age = 100;
//为了能够在静态方法中,返回person对象,需要将其设为static(静态方法只能调用静态属性)
private static Singleton person = new Singleton("xx");
//如何保障只能创建一个Singleton对象:
//1.将构造器私有化
//2.在类的内部直接创建一个对象(静态对象)
//3.提供一个公共的static方法,返回person对象
private Singleton(String name) {
System.out.println("构造器被调用");
this.name = name;
}
public static Singleton getInstance(){
return person;
}
//因为person的编译类型为Singleton,所以返回person
//要使打印完美,则可以重写toString()方法
@Override
public String toString() {
return "Singleton{" +
"name='" + name + '\'' +
'}';
}
}
//懒汉式
//为了防止饿汉式对象的浪费,则引用懒汉式
//不调用时不创建对象,只有在需要时创建对象
//懒汉式,只有在第一次调用静态方法getInstance02()时,才会创建一个对象。从而保证单例
public class instance02 {
public static void main(String[] args) {
System.out.println(Singleton02.age02);
//不调用getInstance()时
// 对象不会被创建,则构造器不会被调用
Singleton02 person01 = Singleton02.getInstance02();
System.out.println(person01);
//再次调用getInstance()
//此时,person = "xx02";已经不为 Null ,所以在方法中直接返回,并未创建新对象
Singleton02 person02 = Singleton02.getInstance02();
System.out.println(person02);
//验证是否只创建了一个对象
System.out.println(person01 == person02);
}
}
//在程序运行过程中,只能创建一个person对象
//使用单例模式
class Singleton02{
private String name;
public static int age02 = 18;
private static Singleton02 person02 ;
//1.将构造器私有化
//2.定义一个静态属性
//3.提供一个公共的static方法
private Singleton02(String name) {
System.out.println("构造器被调用");
this.name = name;
}
public static Singleton02 getInstance02(){
if(person02==null){
person02 = new Singleton02("xx00");
}
return person02;
}
@Override
public String toString() {
return "Singleton02{" +
"name='" + name + '\'' +
'}';
}
}
1.二者最主要的区别在于创建对象的时机不同:饿汉式是在类加载就创建了对象实例,而懒汉式是在使用时才创建。
2.饿汉式不存在线程安全问题,懒汉式存在线程安全问题。
3.饿汉式存在浪费资源的可能。因为如果在程序中一个对象实例都没有使用,那么饿汉
式创建的对象就浪费了,懒汉式是使用时才创建,就不存在这个问题。
final 可以修饰类、属性、方法和局部变量.
在某些情况下,程序员可能有以下需求,就会使用到final:
1)当不希望类被继承时,可以用final修饰.
2)当不希望父类的某个方法被子类覆盖/重写(override)时,可以用final关键字修饰。
3)当不希望类的的某个属性的值被修改,可以用final修饰.
4)当不希望某个局部变量被修改,可以使用final修饰
5)一般来说,如果一个类已经是final类了,就没有必要再将方法修饰成final方法。
6) final不能修饰构造方法(即构造器)
7) final 和static往往搭配使用,效率更高,不会导致类加载.底层编译器做了优化处理。
8)包装类(Integer,Double,Float,Boolean等都是final),String也是final类。
final修饰的属性又叫常量,一般用XX XX XX来命名
final修饰的属性在定义时,必须赋初值,并且以后不能再修改,赋值可以在如下位置之一【选择一个位置赋初值即可】:
①定义时:如public final double TAX_RATE=0.08;
②在构造器中
③在代码块中。
如果final修饰的属性是静态的,则初始化的位置只能是
①定义时
②在静态代码块不能在构造器中赋值。
final类不能继承,但是可以实例化对象。
如果类不是final类,但是含有final方法,则该方法虽然不能重写,但是可以被继承。
public class Final {
public static void main(String[] args) {
System.out.println(C.num);
}
}
class C{
//final 和 static 搭配使用,提高效率,不会导致类加载,底层编译器做了优化处理
public final static int num = 1000;
static {
System.out.println("代码块被执行!");
}
}
/*打印结果:
1000
*/
5)一般来说,如果一个类已经是final类了,就没有必要再将方法修饰成final方法。6) final不能修饰构造方法(即构造器)
7) final 和static往往搭配使用,效率更高,不会导致类加载.底层编译器做了优化处理。
当父类的某些方法,需要声明,但是又不确定如何实现时,可以将其声明为抽象方法,那么这个类就是抽象类
抽象类使用的注意事项和细节讨论
1)抽象类不能被实例化
2)抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法
3)一旦类包含了abstract方法,则这个类必须声明为abstract
4) abstract 只能修饰类和方法,不能修饰属性和其它的
5)抽象类可以有任意成员【抽象类本质还是类】,比如:非抽象方法、构造器、静态属性等等
6)抽象方法不能有主体,即不能实现.
abstract void A(){
//此部分不能被实现!!!
}
7)如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,
除非它自己也声明为abstract类。
8)抽象方法不能使用private、final和static来修饰,因为这些关键字都是和重写相违背的,