Java中的面向?qū)ο蟮暮唵谓榻B(四)接口和多態(tài)

因?yàn)镴ava中繼承具有單一性锤岸,只能繼承一個(gè)父類,所以為了處理這種局限性,Java又提供了接口击敌。

接口interface

是一個(gè)比抽象類還要抽象的類,因?yàn)槠鋬?nèi)部的所有方法全部都是抽象方法拴事。
同時(shí)接口和類的關(guān)系也不再是繼承(extends)而是實(shí)現(xiàn)(implements)

接口的特點(diǎn):

  • 只能有抽象方法
  • 只能有常量沃斤,默認(rèn)使用public static final修飾
  • 方法默認(rèn)就被public abstract修飾,并且也只能被public abstract修飾
  • 一樣的,接口也不能實(shí)例化
  • 類和接口的關(guān)系不再是extends刃宵,而是implements衡瓶,并且也要實(shí)現(xiàn)它所有的方法(@Override)
public class InterfaceDemo {
    public static void main(String[] args) {
        Cat c = new Cat();
        c.eat(); // 貓吃魚
        System.out.println(Animal.num); // 3 可以直接訪問接口內(nèi)部的常量
    }
}

interface Animal { // 聲明接口和聲明類很相似
    public static final int num = 3; // 接口內(nèi)部只支持使用常量,并且默認(rèn)使用public static final來修飾  當(dāng)然可以直接寫出int num = 3;
    public abstract void eat(); // 內(nèi)部的方法默認(rèn)使用public abstract修飾牲证,同時(shí)也只允許使用public abstract修飾哮针,也可以直接寫成void eat();
}

class Cat implements Animal { // 類和接口的關(guān)系是implements
    @Override
    public void eat() { // 必須要重寫接口中的所有方法
        System.out.println("貓吃魚");
    }
}

梳理一下接口和類之間的各種關(guān)系:

  • 類和類: extends, 單一繼承,多層繼承
  • 類和接口: implements, 多實(shí)現(xiàn)(可以實(shí)現(xiàn)多個(gè)接口)
  • 接口和接口: extends坦袍,接口之間不可以實(shí)現(xiàn)只可以繼承十厢,同時(shí)也是單一繼承,多層繼承

接口的優(yōu)點(diǎn):

  • 一個(gè)類可以實(shí)現(xiàn)多個(gè)接口捂齐,解決了extends的單一性問題
  • 接口的所有成員都是public蛮放,可以對(duì)外提供一套規(guī)范
  • 降低了程序的耦合性

接口和抽象類的比較:

  • 相似點(diǎn):
    • 都是不斷的抽取出抽象的概念
  • 不同點(diǎn):
    • 抽象類也是類,只能單一繼承奠宜,而類可以實(shí)現(xiàn)多個(gè)接口
    • 成員方面包颁,抽象類可以有常量和成員變量,但是接口只能有變量压真。抽象類還可以有非抽象方法娩嚼,接口必須都是抽象方法并且修飾符默認(rèn)為public abstract
    • 構(gòu)造方法方面,抽象類是有構(gòu)造函數(shù)的榴都,但是接口沒有構(gòu)造函數(shù)

匿名對(duì)象

沒有變量引用的對(duì)象

public class AnooymousObjDemo {
    public static void main(String[] args) {
        new Test("DeeJay").show(); // name: DeeJay
    }
}

class Test {
    String name;
    public Test(String name) {
        this.name = name;
    }
    public void show() {
        System.out.println("name: "+ name);
    }
}

一般當(dāng)方法只調(diào)用一次的時(shí)候可以使用匿名對(duì)象待锈。

final關(guān)鍵字

修飾符,可以修飾類嘴高,成員方法竿音,以及成員變量

  • final修飾的類不可以被繼承和屎。
  • final修飾的成員方法不可以被重寫
  • final修飾的成員變量不可以被賦值,哪怕賦的是原值春瞬。即是常量

另外自定義常量必須初始化柴信,可以直接賦值,或者在構(gòu)造方法中初始化都可宽气。


