摘 要:抽象類和接口是JAVA中兩個(gè)非常重要的概念,它們的存在使JAVA面向?qū)ο蟮哪芰Πl(fā)揮得淋漓盡致。由于抽象類與接口在語法定義中有些相似之處,甚至在某些應(yīng)用中可以相互替換完成相同的功能,因此經(jīng)常被混淆。實(shí)際二者“形似神不似”,本論文通過介紹抽象類和接口的應(yīng)用場合,論述兩者的區(qū)別。
關(guān)鍵詞:抽象類;接口;JAVA
中圖分類號:TP312.1
抽象類和接口是JAVA中兩個(gè)非常重要的概念,它們的應(yīng)用體現(xiàn)了JAVA作為一門面向?qū)ο蟪绦蛟O(shè)計(jì)語言體現(xiàn)的多態(tài)性。兩者在實(shí)際應(yīng)用中經(jīng)常被認(rèn)為可以互相替換,以至被混淆。本論文通過實(shí)例詳細(xì)介紹了抽象類和接口的應(yīng)用場合和使用方法,幫助讀者設(shè)計(jì)出更高效、更健壯的JAVA程序。
1 抽象類
在設(shè)計(jì)程序時(shí),經(jīng)常會用到abstract類。其原因是,abstract類只關(guān)心操作,但不關(guān)心這些操作具體的實(shí)現(xiàn)細(xì)節(jié),可以使程序設(shè)計(jì)者把主要精力放在程序設(shè)計(jì)中,而不必拘泥于細(xì)節(jié)的實(shí)現(xiàn)。例如,在設(shè)計(jì)地圖時(shí),首先考慮地圖最重要的輪廓,不必去考慮城市中的街道牌號等細(xì)節(jié),細(xì)節(jié)應(yīng)當(dāng)由抽象類的非抽象子類去實(shí)現(xiàn)。使用多態(tài)進(jìn)行程序設(shè)計(jì)的核心技術(shù)之一是使用上轉(zhuǎn)型對象,即將abstract類聲明的對象作為其子類對象的上轉(zhuǎn)型對象,它可以調(diào)用子類重寫的方法[1]。
1.1 抽象類的定義。用關(guān)鍵字abstract修飾的類稱為abstract類(抽象類),例如:
abstract class Shape{
……
}
用關(guān)鍵字abstract修飾的方法稱為abstract方法(抽象方法),例如:
abstract int min(int x,int y);
對于abstract方法,只允許聲明,不允許實(shí)現(xiàn)(即沒有方法體),而且不允許使用final和abstract同時(shí)修飾一個(gè)方法,也不允許使用static修飾abstract方法。
(1)abstract類與abstract方法的關(guān)系。和普通類相比,abstract類中可以有abstract方法(普通類中不允許有抽象方法),也可以有非abstract方法;(2)abstract類不能被實(shí)例化。對于abstract類,不能用new運(yùn)算符創(chuàng)建該類的對象,只能被繼承。對于繼承它的非抽象子類,要求實(shí)現(xiàn)抽象父類的所有抽象方法,這也是為什么抽象類中的方法不允許同時(shí)用final和abstract修飾的原因。
1.2 抽象類的應(yīng)用。例:求常見平面圖形(如三角形、圓、矩形和正方形等)的面積。利用抽象類,編寫程序?qū)崿F(xiàn)該功能。各種平面圖形都可以求出其面積,但不同的形狀求面積的方法不同,因此可以定義一個(gè)平面圖形形狀類Shape。Shape類有一個(gè)求面積的抽象方法(area),把它定義為抽象方法是因?yàn)椴煌钠矫鎴D形求法不同。圓(Circle)、矩形(Rectangle)和三角形(Triangle)都是Shape的子類,而正方形(Square)是矩形(Rectangle)中的一種特殊類型,因此是矩形的子類。
2 接口
前面講了抽象類的應(yīng)用,但在某些場合抽象類具有局限性,需要借助于接口來完成相應(yīng)的功能。例如轎車、卡車、拖拉機(jī)、摩托車和客車都是機(jī)動車的子類,可以把機(jī)動車定義為一個(gè)抽象類。機(jī)動車中有“剎車”、“轉(zhuǎn)向”等抽象方法,要求子類都實(shí)現(xiàn)“剎車”、“轉(zhuǎn)向”,這是合理的。但如果機(jī)動車中還包含兩個(gè)抽象方法“收取費(fèi)用”和“調(diào)節(jié)溫度”,所有子類都要重寫“收取費(fèi)用”和“調(diào)節(jié)溫度”方法,這顯然是不合理的。因?yàn)橥侠瓩C(jī)不可能有這樣的功能,而飛機(jī)、輪船等非機(jī)動車也具有“收取費(fèi)用”和“調(diào)節(jié)溫度”的行為。抽象類不適用了,這時(shí)就要應(yīng)用接口來實(shí)現(xiàn)。
2.1 接口的聲明。使用關(guān)鍵字interface來定義一個(gè)接口,接口定義和類的定義類似,分為接口聲明和方法體部分。例如:
interface Printable{
final int max=100;
void add();
float sum(float x,float y);
}
接口中只有常量和抽象方法兩部分,不允許有變量和普通方法。接口中所有常量訪問權(quán)限都是public,而且是static常量(public、static、final都可以省略)。抽象方法的訪問權(quán)限也是public(抽象方法中的public、abstract也可以省略)。
2.2 接口的實(shí)現(xiàn)。在JAVA語言中,接口是由類來實(shí)現(xiàn)以便使用接口中的方法。一個(gè)類需要在聲明中使用implements 關(guān)鍵字來實(shí)現(xiàn)一個(gè)或多個(gè)接口。如果一個(gè)非抽象類實(shí)現(xiàn)了一個(gè)接口,那么它必須要實(shí)現(xiàn)該接口中的所有抽象方法。在實(shí)現(xiàn)方法時(shí),需要去掉abstract修飾符,并用public修飾(因?yàn)轭惖娜笔⌒揎椃莊riendly)。抽象類可以實(shí)現(xiàn)接口中的抽象方法也可以直接擁有接口中的方法。
2.3 接口的應(yīng)用。使用接口完成對生物(Biology)、動物(Animal)、人(Man)三個(gè)接口的定義。其中生物接口定義一個(gè)breathe()方法;動物接口定義sleep()和eat()抽象方法;人接口定義think()和study()兩個(gè)抽象方法。定義一個(gè)人(Person)類實(shí)現(xiàn)上述三個(gè)接口。
實(shí)現(xiàn)代碼如下所示:
public interface Biology{
void breathe();
}
public interface Animal{
void sleep();
void eat();
}
public interface Man{
void think();
void study();
}
public class Person implements Biology,Animal,Man
{public void breathe(){ Sysem.out.println(“吸進(jìn)的是氧氣,呼出的是二氧化碳”);}
public void sleep(){System.out.println(“保持充足的睡眠”);}
public void eat(){System.out.println(“膳食搭配要合理”);}
public void think(){System.out.println(“用心思考”);}
public void study(){System.out,println(“好好學(xué)習(xí),天天向上”);}
}
3 抽象類與接口的比較
盡管抽象類和接口有些相似的特性,但它們在本質(zhì)上有很大區(qū)別:(1)抽象類在JAVA語言中體現(xiàn)的是一個(gè)“父與子”的關(guān)系,即抽象類與子類之間必須存在“子類是父類中一種”的關(guān)系,如抽象類“水果”與子類“蘋果”之間就存在“蘋果是一種水果”的關(guān)系。而接口與接口的實(shí)現(xiàn)者之間不必有“父與子”的關(guān)系,接口實(shí)現(xiàn)者只是具有接口定義的行為而已;(2)抽象類中可以定義非抽象方法,而接口中的所有方法都是抽象的;(3)接口中的數(shù)據(jù)成員只能是常量;(4)在抽象類中增加一個(gè)方法并賦予其默認(rèn)的行為(即增加一個(gè)非抽象方法),并不一定要修改子類;但如果接口被修改了,即增加或去掉了某個(gè)功能,則所有實(shí)現(xiàn)了該接口的類一定要重新修改[2]。
參考文獻(xiàn):
[1]印旻.JAVA語言與面向?qū)ο蟮某绦蛟O(shè)計(jì)[M].北京:清華大學(xué)出版社,2007.
[2]張思民.JAVA語言程序設(shè)計(jì)[M].北京:清華大學(xué)出版社,2007.
作者簡介:曲翠玉(1982-),女,管理科學(xué)與工程碩士,信息管理與信息系統(tǒng)專業(yè)講師。
作者單位:大連理工大學(xué) 城市學(xué)院,遼寧大連 116600