java中的接口和抽象類

一、抽象類

1、抽象方法


抽象方法只有聲明,而沒有具體的實現(xiàn)。也就是說沒有{}。


抽象方法的聲明格式為:abstract void 方法名();


2、抽象類

包含一個抽象方法的類就是抽象類 使用abstract類就是抽象類

3、特點


1.抽象類與抽象方法必須使用abstract修飾


2.抽象類不允許創(chuàng)建對象


3.抽象類總可以有抽象方法也可以沒有抽象方法.如果抽象類中有帶主體方法子類繼承也可以直直接用


4.抽象類的子類使用
??? a.繼承抽象類,重寫抽象方法
??? b.抽象類的子類也可是抽象類


4.格式

public?abstract?class?People {?//關(guān)鍵詞abstract,聲明該類為抽象類
?????? public?int?age;
?????? public?void?Num() {
?????? }
?????? public?abstract?Name();?//聲明該方法為抽象方法
}

注意:
abstract不能與final并列修飾同一個類
abstract 不能與private、static、final或native并列修飾同一個方法。

5.使用

在下面這個例子中,把打印機類封裝成抽象類,把print定義成抽象類,當HPPrinter和CannonPrinter要繼承printer類的時候,必須重寫print函數(shù)。這樣寫的好處是,每個打印機都有自己打印方式,此舉可以防止子類沒有寫明打印方式。


public?abstract?void?Printer() {
?????? public?void?open() {
??????????? system.out.print("打印機開啟");
??????? }


??????? public?void close() {
??????????? system.out.print("打印機關(guān)閉");
??????? }


??????? abstract?void?print();?//把print方法定義為抽象方法
? }


public?HPPrinter?extends?Printer {
???????? void?print(){?//必須重寫抽象方法print()??
??????????????? system.out.print("惠普打印機開始打印");
????????? };
}


public?CanonPrinter?extends?Printer {
???? void?print(){?//必須重寫抽象方法print()
????????????? system.out.print("佳能打印機開始打印");
????? };
}


接口

接口可以理解為一種特殊的類,里面全部是由全局常量和公共的抽象方法組成

1.格式

public interface?interface 接口名稱{
? ? ? 全局常量
? ? ? 抽象方法
}

2.特點


1.使用關(guān)鍵字interface


2.接口的實現(xiàn)也必須通過子類,使用關(guān)鍵字implements,而且接口是可以多實現(xiàn)的
class?A?implements?Inter1,Inter2{?//Inter1和Inter2是接口???
?? ...
}


3.一個類可以同時繼承抽象類和接口
class?A?extends?Abs?implements?Inter1,Inter2{?//Abs是一個抽象類???
??? ...
}


4.一個接口不能繼承普通的類,但可以通過extends關(guān)鍵字繼承多個接口,實現(xiàn)接口的多繼承
interface?Inter?extends?Inter1,Inter2{?//Inter、Inter1、Inter2都為接口??
? ?? ...
}


5.接口中可以含有 變量和方法。但是要注意,接口中的變量會被隱式地指定為public static final變量(并且只能是public static final變量,用private修飾會報編譯錯誤),而方法會被隱式地指定為public abstract方法且只能是public abstract方法(用其他關(guān)鍵字,比如private、protected、static、 final等修飾會報編譯錯誤)


6.無構(gòu)造方法


抽象類和接口的區(qū)別


接口和抽象類區(qū)別

一、語義層次


public?abstract?class?People {?//關(guān)鍵詞abstract,聲明該類為抽象類
????? void?Num();      
????? abstract?void?Name();    //聲明該方法為抽象方法
}


Interface Person {
?????? void?Num();
?????? void?Name();
}


一、抽象類方式中,抽象類可以擁有任意范圍的成員數(shù)據(jù),同時也可以擁有自己的非抽象方法,但是接口方式中,它僅能夠有靜態(tài)、不能修改的成員數(shù)據(jù)(但是我們一般是不會在接口中使用成員數(shù)據(jù)),同時它所有的方法都必須是抽象的。


二、在某種程度上來說,接口是抽象類的特殊化。


三、對子類而言,它只能繼承一個抽象類(這是java為了數(shù)據(jù)安全而考慮的),但是卻可以實現(xiàn)多個接口。


二、設(shè)計層次


1、 抽象層次不同


抽象類是對類抽象,而接口是對行為的抽象。抽象類是對整個類整體進行抽象,包括屬性、行為,但是接口卻是對類局部(行為)進行抽象。


2、 跨域不同


抽象類所跨域的是具有相似特點的類,而接口卻可以跨域不同的類。我們知道抽象類是從子類中發(fā)現(xiàn)公共部分,然后泛化成抽象類,子類繼承該父類即可,但是接口不同。實現(xiàn)它的子類可以不存在任何關(guān)系,共同之處。例如貓、狗可以抽象成一個動物類抽象類,具備叫的方法。鳥、飛機可以實現(xiàn)飛Fly接口,具備飛的行為,這里我們總不能將鳥、飛機共用一個父類吧!所以說抽象類所體現(xiàn)的是一種繼承關(guān)系,要想使得繼承關(guān)系合理,父類和派生類之間必須存在"is-a" 關(guān)系,即父類和派生類在概念本質(zhì)上應(yīng)該是相同的。對于接口則不然,并不要求接口的實現(xiàn)者和接口定義在概念本質(zhì)上是一致的, 僅僅是實現(xiàn)了接口定義的契約而已。


3、 設(shè)計層次不同