public class FinalDemo {
    public static void main(String[] args) {
        Animal3 a3 = new Animal3();
        // a3.num = 10; // the final fields cannot be assigned  final修飾的成員變量不可以被賦值随常,哪怕賦的是原值。即是常量,一般命名使用大寫萄涯。
    }
}

final class Animal {
    public void eat(){
        System.out.println("eating");
    }
}

// class Dog extends Animal {} // cannot subclass the final class   final修飾的類不可以被繼承

class Animal2 {
    final public void eat(){ // final修飾成員方法
        System.out.println("eating");
    }
}
class Dog2 extends Animal2 {
    // public void eat() {} // cannot Override the final method  final修飾的成員方法不可以被重寫
}

class Animal3 {
    final int num = 3;
}

多態(tài)

多態(tài)的前提:

  • 子父類的繼承關(guān)系
  • 方法的重寫
  • 父類引用指向子類對(duì)象 Dad d = new Child();

多態(tài)的成員特點(diǎn):

  • 成員變量:成員變量在繼承時(shí)沒有重寫的概念绪氛,也沒有動(dòng)態(tài)綁定的概念,所以運(yùn)行時(shí)指向的是父類的成員變量涝影。
  • 成員方法: 成員方法運(yùn)行時(shí)枣察,指向的是子類中被重寫的方法
  • 靜態(tài)方法: 調(diào)用的靜態(tài)方法是父類的靜態(tài)方法,因?yàn)閟tatic是跟著類型走的燃逻。

public class PolymorphismDemo {
    public static void main(String[] args) {
        Dad d = new Child();
        System.out.println(d.num); // 20 成員變量在繼承時(shí)沒有重寫的概念序目,也沒有動(dòng)態(tài)綁定的概念。 所以這邊的是父類的成員變量伯襟。
        d.show(); // child 成員方法運(yùn)行時(shí)猿涨,指向的是子類中被重寫的方法
        d.show2(); // dad static  d變量類型還是Dad型,所以調(diào)用的靜態(tài)方法是Dad類的靜態(tài)方法
    }
}

class Dad {
    int num = 20;
    public void show() {
        System.out.println("dad");
    }
    public static void show2() {
        System.out.println("dad static");
    }
}
class Child extends Dad {
    int num = 10;
    public void show() {
        System.out.println("child");
    }
    public static void show2() {
        System.out.println("child static");
    }
}

多態(tài)中的類型轉(zhuǎn)換:

public class PolymorphismDemo {
    public static void main(String[] args) {
        //向下轉(zhuǎn)型
        Dad2 d2 = new Child2();
        Child2 c2 = (Child2)d2; // 強(qiáng)制的進(jìn)行了類型轉(zhuǎn)換  從Dad2類型到了Child2類型姆怪。 向下轉(zhuǎn)型
        c2.show(); // child 向下轉(zhuǎn)型了之后就可以調(diào)用子類的方法
    }
}

// 關(guān)于多態(tài)中引用類型的轉(zhuǎn)換  向上轉(zhuǎn)換Dad d = new Child(); 已經(jīng)隱式的進(jìn)行了轉(zhuǎn)換叛赚,從小到大向上轉(zhuǎn)換即從子類型到父類型
// 對(duì)于向下轉(zhuǎn)換即從父類轉(zhuǎn)到子類,一般是由于想訪問子類中特有的成員才執(zhí)行的稽揭,需要強(qiáng)制進(jìn)行類型轉(zhuǎn)換
class Dad2 {}
class Child2 extends Dad2{
    public void show() {
        System.out.println("child");
    }
}

多態(tài)的優(yōu)缺點(diǎn):

缺點(diǎn):

  • 無法直接訪問子類特有的成員红伦,如果非要訪問,需要向下轉(zhuǎn)型
    優(yōu)點(diǎn):
  • 提高可維護(hù)性和可擴(kuò)展性

對(duì)于提高可擴(kuò)展性淀衣,來寫一個(gè)例子:

package com.polymorphism;

public class PolymorphismDemo {
    public static void main(String[] args) {
        Factory f = new Factory();
        f.createPhone(new MiPhone());
        f.createPhone(new MeiZuPhone());
    }
}

