抽象类与抽象方法
抽象类:
public abstract class Pet {
抽象方法
public abstract void toHospital();
}
抽象类VS普通类
分为语义上的区别(宠物和狗,水果和苹果)和语法上的区别(抽象类里有抽象方法无法实例化)
- 抽象类不能被实例化:但可以创建一个引用变量,其类型是一个抽象类,指向非抽象的子类实例:Pet p = new Dog();父类类型指向子类对象
- 普通类可以被实例化:Pet p = new Pet();
抽象方法VS普通方法
有无方法体(抽象方法没有大括号,但是有分号)
抽象类与抽象方法的使用区别:
- 抽象类中可以没有抽象方法(进行扩展时一旦有抽象方法时扩展方便),但包含了抽象方法的类必须被定义为抽象类
- 如果子类没有实现父类的所有抽象方法,子类必须被定义为抽象类
- 没有抽象构造方法,也没有抽象静态方法(和类相关一定有方法体)
- 抽象类中可以有非抽象的构造方法,创建子类的实例时可能调用
继承中实现代码复用时用到抽象类(一般继承树的顶层就是抽象类),好处是如果有一些事子类都有的行为但是实现不同。
接口:
接口是什么:
- 概念性的接口:一个系统能对外提供的所有服务
- 实在的接口(语法层面):用interface修饰的都是接口
- 接口是一种能力,接口是一种能力
- 面向接口编程,程序设计时:
- 关心实现类有何能力,而不关心实现细节
- 面向接口的约定而不考虑接口的具体实现
public interface +名字(名字的所有单词都要要大写){
接口
public void foo();
//其他方法
所有的方法默认都是公共的抽象的:public abstract
}
接口特征:
继承中叫:继承父类,而接口中叫:实现接口
接口不可以被实例化(可以作为类型使用,创建一个指向子类对象的方法)
实现类必须实现接口的所有方法
实现类可以实现多个接口;java中的多继承;弥补单继承的缺陷
(implements,多个接口使用逗号隔开)
接口中的变量都是静态常量(public static final)
(A extends B implements C,D,E)
实现接口
在类图里实线一般代表继承,虚线一般代表接口实现。
一个人可以具有多项能力;一个类可以实现多个接口
接口使用:
- 接口中的成员变量:默认都是public static final的,必须显式初始化(常量要全部大写)
- 接口中的方法:默认都是public abstract的
- 除了成员变量和方法,不能包含其他(没有静态方法)
- 接口没有构造方法,不能被实例化(抽象类可以有构造方法)
- 一个接口不能实现另一个接口,但可以继承多个其他接口,称为复合接口
- 一个类必须实现接口抽象方法(implements),除非这个类也是抽象类
阅读代码,找出错误:
public interface MyInterface {
public MyInterface(); (错:接口里不能有构造方法)
public void method1(); (对)
public void method2(){} (错:接口里不能有普通方法)
private void method3(); (错:接口里不能有private)
void method4(); (对)
int method5(); (对)
int TYPE = 1; (对)
接口是一种约定:体现在接口名称和注释上
有些接口只有名称;方法的实现方式要通过注释来约定
面向接口编程:程序设计时面向接口的约定而不考虑具体实现
类和接口的区别:
class 修饰的是类;interface修饰的是接口
类和对象是is a 的关系
接口和对象是 has a的关系
抽象类vs接口
相同点:
- 代表系统的抽象层
- 都不能被实例化
- 都能包含抽象方法(用于描述系统提供的服务,不必提供具体实现)
不同点:
- 在抽象类中可以为部分方法提供默认实现(可以有普通方法,利于抽象类一些代码的可重用性,扩展功能时只要在抽象类里加具体方法就可以,子类都可以继承),而接口(必须稳定不能随意改变)中只能包含抽象方法
- 一个类只能继承一个直接的父类,但可以实现多个接口(接口中只有抽象方法,不会增加Java虚拟机绑定的复杂度)
- 已存在的继承树,可以方便的抽取接口,但是抽取抽象类不容易
使用原则:
- 接口做系统与外界交互的窗口(接口提供服务)
- 接口本身一旦制定,就不允许随意修改
- 抽象类可完成部分功能实现,还有部分功能可作为系统的扩展点
(系统之间交互用接口实现,系统内部如果有功能介于抽象具体之间用抽象类)