您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)java中抽象類和接口的相同和不同點(diǎn)是什么,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
下面簡單介紹抽象類,接口以及它們的異同點(diǎn),另附簡單的代碼舉例。
在 Java 語言中使用 abstract class 來定義抽象類。抽象類是不能被實(shí)例化的,即不能用new關(guān)鍵字來實(shí)例化對(duì)象。包含抽象方法的一定是抽象類,但抽象類不一定包含抽象方法。如果一個(gè)子類實(shí)現(xiàn)了父類(抽象類)的所有抽象方法,那么該子類可以不必是抽象類,否則就是抽象類。抽象類中的抽象方法的修飾符只能為public或者protected。
為什么要在抽象類中定義抽象方法呢?下面我們來看一個(gè)代碼實(shí)例:
package example; import java.util.Date; public abstract class GeometricObject { private String color="white"; private boolean filled; private java.util.Date dateCreated; protected GeometricObject() { dateCreated=new java.util.Date(); }//構(gòu)建默認(rèn)的幾何對(duì)象 protected GeometricObject(String color,boolean filled) { dateCreated=new java.util.Date(); this.color=color; this.filled=filled; } public String getColor() { return color; }//返回顏色 public void setColor(String color) { this.color=color; }//設(shè)置新的顏色 public boolean getFilled() { return filled; } public void setFilled(boolean filled) { this.filled=filled; } public java.util.Date getDateCreated(){ return dateCreated; } public abstract double getArea();//抽象方法定義得到面積 public abstract double getPerimeter();//抽象方法得到周長 }
我們假設(shè)自定義的Circle類和Rectangle類均為GeometricObject的子類,且均有求各自面積的getArea()方法和各自周長的getPerimeter()方法,但這些方法并不能在父類中定義,因?yàn)榫唧w的計(jì)算方法要取決于幾何對(duì)象的具體類型。所以采取抽象方法進(jìn)行定義,這樣可以保證父類中的抽象方法可以在子類中被重寫。
抽象類只有定義沒有實(shí)現(xiàn)。
下面是抽象類值得注意的幾點(diǎn):
1.抽象方法不能包含在非抽象類中。如果抽象父類的子類不能實(shí)現(xiàn)所有的抽象方法,那么子類也必須定義為抽象的。也就是說,在繼承自抽象類的非抽象子類中,必須實(shí)現(xiàn)所有的抽象方法。還要注意到,抽象方法是靜態(tài)的。
2.抽象類不能使用new操作符來初始化。但仍然可以定義它的構(gòu)造方法,這個(gè)構(gòu)造方法在它的子類的構(gòu)造方法中進(jìn)行調(diào)用。
3.包含抽象方法的類必須是抽象的。但是是可以定義一個(gè)不包含抽象方法的抽象類,這個(gè)抽象類用于作為定義新子類的基類。
4.即使子類的父類是具體的,這個(gè)子類也可以是抽象的。
5.不能使用new操作符從一個(gè)抽象類創(chuàng)建一個(gè)實(shí)例,但是抽象類可以用做一種數(shù)據(jù)類型。
例如:GeometricObject[] objects=new GeometricObject[10];是正確的,。
6.子類可以重寫父類的方法并將它定義為抽象的,這雖然不常見,但很適用于當(dāng)父類的方法實(shí)現(xiàn)在子類中變得無效時(shí)的情況。
接口是一種與類很相似的結(jié)構(gòu),用于為對(duì)象定義共同操作,但它的目的是指明相關(guān)或者不相關(guān)類的對(duì)象的共同行為。
Java中接口使用interface關(guān)鍵字修飾。接口是抽象方法的集合。如果一個(gè)類實(shí)現(xiàn)了某個(gè)接口,那么它就繼承了這個(gè)接口的抽象方法。
類和接口之間的關(guān)系稱為接口繼承。
下面是簡單的代碼舉例:
package example; public class TestEdible { public static void main(String[] args) { // TODO Auto-generated method stub Object[] objects= {new Tiger(),new Chicken(),new Apple()}; //創(chuàng)建由Tiger,Chicken和Apple類型的三個(gè)對(duì)象構(gòu)成的數(shù)組 for(int i=0;i<objects.length;i++) { if(objects[i] instanceof Edible) System.out.println(((Edible)objects[i]).howToEat()); if(objects[i] instanceof Animal) { System.out.println(((Animal)objects[i]).sound()); } }//如果可食用,則調(diào)用howToEat方法,如果是動(dòng)物,則調(diào)用sound方法 } } abstract class Animal{ private double weight; public double getWeight() { return weight; } public void setWeight(double weight) { this.weight=weight; } public abstract String sound();//返回動(dòng)物的聲音,是抽象方法,被具體的animal類實(shí)現(xiàn) } class Chicken extends Animal implements Edible{ @Override public String howToEat() { return "Chicken: Fry it"; }//實(shí)現(xiàn)了Edible接口。當(dāng)一個(gè)類實(shí)現(xiàn)接口時(shí),該類實(shí)現(xiàn)定義在接口中的所有方法。 @Override public String sound() { return "Chicken: cock-a-doodle-doo"; } } class Tiger extends Animal{ @Override public String sound() { return "Tiger:RROOAARR"; } } abstract class Fruit implements Edible{ }//Fruit類實(shí)現(xiàn)了Edible,但沒有實(shí)現(xiàn)howToEat方法,所以它必須定義為abstract。 class Apple extends Fruit{ @Override public String howToEat() { return "Apple:Make apple cider"; } }//Fruit的具體子類必須實(shí)現(xiàn)howToEat方法,所以Apple類實(shí)現(xiàn)了howToEat方法。
需要注意的是,接口中所有的數(shù)據(jù)域都是public static final,而且所有方法都是public abstract,但Java允許忽略這些修飾符。
即下面的兩個(gè)代碼是等價(jià)的:
public interface T { public static final int K=1; public abstract void p(); }
public interface T { int K=1; void p(); }
盡管public修飾符對(duì)于定義在接口中的方法可以省略,但是在子類實(shí)現(xiàn)中方法必須定義為public。
一個(gè)類可以實(shí)現(xiàn)多個(gè)接口,但是只能繼承一個(gè)父類。
首先我們先來列舉個(gè)表格簡單講述一下抽象類和接口之間的異同點(diǎn):
比較點(diǎn) | 抽象類 | 接口 |
關(guān)鍵字 | abstract class | interface |
字段 | 無限制 | 變量必須是public static final |
方法 | 既可以含普通方法,又可以含抽象方法,無限制 | 只能含抽象方法,且必須是public的 |
繼承/實(shí)現(xiàn) | 只能被類或抽象類繼承 | 既可以被接口繼承,也能被類或抽象類實(shí)現(xiàn) |
多重繼承 | 不支持 | 可以繼承多個(gè)父接口 |
java只允許為類的繼承做單一繼承,但是允許使用接口做多重繼承。例如:
public class NewClass extends BaseClass implements Interface1,...,InterfaceN{ }
利用extends,接口可以繼承其他接口,這樣的接口被稱為子接口。例如:下面的代碼中,NewInterface是Interface1,...,InterfaceN的子接口。
public interface NewInterface extends Interface1,...,InterfaceN{ }
一個(gè)實(shí)現(xiàn)NewInterface的類必須實(shí)現(xiàn)在NewInterface,Interface1,...,InterfaceN中定義的抽象方法。接口可以繼承其他接口但不能繼承類。一個(gè)類可以繼承它的父類同時(shí)實(shí)現(xiàn)多個(gè)接口。
所有的類都有一個(gè)共同的根類Object,但是接口并沒有共同的根。與類相似,接口同樣也可以定義一種類型。一個(gè)接口類型的變量可以引用任何實(shí)現(xiàn)該接口的類的實(shí)例。如果一個(gè)類實(shí)現(xiàn)了一個(gè)接口,那么這個(gè)接口就類似于該類的一個(gè)父類??梢詫⒔涌诋?dāng)作一種數(shù)據(jù)類型使用,將接口類型的變量轉(zhuǎn)換為它的子類,反過來同樣可以。
通常情況下,使用接口的頻率更高,因?yàn)榻涌诒阮惛屿`活,不用使所有東西都屬于同一個(gè)類型的類。
下面進(jìn)行一個(gè)簡單的代碼舉例:
abstract class Animal{ public abstract String howToEat(); }//在Animal中定義howToEat方法 //Animal的兩個(gè)子類定義如下 class Chicken extends Animal{ @Override public String howToEat() { return "Chicken: Fry it"; } } class Duck extends Animal{ @Override public String howToEat() { return "Roast it"; } } public static void main(String[] args) { Animal animal = new Chicken(); eat(animal); Animal animal = new Duck(); eat(animal); } public static void eat(Animal animal){ System.out.println(animal.howToEat()); }
假設(shè)給定這個(gè)繼承結(jié)構(gòu),java在調(diào)用方法時(shí)可以根據(jù)對(duì)象動(dòng)態(tài)地決定調(diào)用具體的howToEat方法。但有一個(gè)限制條件,即該子類必須是另一種動(dòng)物才可以。如果一種動(dòng)物不可食用,那么此刻再繼承Animal類就并不合適了。
限制條件這個(gè)問題在接口中可以被解決,例如:
public class Demo{ public static void main(String[] args) { Edible stuff = new Chicken(); eat(stuff); Edible stuff = new Broccoli(); eat(stuff); } public static void eat(Edible stuff){ System.out.println(stuff.howToEat()); } } interface Edible{ public String howToEat(); } class Chicken implements Edible{ @Override public String howToEat() { return "Chicken: Fry it"; } } class Broccoli implements Edible{ @Override public String howToEat() { return "Broccoli: Stir-fty it"; } }
定義表示可食用對(duì)象的一個(gè)類,只須讓該類實(shí)現(xiàn)Edible接口即可。任何Edible對(duì)象都可以被傳遞以調(diào)用HowToEat方法。
關(guān)于java中抽象類和接口的相同和不同點(diǎn)是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。