class Factory {
    public void createPhone(MiPhone mp) { 
        System.out.println("create phone");
        mp.call();
    }
    
    public void createPhone(MeiZuPhone mzp) { // 隨著手機(jī)類越來越多    Factory類中要一直新增createPhone的重載方法
        System.out.println("create phone");
        mzp.call();
    }
}

class MiPhone {
    public void call() {
        System.out.println("MI phone is calling");
    }
}

class MeiZuPhone {
    public void call () {
        System.out.println("MeiZuPhone is calling");
    }
}

上面這個(gè)例子中昙读,F(xiàn)actory類中的方法隨著手機(jī)類的增多,被迫要一次次的新增一個(gè)重載的方法膨桥。

我們可以使用多態(tài)來改寫這個(gè)例子:

package com.polymorphism;

public class PolymorphismDemo2 {
    public static void main(String[] args) {
        Factory2 f2 = new Factory2();
        f2.createPhone(new MiPhone2());
        f2.createPhone(new MeiZuPhone2());
    }
}

class Factory2 {
    public void createPhone(Phone p) {  // 不需要每新增一個(gè)手機(jī)類就實(shí)現(xiàn)一次重載 
        System.out.println("create phone");
        p.call();
    }
}

interface Phone { // 創(chuàng)建一個(gè)公共的接口  讓其他的手機(jī)類來實(shí)現(xiàn)這個(gè)接口   在Factory2的方法中就可以只傳人實(shí)現(xiàn)了這個(gè)Phone 類型的變量
    public abstract void call(); 
}

class MiPhone2 implements Phone { // 實(shí)現(xiàn)公共接口   具體的方法在類內(nèi)部進(jìn)行定義
    public void call() {
        System.out.println("MI phone is calling");
    }
}

class MeiZuPhone2 implements Phone { // 實(shí)現(xiàn)公共接口   具體的方法在類內(nèi)部進(jìn)行定義
    public void call () {
        System.out.println("MeiZuPhone is calling");
    }
}

在改進(jìn)的例子中蛮浑,我們寫了一個(gè)公共的接口Phone,所有的手機(jī)類都來實(shí)現(xiàn)這個(gè)接口只嚣,最后在Factory2中的方法中沮稚,我們只需要傳入Phone p的參數(shù)就可以了,不用關(guān)心它具體是什么類型册舞,從而就避免了一直重載方法的尷尬蕴掏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子盛杰,更是在濱河造成了極大的恐慌挽荡,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件即供,死亡現(xiàn)場離奇詭異定拟,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)逗嫡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門青自,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人驱证,你說我怎么就攤上這事延窜。” “怎么了抹锄?”我有些...
    開封第一講書人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵需曾,是天一觀的道長。 經(jīng)常有香客問我祈远,道長,這世上最難降的妖魔是什么商源? 我笑而不...
    開封第一講書人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任车份,我火速辦了婚禮,結(jié)果婚禮上牡彻,老公的妹妹穿的比我還像新娘扫沼。我一直安慰自己,他們只是感情好庄吼,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開白布缎除。 她就那樣靜靜地躺著,像睡著了一般总寻。 火紅的嫁衣襯著肌膚如雪器罐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評(píng)論 1 291
  • 那天渐行,我揣著相機(jī)與錄音轰坊,去河邊找鬼。 笑死祟印,一個(gè)胖子當(dāng)著我的面吹牛肴沫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蕴忆,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼颤芬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起站蝠,我...
    開封第一講書人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤汰具,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后沉衣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體郁副,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年豌习,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了存谎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡肥隆,死狀恐怖既荚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情栋艳,我是刑警寧澤恰聘,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站吸占,受9級(jí)特大地震影響晴叨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜矾屯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一兼蕊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧件蚕,春花似錦孙技、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至妄痪,卻和暖如春哈雏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背衫生。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來泰國打工僧著, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人障簿。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓盹愚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親站故。 傳聞我的和親對(duì)象是個(gè)殘疾皇子皆怕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容