私有构造器:高内聚低耦合,增强代码的封装性,对于一些其他类访问具有限制。
接口
1.1 概述
接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(JDK 9)。
接口的定义,它与定义类方式相似,但是使用 interface 关键字。它也会被编译成.class文件,但一定要明确它并不是类,而是另外一种引用数据类型。
引用数据类型:数组,类,接口。
接口的使用,它不能创建对象,但是可以被实现( implements ,类似于被继承)。一个实现接口的类(可以看做是接口的子类),需要实现接口中所有的抽象方法,创建该类对象,就可以调用方法了,否则它必须是一个抽象类。
课:接口就是一种公共暴露的规则,好处:具有通用性,只要符合规则,就可以通用我这个电源插口,不符合要求的,就不能通用。
1.2 定义格式
public interface 接口名称 {
// 抽象方法-1
// 默认方法-2 java8 有
// 静态方法-3 java8 有
// 私有方法-4 java9 有
// 常 量-5
}
虽然使用了interface关键字,但是编译之后产生的字节码文件仍然是一个Class文件。
如何使用接口当中的抽象方法:
1. 不能直接new接口
2. 必须有一个实现类,去实现接口
public class 实现类名称 implements 接口名称 {
// ...
}
3. 实现类当中必须覆盖重写所有的抽象方法。
4. 创建实现类对象进行使用。
含有抽象方法
抽象方法:使用abstract 关键字修饰,可以省略,没有方法体。
该方法供子类实现使用。
格式如下:
public abstract void method();//
不能new接口,new它的实现它的类
含有默认方法(唯java8以上有)和静态方法
从Java 8开始,接口里面可以定义默认方法:
public default 返回值类型 方法名称(参数列表) {
方法体
}
备注:
1. public关键字可以省略,就算不写,也照样是public的。但是
default关键字不能省略。
2. 这是Java 8特性之一。
3. 接口当中的默认方法一般不强制要求覆盖重写。
4. 然而实现类也是可以对默认方法进行覆盖重写的。
Java 8还允许接口当中定义静态方法:
如果一个方法和对象无关,那么就可以定义成为静态方法。 格式: public static 返回值类型 方法名称(参数列表) { 方法体 } 备注: public可以省略,就算不写public,也照样是public。
但是static不能省略。 使用格式: 接口名称.静态方法名(参数); 注意: 接口当中的静态方法使用,不能通过实现类对象调用。
含有私有方法和私有静态方法
从Java 9开始,接口当中允许定义私有方法: public interface 接口名称 { // 普通的私有方法 private 返回值类型 方法名称(参数列表) { 方法体 } // 静态的私有方法 private static 返回值类型 方法名称(参数列表) { 方法体 } }
注意事项:
1. 这个特性是Java 9才有的。
2. 静态不能直接调用非静态,
private用来解决default方法之间的重复代码
private static用来解决static方法之间的重复代码
3. 任何一个关键字都不能省略。
接口当中的常量
常量的定义:public staic fianal int AGE= 18;
注意事项:1.其中可以省略三个关键字,也可以省略其中任何一个,
2.Final关键字代表的是“最终”,也就是不可改变。
3.接口当中的常量,必须进行赋值,不能不赋值。
4.接口当中的常量,命名规则为:所有字母一律大写,中间使用下
划线分隔;
5.使用接口中常量的格式:接口名称.常量名
1.3 基本的实现
实现的概述
类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类。实现的动作类似继承,格式相仿,只是关键字不同,实现使用 implements 关键字。
非抽象子类实现接口:
1. 必须重写接口中所有抽象方法。
2. 继承了接口的默认方法,即可以直接调用,也可以重写。
实现格式:
class 类名 implements 接口名 {
// 重写接口中抽象方法【必须】
// 重写接口中默认方法【可选】
}
1.4 接口的多实现
一个类在继承父类的同时,实现多个接口的格式: 格式如下:
public class 类名称 extends 父类 implements 接口A, 接口B { // ... } 1. 这个类必须覆盖重写所有的抽象方法。 2. 如果父类和/或多个接口之间存在重复的抽象方法,那么只要覆盖重写一次即可。 3. 如果这个类没有做到覆盖重写所有抽象方法,那么这个类自己也必须是一个抽象类。 4. 对于多个接口当中存在冲突的默认方法,实现类必须进行覆盖重写。 5. 父类的方法,优先于接口当中的默认方法
1.5 接口的多继承
1. 类与类之间与单继承关系。 2. 类与接口之间是实现关系。 3. 接口与接口之间是多继承关系。 public interface 接口名 extends 父接口A, 父接口B { // ... } 子接口的实现类,必须覆盖重写来自于所有接口的所有抽象方法。 如果多个父接口当中存在重复的抽象方法,无所谓。 如果多个父接口当中存在冲突的默认方法,那么子接口必须覆盖重写默认方法,而且带着default关键字。
多态
2.1 概述
引入
多态是继封装、继承之后,面向对象的第三大特性。
生活中,比如跑的动作,小猫、小狗和大象,跑起来是不一样的。再比如飞的动作,昆虫、鸟类和飞机,飞起来也是不一样的。可见,同一行为,通过不同的事物,可以体现出来的不同的形态。多态,描述的就是这样的状态。
定义
多态: 是指同一行为,具有多个不同表现形式。
2.2 多态的体现
多态性在代码当中的体现就是:左父右子,或者左接口右实现。 在继承关系当中使用多态: 父类 对象名 = new 子类(); 在实现关系当中使用多态: 接口 对象名 = new 实现类(); 使用多态的时候,【重要】特点是: 编译看左边,运行看右边。 “由左边决定能不能调用;由右边决定运行的是谁。”
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,执行的是子类重写后方法。
2.3 多态的好处
多态当中成员变量的访问特点:
直接通过对象名称访问成员变量:
等号左边是谁,优先用谁;如果没有,向上找父类。
间接通过成员方法访问成员变量:
该方法属于谁,优先用谁;如果没有,向上找父类。
多态当中成员方法的访问特点: 看n ew的是谁,优先用谁;如果没有,向上找父类。
2.4 多态的好处
实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用,更能体现出多态的扩展性与便利。
2.5 引用类型转换
向上转型:将本来一个子类对象,向上转换成为父类类型。
向下转型:将一个父类对象,向下转换成为子类类型。
向上转型的格式:
父类 对象名 = new 子类();
或者:
接口 对象名 = new 实现类();
注意:对象向上转型之后,就不能再调用子类特有的方法了。
向下转型的格式:
子类 对象名 = (子类) 父类对象
或者:
实现类 对象名 = (实现类) 接口对象
通过关键字【instanceof】可以判断一个对象是不是指定类型的实例:
对象 instanceof 类名称
这将会得到一个boolean值,如果是true代表可以转换成为后者类型;如果是false就代表不可以转换成为后者类型
注意:
一定要保证向下转型之前,首先通过instanceof判断。绝对不能直接想当然地向下转型。
转型的异常
向上转型之后,就不能调用子类里的独有的方法,因为父类给屏蔽了。
要想继续调用子类的里的独有的方法,得需要向下转型。
接口多态的综合案例