一、单例设计模式:
解决一个类在内存中只存在一个对象。
用代码体现:
1,将构造方法私有化;
2,在类中创建一个本类对象;
3,提供一个方法可以获取到该对象。
1)饿汉式(开发一般用这个方式,安全简单):
class NumberMachine {
//instance一定是static的,因为,在实例还没创建之前,就要有这个对象。
private static NumberMachine instance = new NumberMachine();
private NumberMachine(){}
public static NumberMachine getInstance() {
return instance;
}
//…其他方法
}
饿汉式是先初始化对象。
2)懒汉式(不常用,面试常考):
懒汉式方法被调用时,才把对象初始化,也叫做对象的延时加载。
class NumberMachine {
private static NumberMachine instance = null;
private NumberMachine(){}
public static NumberMachine getInstance() {
if(instance == null)
instance = new NumberMachine();
}
//…其他方法
}
这个方式一般开发不用,因为可能有安全隐患,比如多个线程同时用到这个类,CPU执行语句时,到第一个线程的if(instance == null)时为true,准备创建对象,这时去执行第二个线程,碰巧遇到执行new一个该类的对象。这时再去第一个线程执行创建,就出现两个实例对象。而单例设计模式在程序过程中只能有一个实例对象。
因此,解决方案是给getInstance加一个Sychronized修饰(给该方法加锁):
…
public static Sychronized NumberMachine getInstance()
…
但加上Sychronized之后,程序的运行会变的低效。解决低效方式为:
public static NumberMachine getInstance() {
if(instance == null)
{
Sychronized(NumberMachine.class)
{
if(instance == null)
instance = new NumberMachine();
}
}
}
二、继承:
java中只支持单继承,不支持多继承(优化了C++的部分,但保留了这种机制,并用多实现的方式来体现),但接口之间可以多继承。
因为多继承容易带来安全隐患:当多个父类中定义了相同的功能,但功能内容不同时,子类不确定要执行哪一个。
java支持多层继承,也就是一个继承体系。
子父类中的构造函数:
在对子类对象进行初始化时,父类的构造函数也会运行,那是因为子类的构造函数默认第一行有一条隐式的语句super(),所以会先访问父类中空参数的构造函数,而且子类中所有的构造函数默认第一行都是super()。而且,如果父类中没有自定义空参数的构造函数,这一行就要手动写出来,并且super里面要传入父类中定义过的构造函数的参数。比如:
class Fu
{
Fu(int x)
{
System.out.println("Fu"+"...."+x);
}
}
class Zi extends Fu
{
Zi()
{
super();
System.out.println("Zi"+"....");
}
}
上面的super()注释和写出都会出错。因为Fu类中没有自定义空参数的构造方法。所以,要么在Fu类中加一个Fu(){},要么就是super里面传参数或值进去,显示调用父类有参数的构造函数。
那么,为什么子类一定要访问父类中的构造函数呢?
因为,父类中的数据,子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问以下父类中的构造函数。如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
另外,super语句一定要定义在构造函数第一行。或者是指定this()来访问本类中的构造函数(也只能放第一行,所以super和this只能出现一个);但子类中一定要有一个构造函数去访问父类的构造函数。
被final修饰的变量是一个常量,并且只能被赋值一次,既可以修饰成员变量,又可以修饰局部变量。