11_抽象和接口
面向对象的特性:封装、继承、多态、抽象。
抽象的概述
当在使用继承之后,如果发现父类的方法肯定会被不同的子类进行重写时,那么父类的该方法可以定义为抽象方法,与此同时该类也变为抽象类。
抽象的使用
抽象方法
访问权限修饰符 abstract 返回值类型 方法名(形式参数列表)
在子类中都重写了方法,父类中定义抽象方法的意义?
在父类定义的抽象方法是为了配合多态使用,不然父类无法调用子类特有的行为或特征。
特别注意:
- 抽象方法没有方法体
- 抽象方法有一个修饰关键字:abstract
- 父类中定义的抽象方法,必须在子类中进行方法重写
- 在定义了抽象方法之后,该类称为抽象类
抽象类
访问权限修饰符 abstract class 类名{
// 属性
// 方法
}
特别注意:
- 抽象类不能创建对象,但可以有构造方法,构造方法用来给子类使用
- 抽象类中不一定有抽象方法(可以只有普通方法,例如不想在子类中重写父类抽象方法得类,该方法在孙子类中重写),但有抽象方法的类一定是抽象类
- 在子类继承了抽象的父类之后,强制要求重写对应的抽象方法,如果子类也不重写,那就定义为抽象类
- 抽象类依然可以用于多态的使用
- 抽象类可以用作为一个程序架构体系中的基类(基础类)
匿名内部类
这种类只能使用一次,无法像在 Java 源文件中定义的带名类型一样反复使用。
// 多态:父类引用的对象指向了子类对象
父类名 对象名 = new 父类名() {
重写相应抽象方法
};
接口的概述
Java支持单继承,但支持多接口
接口的使用
1.定义父类:接口
访问权限修饰符 interface 接口名 {
属性;
行为;
}
在接口中主要定义的是行为。
2.子类继承父类:实现接口
访问权限修饰符 class 子类名 implements 接口名, 接口名2, ... {
}
接口的注意事项:
- 在接口中,定义的方法主要是公共的抽象方法
- 在 Java 8 以前,接口中只能定义公共的抽象方法
- 在 Java 8 以后,接口中允许定义公共的默认(default)的方法,这样就不是强制子类重写方法了
- 在接口中,定义的属性都是公共的静态常量
- 接口之间可以使用继承关键字(extends)
- 接口没有构造方法,也不能创建对象
抽象类和接口的区别
- 抽象类(abstract class)毕竟是一个类,Java 是单根继承嘛,所以一个子类只能继承一个抽象类;但是一个子类可以实现多个接口(interface),并且一个接口也可以继承多个接口来扩展自身。
- 抽象类和接口都不能实例化,但抽象类可以有构造方法,而接口不能有构造方法。
- 接口中定义的变量只能是 public static final 修饰的静态常量,而抽象类没有此限制。
- 有抽象方法的一定是抽象类,但抽象类不一定有抽象方法,它也可以有非抽象方法;而接口在 JDK 1.8 之前定义的方法都是抽象方法,在 JDK 1.8 开始也可以定义被 default 修饰的带实现的默认方法。不过如果一个实现类实现的两个接口都有相同的方法,而且它们对这个方法都进行了 default 默认实现,那么实现类就必须重写该方法。
- 接口在 JDK 1.8 之前因为只能定义抽象方法,所以所有的方法都是 public 修饰的(为了子类可以进行方法重写),但在 JDK 1.8 开始支持定义带实现的默认方法,所以在 JDK 1.9 的时候,也可以定义私有方法了,这样在接口中就可以复用内部方法了,当然了抽象方法依然只能是 public 修饰的;抽象类除了抽象方法不能定义为私有访问权限的之外,其他没有限制。
- 抽象类中可以定义静态方法,且可以被子类使用;而接口在 JDK 1.8 开始才可以定义静态方法,并且只能被接口调用,接口的实现类无法使用。
- 抽象类和接口都代表着系统的抽象层,但抽象类可以通过抽取子类共有的信息来实现属性和行为的复用,而接口往往是作为子类的行为规范,虽然也增加了默认实现,但也仅仅是行为的复用。