单例设计模式
1、设计模式
针对特定的问题提供的固定的最优的解决方案;
在面向对象的编程语言中有23中设计模式;
单例设计模式
确保唯一性;
拿到某个类的对象,始终是同一个对象,多个对象引用的引用地址是相同的;
基本类型变量恒等比较的是两个变量的值是否相等,引用类型变量恒等比较的是两个引用变量引用的地址是否相等
单例设计模式核心
因为被static修饰过的对象成员会成为类成员,随着类的加载而产生,只会被加载一次,随着jvm的关闭而销毁,Single中的类成员只会被加载一次,多次的取用静态成员都始终是同一个。
1、饿汉式单例模式
class Demo{
public static void main(String[] args){
//不能让外类随意的去new构造器创造对象
//将构造器私有化
Single s = Single.getSingle();
System.out.println(s);
}
}
class Single{
//本类中创建的私有成员只能通过类的对象成员来调用
//想要不创建类的对象来调用对象成员就要将其
//设置为静态成员
private static Single s = new Single();
//私有化无参构造器,无法在外类里new构造器来创建对象
//而是在本类中创建对象
private Single(){}
//将通过成员函数将成员变量拿到传递给外部调用者,
//要将其设置为静态成员,不用创建对象来调用
private static Single getSingle(){
return s;
}
}
2、懒汉式单例模式
class Demo{
public static void main(String[] args){
}
}
class Single{
private static Single s = null;
private Single(){}
public static Single getSingle(){
if(s == null) s = new Single();
return s;
}
}
继承
1、概念:
当多个类定义了相同的共性内容(相同的成员变量和成员方法),为了提高代码复用性,建立起继承结构;将多个类中具有相同的共性内容提取并定义成一个独立的类,然后让其他的类去继承这个具有相同共性内容的独立的类,就是继承了这个类中的共性内容;
2、Java继承的限制
Java中不支持直接多继承,只允许直接单继承;
3、Java的多重继承
允许多重继承(B继承A,C继承B);
4、继承的使用细节:
1)继承子父类间成员变量的特点
a、父类中有的成员变量,子类中没有,子类继承父类的直接使用;
b、父类中没有的成员变量,子类中有,则子类使用自己的;
c、父类与子类中都有相同的成员变量,直接调用则是调用子类中的成员变量(就近原则);
d、父类与子类中都有相同的成员变量,并且都想要调用,调用子类中的成员变量时:this.成员 或 直接调用,调用父类中的成员变量时:super.成员
2)继承子父类间成员方法的特点:
a、父类中有的成员方法,子类中没有,子类继承父类的直接使用;
b、父类中没有的成员方法,子类中有,则子类使用自己的;
c、当子类和父类有相同的方法时,子类成员方法则会覆盖子类继承父类的该成员方法(访问自己的);
d、父类与子类中都有相同的成员变量,并且都想要调用,调用子类中的成员变量时:this.方法 或 直接调用,调用父类中的成员变量时:super.方法
3)继承子父类间的构造方法的特点
在子类的所有构造器中的第一句话都是默认隐藏存在一个super(); ,表示访问父类默认的无参构造器。
因为子类继承父类并不是通过extends关键字,仅仅是表示子父类中的继承关系;子类继承父类底层是通过子类中的构造器中通过访问父类中的构造器来实现的,因为构造器是用于初始化对象的,子类通过访问父类的构造器来明确继承父类中的哪些内容被继承了;
除了在子类构造器中通过默认隐藏super(),也能通过带参的super(参数列表),去指定访问具体的父类构造器,
子父类中构造代码块和构造函数的执行顺序:
class Demo8
{
public static void main(String[] args)
{
B b = new B();
}
}
class A
{
{
System.out.println("A的构造代码块");
}
public A(){
System.out.println("A的构造函数");
}
}
class B extends A
{
{
System.out.println("B的构造代码块");
}
public B(){
System.out.println("B的构造函数");
}
}
/*
执行结果:
A的构造代码块
A的构造函数
B的构造代码块
B的构造函数
*/
super()与this()的位置:
class Demo9
{
public static void main(String[] args)
{
Student s = new Student(5);
}
}
class Person{
public Person(){
System.out.println("父类无参构造函数");
}
}
class Student extends Person{
public Student(){
super();
System.out.println("子类无参构造函数");
}
public Student(int i){
this();//super() this() 无法同时出现
System.out.println("子类int型构造函数");
}
}
/*
执行结果:
父类无参构造函数
子类无参构造函数
子类int型构造函数
*/
4)父类的私有成员变量子类可以继承但不能直接继承
a、子类通过继承父类的get/set方法去给私有成员变量取值赋值;
b、子类通过访问父类的构造器来完成对父类私有成员变量的初始化;
supe关键字
1)super表示在子类对象空间中继承自父类的成员的一块存储空间的标志;
2)表示父类构造器
方法的重写(覆盖)
当子父类中出现了相同的方法时(a、方法名相同 b、参数列表相同 c、返回值相同 d、修饰符相同),子类中该名称的方法会覆盖子类继承父类的该名称的方法(子类仍可以去用super去调用父类中的该名称方法)
常见的面试题
1、this和super的使用及区别?
this的用法:
a、代表当前对象,一般用于区分同名的成员变量和局部变量,直接变量是局部变量,this.变量是成员变量,哪个对象调用了this所在的方法,this就代表哪个对象;
b、代表当前类的构造器,放在调用者构造器的第一句;
super的用法:
  a、代表子类对象空间中继承自父类的成员的存储空间的标志,用于区分子父类间的相同成员,直接成员是子类自己的,super.成员是子类继承自父类的;
  b、代表父类构造器,房子啊子类构造器的第一句;
2、什么是重载,什么是重写?
重载:同一个类中,方法名相同参数列表不同与返回值类型无关的多个方法;
重写:子父类间,相同的方法(方法名 参数列表 返回值类型 修饰符都相同),子类方法会覆盖继承父类的方法;
静态成员的继承
父类的静态成员子类是可以继承的,但是静态成员是属于类的,所以虽然子类能够继承但是仍然属于父类不是子类的。所以当子父类间出现的相同的静态方法时,无论使用子类对象还是子类访问的都是子类自己的,这不是覆盖,而就是访问子类自己的静态成员方法。