抽象类
抽象类的基本概念
-
Java中一种专门用来做父类的类称为“抽象类”。与普通类相比,内部新增了抽象方法
-
抽象方法时只声明而未实现的方法,所有的抽象方法必须使用abstract关键字声明,包含抽象方法的类也必须使用abstact class声明
-
抽象类的定义规则
- 抽象类、方法都必须用abstract关键字去产生对象;
- 抽象类不能直接实例化,也就是不能直接用new关键字去产生对象;
- 抽象类定义时抽象方法只需声明,而不需实现;
- 含有抽象方法的类必须被声明为抽象类,抽象类的子类必须实现所有的抽象方法后才能被实例化,否则这个子类还是个抽象类;
- 定义语法
abstract class 类名称{ 声明数据成员; 访问权限 返回值的数据类型 方法名称(参数…){ //定义一般方法} abstract 返回值的数据类型 方法名称(参数…);//定义抽象方法,在抽象方法里没有定义方法体}
- 总结:抽象类可以用“有得有失”4个字来描述。得指的是抽象类多了一个能力——抽象类可以包含抽象方法;失指的是抽象类失去了一个能力——抽象类不能用于创建实例
-
抽象类的使用原则
- 抽象类必须有子类,子类是用extends继承抽象类,一个子类只能够继承一个抽象类;
- 子类(如果不是抽象类)则必须实现抽象类之中的全部抽象方法;
- 如果要想实例化抽象类的对象,则可以使用子类进行对象的向上转型来完成;
-
抽象类的子类改写父类的同名方法,我们称其为实现,而非覆盖
-
抽象类的特征
-
抽象类中可以有构造方法
- 抽象类的构造方法必须在子类中被调用,并且子类实例化对象的时候依然满足类继承的关系,先默认调用父类的构造方法,而后再调用子类的构造方法;抽象类的构造方法无法被外部实例对象调用;
-
抽象类不能使用final定义
-
Static声明,抽象类内外不同
- 在外部抽象类上无法使用 static声明,但是内部抽象类却可以使用static定义,使用static定义的内部抽象类就表示一个外部类
-
抽象类之中可以没有抽象方法,但即便没有抽象方法的抽象类也不能够直接在外部通过关键字new实例化对象
-
抽象类应用——模板设计模式
-
在使用抽象类时,可以将部分逻辑以具体方法和具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现,这就是模板方法模式
-
模板模式的一些简单规则
- 抽象父类可以只定义需要使用的某些方法,把不能实现的部分抽象成抽象方法,留给其子类去实现
- 父类中可能包含需要调用其它系列方法的方法,这些被调用方法既可以由父类实现,也可以由其子类实现。父类里提供的方法只是定义了一个通用算法,其实现也许并不完全由其自身实现,而必须依赖于其子类的辅助
接口
接口的基本概念
-
对于接口的理解
- 这里以主板上的接口为例,当我们提到主板上的PCI接口时,指的是主板上那个插槽遵守了PCI规范,而具体的PCI插槽只是PCI接口的实例
- 对于不同型号的主板而言,它们各自的PCI插槽都需要遵守一个规范,遵守这个规范就可以保证插入插槽里的板卡能与主机板正常通信。对于同一个型号的主机板而言,他们的PCI插槽需要相同的数据交换方式、相同的实现细节,它们都是一个类的不同实例。其抽象过程如下
-
定义语法
-
[修饰符] interface 接口名称 [extends 父接口1,父接口2...] { final 数据类型 成员名称 = 常量;//数据成员必须赋初值 abstract 返回值的数据类型 方法名称(参数…);//抽象方法,注意在抽象方法里没有定义方法主体 default 返回值的数据类型 方法名称(参数…);//默认方法,包含方法体 {……方法体……} }
- 由于接口只是一种规范,因此接口里不能包含构造方法和初始化块定义。接口里可以包含成员变量(只能是静态变量)、方法(只能是抽象实例方法、类方法或默认方法)、内部类(包括内部接口、枚举)定义
- 接口里定义的是多个类共同的公共行为规范,因此接口里的所有成员,包括常量、方法、内部类和内部枚举都是public访问权限。定义接口成员时,不管是否使用public、static、final修饰符,接口里的成员变量总是使用这三个修饰符来修饰。而且接口里没有构造方法和初始化块,因此接口里定义的成员变量只能在定义时指定默认值,同时即使另一个类处于不同包下,也可以通过接口访问接口里的成员变量
- 接口里定义的方法只能是抽象方法、类方法或默认方法,因此如果不是定义默认方法,系统将自动为普通方法增加abstract修饰符;定义接口里的普通方法时不管是否使用public、abstract修饰符,接口里的普通方法总是使用这两个修饰符来修饰。接口里的普通方法不能有方法实现(方法体);但类方法、默认方法都必须有方法实现(方法体)
- 从某个角度看,接口可被当成一个特殊的类,因此一个Java源文件里最多只能有一个public接口。如果一个Java源文件里定义了一个public接口,则该源文件的主文件名必须与该接口名相同
-
接口的基本原则
- 接口必须有子类,子类依靠implements关键字可以同时实现多个接口;
- 接口的子类(如果不是抽象类)则必须实现接口之中的全部抽象方法里;
- 接口可以利用对象多态性,利用子类实现对象的实例化;
- 接口与一般类一样,本身也具有数据成员与方法,但数据成员一定要赋初值,且此值不能再更改,方法也必须是abstract或者default方法
- 一个类实现多个接口时,若接口中有默认方法,不能出现同名默认方法
- 如果一个子类既要实现接口又要继承抽象类名则应该采用先继承后实现的顺序完成;一个抽象类可以继承多个接口,但是反过来说,一个接口却不能够继承抽象类,但是一个接口却可以使用extends关键字继承多个接口;
interface 子接口名称 extends 父接口1,父接口2,… { …… }
接口的作用——制定标准
- 接口是标准,即各方共同遵守的一个守则
接口的作用——工厂设计模式(Factory)
- 在程序复杂时,新对象的建立是一个“过程”,不再是一个单步操作。为了轻松的建立“复杂”的对象,我们可以构建一个工厂模式,来创建新的对象;
- 在程序猿自己开发的代码之中,只要是遇见了取得接口对象实例的操作,都应该采用工厂设计模式;
接口的作用——代理设计模式(Proxy)
-
代理模式:给某一对象提供代理对象,并由代理对象控制具体对象的引用;
-
代理模式作用:为其他对象(生产厂商)提供一种代理(代理商,即卖产品的)以控制对这个对象(生产厂商)的访问;
-
代理对象可以在客户端(客户)和目标对象(生产厂商)之间起到中介作用;
-
核心组成
- 一个接口两个子类,一个子类负责真实的业务操作功能,另外一个子类负责完成与真实业余有关的操作;
加油!加油!加油!加油!