對于抽象類而言,它是自下而上來設(shè)計的,我們要先知道子類才能抽象出父類,而接口則不同,它根本就不需要知道子類的存在,只需要定義一個規(guī)則即可,至于什么子類、什么時候怎么實現(xiàn)它一概不知。比如我們只有一個貓類在這里,如果你這是就抽象成一個動物類,是不是設(shè)計有點兒過度?我們起碼要有兩個動物類,貓、狗在這里,我們在抽象他們的共同點形成動物抽象類吧!所以說抽象類往往都是通過重構(gòu)而來的!但是接口就不同,比如說飛,我們根本就不知道會有什么東西來實現(xiàn)這個飛接口,怎么實現(xiàn)也不得而知,我們要做的就是事前定義好飛的行為接口。所以說抽象類是自底向上抽象而來的,接口是自頂向下設(shè)計出來的。


實例:

現(xiàn)在有個鳥類,鳥的屬性有種類,顏色,重量等,鳥的行為有吃,飛。但是有的鳥類只會奔跑不會飛(鴕鳥)。這時如果我們在一個Birds類中去定義飛和奔跑的行為,分別讓只會飛的鳥和只會奔跑的鳥都去繼承這個類,好像有些不太妥當。我們可以這樣解決:定義一個抽象類,屬性包括種類、顏色、重量,行為包括吃。在定義一個Fly接口,包含一個方法fly()。在定義一個Run接口,包含一個run()方法。如果只是會飛的鳥我們就繼承Birds類,實現(xiàn)Fly接口。如果只是會奔跑的鳥我們就實現(xiàn)Birds類,實現(xiàn)Run接口。如果繼承Birds類,實現(xiàn)了Fly和Run接口,那就是又會飛又會奔跑的鳥。實現(xiàn)代碼如下:

定義鳥的抽象類其中用3個成員變量一個eat的抽象方法,一個print方法
public?abstract?class?Birds?{?
???????? private?String?type;?
???????? private?String?color;?
???????? private?double?weight;?

???????? public?Birds(String?type,?String?color,?double?weight){?
??????????????? this.setType(type);?
?????????????? this.setColor(color);?
?????????????? this.setWeight(weight);?
? ? ? ? ?? }?

???????? public?abstract?void?eat();

???????? public?void?print(){?
????????????? System.out.println("種類:"+this.getType());?
????????????? System.out.println("顏色:"+this.getColor());?
????????????? System.out.println("重量:"+this.getWeight());?
? ? ? ? }

?????? public?String?getType()?{?
???????? ? ? return?type;?
?? ? ? }
? ? ? public?void?setType(String?type)?{?
????? ?? ?? this.type?=?type;
? ? ?? }?
????? public?String?getColor()?{?
????????? return?color;?
?????? }?
?????? public?void?setColor(String?color)?{?
????????? this.color?=?color;?
? ? ?? }?
???? public?double?getWeight()?{?
??????? return?weight;?
???? }?
??? public?void?setWeight(double?weight)?{?
??????? this.weight?=?weight;?
??? }?
}

定義飛的接口
public?interface?Fly?{?
??? void?fly();?
}?

定義跑的接口
public?interface?Run?{?
??? void?run();?
}?

/**
*?蜂鳥 繼承抽象類,實現(xiàn)Fly的接口
*/?
public?class?HummingBird?extends?Birds?implements?Fly?{
???? public?HummingBird(String?type,?String?color,?double?weight){?
???????? super(type,?color,?weight);?
???? }

??? @Override?
??? public?void?fly()?{
??????? //實現(xiàn)飛接口中的方法
??????? System.out.println("我是"+this.getType()+",我會fly。");?
??? }?

?? @Override?
?? public?void?eat()?{
?? //實現(xiàn)抽象類中的抽象方法
? ? System.out.print("我是"+this.getType()+",我吃花蜜。");?
?? }?
}?

/**
*?鴕鳥
*/??

public?class?OstrichBirds?extends?Birds?implements?Run?{
?????? public?OstrichBirds(String?type,?String?color,?double?weight)?{?
?????????? super(type,?color,?weight);?
? ? ? ? }?

???? @Override
?????? public?void?run()?{?
?????? System.out.println("我是"+this.getType()+",我會奔跑。");?
?????? }? ???

????? @Override?
?????? public?void?eat()?{?
?????? System.out.println("我是"+this.getType()+",我吃草。");?
????? }?
}?

public?class?Test?{?
???? public?static?void?main(String?[]?args){?
????????? //蜂鳥?
???????? Birds?hummingBirds?=new?HummingBird("蜂鳥",?"彩虹色",?2.3);?
? ? ? ?? hummingBirds.print();?
???????? hummingBirds.eat();?
???????? Fly?f?=?(Fly)?hummingBirds;?
???????? f.fly();??

?????? //鴕鳥?
??????? OstrichBirds?ostrichBirds?=new?OstrichBirds("鴕鳥",?"灰色",?200.2);?
??????? ostrichBirds.print();?
??????? ostrichBirds.eat();?
??????? ostrichBirds.run();?

??????? System.out.println("是否會飛=>"+(hummingBirds?instanceof?Fly));?
??????? }
}?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,652評論 18 399
  • 1.import static是Java 5增加的功能,就是將Import類中的靜態(tài)方法,可以作為本類的靜態(tài)方法來...
    XLsn0w閱讀 1,424評論 0 2
  • 面向?qū)ο笾饕槍γ嫦蜻^程。 面向過程的基本單元是函數(shù)。 什么是對象:EVERYTHING IS OBJECT(萬物...
    sinpi閱讀 1,220評論 0 4
  • 麥田里的守望者,純凈的空氣,干凈的樹枝,綠油油的麥田,呼吸到春天的氣息。 遠離了大城市的繁華,放下壓力,放下執(zhí)念...
    蓮花山的小薇閱讀 1,394評論 28 27

友情鏈接更多精彩內(nèi)容