抽象类和接口

来源:互联网 发布:哪里申请免费域名 编辑:程序博客网 时间:2024/05/16 00:43

当编写一个类时,常常会为该类定义一些方法,这些方法用以描述该类的行为方式,那么该方法都有具体的方法体。但在某些
情况下,某个父类只是知道了其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法,例如定义了一个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 修饰符,接口里的属性总将使用这三个修饰符
来修饰。而且,接口里没有构造器和初始化块,因此接口里定义的属性只能在定义时指定默认值。
接口里定义属性采用如下两行代码的结果完全相同:

[java] view plaincopy
  1. //系统自动为接口里定义的属性增加public static final修饰符  
  2. int MAX_SIZE = 50;  
  3. public static final int MAX_SIZE = 50;  

对于接口里定义的方法而言,它只能是抽象方法,因此系统会自动为其增减abstract修饰符;由于接口里的方法全部都是抽象
方法,因此接口里不允许定义静态方法,即不可使用static修饰接口里定义的方法。不管定义接口里方法是否使用public abstract
修饰符,接口里的方法总是使用public abstract来修饰。

下面定义一个接口:

[java] view plaincopy
  1. public interface Output {  
  2.   
  3.     //接口里定义的属性只能是常量  
  4.     int MAX_CACHE_LINE = 50;  
  5.       
  6.     //接口里定义的方法只能是public的抽象方法  
  7.     void out();  
  8.     void getData(String msg);  
  9. }  

接口的继承

接口的继承和类继承不一样,接口完全支持多继承,即一个接口可以有多个直接父类接口。和类继承相似,子接口扩展父
接口,将会获得父接口里定义的所有抽象方法、常量属性、内部类和枚举类定义。一个接口继承多个父接口,多个父接口排在
extends关键字之后,多个父接口之间以英文逗号隔开。看下面程序定义了三个接口。

[java] view plaincopy
  1. public class TestInterfaceExtends {  
  2.   
  3.     interface interfaceA{  
  4.         int PROP_A = 5;  
  5.         void testA();  
  6.     }  
  7.       
  8.     interface interfaceB{  
  9.         int PROP_B = 6;  
  10.         void testB();  
  11.     }  
  12.       
  13.     interface interfaceC extends interfaceA,interfaceB{  
  14.         int PROP_C = 7;  
  15.         void testC();  
  16.     }  
  17.       
  18.     public static void main(String[] args) {  
  19.         System.out.println(interfaceC.PROP_A);  
  20.         System.out.println(interfaceC.PROP_B);  
  21.         System.out.println(interfaceC.PROP_C);  
  22.     }  
  23.       
  24. }  

使用接口

接口不能用于创建实例,但接口可以用于声明引用类型的变量。当使用接口来声明引用类型的变量时,这个引用类型的变量必须
引用到其实现类的对象。除此之外,接口的主要用途就是被实现类实现。
一个类可以实现一个或多个接口,继承使用extends关键字,实现使用inplements关键字
实现接口与继承父类相似,一样可以获得所实现接口里定义常量属性、抽象方法、内部类和枚举类。

接口和抽象类

接口和抽象类很像,他们都具有如下特征:
== 接口和抽象类都不能被实例化,他们都位于继承树的顶端,用于被其他类实现和继承。
== 接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。
但接口和抽象类之间的差别非常大,这种差别主要体现在二者设计目的上,下面具体分析二者的差别。
接口作为系统与外界交互的窗口,接口体现的是一种规范。对于接口的实现者而言,接口规定了实现者必须向外界提供哪些服务
(以方法的方式实现);对于接口的调用者而言,接口规定了调用者可以调用哪些服务,以及如何调用这些服务。当一个程序
中使用接口时,接口时多个模块间的耦合标准;当多个应用程序之间使用接口时,接口是多个程序之间的通信标准。
从某种程度上来看,接口类似于整个系统的“总纲”,它制定了系统各模块应该遵循的标准,因此一个系统中的接口不应该
经常改变。一旦接口被改变,对整个系统甚至其他系统的影响将士辐射式的,导致系统中大部分类都需要重写。

抽象类则不一样,抽象类作为系统中多个子类的共同父类,它体现的是一种模板式设计。抽象父类作为多个子类的抽象父类
,可以被当作为系统实现过程中的中间产品,这个中间产品已经实现了系统的部分功能(那些已经提高实现的方法),但这个
产品依然不能当作为最终产品,必须由更进一步的完善。

除此之外,接口和抽象类在用法上也存在如下差别:
== 接口里只能包含抽象方法,不包含已经提供实现的方法;抽象类则完全可以包含普通方法。
== 接口里不能定义静态方法,抽象类里可以定义静态方法
== 接口里只能定义静态常量属性,不能定义普通属性;抽象类里则可以定义普通属性,也可以定义常量静态属性。
== 接口不包含构造器;抽象类里可以包含构造器,抽象类的构造器并不是用于创建对象,而是让其子类调用这些构造器完成
属于抽象类的初始化操作。
== 接口里不能包含初始化块,则抽象类完全可以包含初始化块
== 一个类最多只能有一个父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补Java但继承的不足。

0 0