当编写一个类时,常常会为该类定义一些方法,这些方法用以描述该类的行为方式,那么该方法都有具体的方法体。但在某些
情况下,某个父类只是知道了其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法,例如定义了一个Shape
类,这个类应该提供一个计算周长的方法calPerimeter(),但不同Shape子类对周长的计算方法是不一样的,即Shape类方法
无法准确知道其子类计算周长的方法。
抽象方法和抽象类
抽象方法和抽象类必须使用abstract修饰符来定义,有抽象方法的类只能被定义成抽象类,抽象类里可以没有抽象方法。
抽象方法和抽象类的规则如下:
== 抽象类必须使用abstract修饰符来修饰,抽象方法也必须使用abstract修饰符来修饰,抽象方法不能有方法体。
== 抽象类不能被实例化,无法使用new关键字来调用抽象类的构造器创建抽象类的实例,即使抽象类里不包含抽象方法,这个
抽象类也不能创建实例。
== 抽象类可以包含属性、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类、枚举类六中成分。抽象类的
构造器不能用于创建实例,主要是用于被其子类调用。
== 含有抽象方法的类只能被定义为抽象类。
当abstract修饰类时,表明这个类只能被继承,当abstract修饰方法时,表明这个方法必须由子类提供实现(即重写),而final
修饰的类不能被继承,final修饰的方法不能被重写。因此final和abstract永远不能同时使用。
注意:abstract不能用于修饰属性,不能用于修饰局部变量,即没有抽象变量,没有抽象属性等说法;abstract也不能用于
修饰构造器,没有抽象构造器。抽象类里定义的构造器只能是普通的构造器。
除此之外,当使用static修饰一个方法时,表明这个方法属于当前类,即该方法通过类来调用,如果该方法被定义成抽象方法,则
将导致通过该类来调用该方法时出现错误(调用了一个没有方法体的方法肯定会引起错误),因此abstract和static不能同时
修饰某个方法,即没有所谓的抽象类方法。
抽象类是从多个类中抽象出来的模块,如果将这种抽象进行的更彻底,则可以提炼出一种更加特殊的“抽象类”--接口(interface)
,接口里不能包含普通方法,接口里所有方法都是抽象方法。
接口的定义
和类定义不同,定义接口不能使用class关键字,而是使用interface关键字。接口定义的基本语法如下:
[修饰符] interface 接口名 extends 父接口1,父接口2...
{
零个到多个常量定义...
零个到多个抽象方法定义...
}
上面语法的详细说明如下:
== 修饰符可以是public或者省略,如果省略了public访问控制符,则默认采用包权限访问控制符,及只能在相同的包结构
下才可以访问接口
== 接口名应与类名采用相应的命名规则
== 一个接口可以有多个直接父接口,但接口只能继承接口,不能继承类。
由于接口定义的是一种感觉,因此接口里不能包含构造器和初始化块定义。接口里可以包含属性(只能是常量)、方法(只能是
抽象实例方法)、内部类(包括内部接口)和枚举定义。
对于接口里定义的常量属性而言,它们是接口相关的,只能是常量,因此系统会自动会为这些属性增加static和final两个属性
符。也就是说,在接口中定义属性时,不管是否使用public static final 修饰符,接口里的属性总将使用这三个修饰符
来修饰。而且,接口里没有构造器和初始化块,因此接口里定义的属性只能在定义时指定默认值。
接口里定义属性采用如下两行代码的结果完全相同:
- //系统自动为接口里定义的属性增加public static final修饰符
- int MAX_SIZE = 50;
- public static final int MAX_SIZE = 50;
对于接口里定义的方法而言,它只能是抽象方法,因此系统会自动为其增减abstract修饰符;由于接口里的方法全部都是抽象
方法,因此接口里不允许定义静态方法,即不可使用static修饰接口里定义的方法。不管定义接口里方法是否使用public abstract
修饰符,接口里的方法总是使用public abstract来修饰。
下面定义一个接口:
- public interface Output {
- //接口里定义的属性只能是常量
- int MAX_CACHE_LINE = 50;
- //接口里定义的方法只能是public的抽象方法
- void out();
- void getData(String msg);
- }
接口的继承
接口的继承和类继承不一样,接口完全支持多继承,即一个接口可以有多个直接父类接口。和类继承相似,子接口扩展父
接口,将会获得父接口里定义的所有抽象方法、常量属性、内部类和枚举类定义。一个接口继承多个父接口,多个父接口排在
extends关键字之后,多个父接口之间以英文逗号隔开。看下面程序定义了三个接口。
- public class TestInterfaceExtends {
- interface interfaceA{
- int PROP_A = 5;
- void testA();
- }
- interface interfaceB{
- int PROP_B = 6;
- void testB();
- }
- interface interfaceC extends interfaceA,interfaceB{
- int PROP_C = 7;
- void testC();
- }
- public static void main(String[] args) {
- System.out.println(interfaceC.PROP_A);
- System.out.println(interfaceC.PROP_B);
- System.out.println(interfaceC.PROP_C);
- }
- }