多態(tài)翰撑、接口、內(nèi)部類與單例模型

多態(tài)

概念:

意味著允許不同類的對象對同一消息做出不同的響應(yīng)

必要條件:

1遵倦、滿足繼承關(guān)系

2尽超、父類引用指向子類

編譯時多態(tài)(設(shè)計時多態(tài))

運行時多態(tài)(運行時多態(tài))

向上轉(zhuǎn)型(隱式轉(zhuǎn)型、自動轉(zhuǎn)型):
        父類引用指向子類實例梧躺,可以調(diào)用子類重寫父類的方法以及父類派生的方法似谁,無法調(diào)用子類獨有的方法,是小類轉(zhuǎn)大類
Animal one = new Animal();
Animal two  = new Cat();
Animal three = new Dog();
one.eat();
two.eat();
three.eat();

結(jié)果:

動物都有吃東西的能力
貓吃魚~~
狗吃肉~~
向下轉(zhuǎn)型(強制類型轉(zhuǎn)換)
    子類引用指向父類對象掠哥,此處必須進行強轉(zhuǎn)巩踏。可以調(diào)用子類特有的方法续搀,必須滿足轉(zhuǎn)型條件才能轉(zhuǎn)換
Cat temp = (Cat)two;
temp.eat();
temp.run();

結(jié)果:

貓吃魚~~
小貓在快樂的奔跑

instanceof運算符:

作用:判斷對象是否滿足某個特定類型塞琼,判斷左邊的對象是否是右邊類型的實例

返回true或false
if(two instanceof Cat){
    Cat temp = (Cat)two;
    System.out.println("two可以轉(zhuǎn)換為Cat類型");
}
if(two instanceof Dog){
    Dog temp2 = (Dog)two;
    System.out.println("two可以轉(zhuǎn)換為Dog類型");
}
if(two instanceof Animal){
    System.out.println("Animal");
}
if(two instanceof Object){
    System.out.println("Object");
}

結(jié)果:

two可以轉(zhuǎn)換為Cat類型
Animal
Object

由此結(jié)果我們可知two滿足Cat的類型的特征禁舷,也滿足Cat類型的父類Animal和Object類型的特征

Master案例:

需求:

  • 喂寵物
  • 喂貓咪:吃完東西后彪杉,主人會帶著去玩線球
  • 喂狗狗:吃完東西后,主人會帶著狗狗去睡覺
  • 主人時間充足的條件下養(yǎng)狗狗
  • 主人時間不充足的條件下養(yǎng)貓咪

Cat.java

//方法:吃東西(重寫父類方法)
@Override
    public void eat() {
        System.out.println("貓吃魚~~");
    }
//方法:玩線球
public void playBall() {
        // TODO Auto-generated method stub
        System.out.println("小貓喜歡玩線球");
    }

Dog.java

//方法:吃東西(重寫父類方法)
    @Override
    public void eat() {
        System.out.println("狗吃肉~~");
        
    }
//方法:睡覺
    public void sleep(){
        System.out.println("小狗有午睡的習(xí)慣");
    }

Master.java

//方案:編寫方法傳入動物的父類牵咙,方法中通過類型轉(zhuǎn)換派近,調(diào)用指定子類的方法
public void feed(Animal obj){
        obj.eat();
        if(obj instanceof Cat){
            Cat temp=(Cat)obj;
            temp.playBall();
        }else if(obj instanceof Dog){
            Dog temp=(Dog)obj;
            temp.sleep();
        }
    }
//
public Animal raise(boolean isManyTime){
        if(isManyTime){
            System.out.println("主人休閑時間比較充足,適合養(yǎng)狗狗");
            return new Dog();
        }else{
            System.out.println("主人平時比較忙碌洁桌,適合養(yǎng)貓咪");
            return new Cat();
        }
    }

MasterTest.java

Master master=new Master();
Cat one=new Cat();
Dog two=new Dog();
master.feed(one);
master.feed(two);
System.out.println("=============");
        boolean isManyTime=false;
        Animal temp=master.raise(isManyTime);
        System.out.println(temp);

結(jié)果:

貓吃魚~~
小貓喜歡玩線球
狗吃肉~~
小狗有午睡的習(xí)慣
=============
主人平時比較忙碌渴丸,適合養(yǎng)貓咪
com.imooc.animal.Cat@15db9742

接口:

定義接口:interface
package com.imooc.tel;

/**
 * 具有照相能力的接口
 * @author imooc
 *
 */
public interface IPhoto {
    //具有拍照的能力
    public void photo();
    }
    
//  void network();
}

實現(xiàn)接口:implements

一個類去實現(xiàn)一個接口使用到的關(guān)鍵字是implements

一個類去實現(xiàn)一個接口的時候需要去實現(xiàn)這個接口當(dāng)中的方法

Camera.java

package com.imooc.tel;

public class Camera implements IPhoto{

    @Override
    public void photo() {
        // TODO Auto-generated method stub
        System.out.println("相機可以拍照");
    }

FourthPhone.java

package com.imooc.tel;

public class FourthPhone extends ThirdPhone implements IPhoto,INet{

    public void game(){
        System.out.println("手機可以玩游戲");
    }
    @Override
    public void photo() {
        // TODO Auto-generated method stub
        System.out.println("手機可以拍照");
    }

PhoneTest.java

package com.imooc.test;

import com.imooc.tel.Camera;
import com.imooc.tel.FourthPhone;
import com.imooc.tel.INet;
import com.imooc.tel.IPhoto;
import com.imooc.tel.SmartWatch;

public class PhoneTest {

    public static void main(String[] args) {
        IPhoto ip=new FourthPhone();
        ip.photo();
        ip=new Camera();
        ip.photo();
        
    }

}

結(jié)果:

相機可以拍照
手機可以拍照
default:默認方法,可以帶方法體
    //default:默認方法 可以帶方法體 jdk1.8后新增
    //可以在實現(xiàn)類中重寫另凌,并可以通過接口的引用調(diào)用
    default void connection(){
        System.out.println("我是接口中的默認鏈接");
    }
    

default實現(xiàn)類的重寫:

系統(tǒng)自動加上public訪問權(quán)限

INet.super.connection();//接調(diào)用接口中默認的方法

如果不填super的話谱轨,通過接口名打點調(diào)用的是當(dāng)前接口的靜態(tài)成員

static:靜態(tài)方法 可以帶方法體 ,通過接口名去調(diào)用

INet.java

    //static:靜態(tài)方法 可以帶方法體 jdk1.8后新增
    //不可以在實現(xiàn)類中重寫,可以同接口名調(diào)用
    static void stop(){
        System.out.println("我是接口中的靜態(tài)方法");
    }

PhoneText.java

INet.stop();

一個類可以實現(xiàn)多個接口吠谢,但注意去實現(xiàn)接口中待重寫的方法土童,否則這個類也會變成抽象類

當(dāng)一個類實現(xiàn)多個接口,接口中有多個同名的方法時工坊,實現(xiàn)類必須要重寫一個滿足自己特征的同名方法娜扇,如果這個實現(xiàn)類中的父類有同名方法時错沃,默認情況下會調(diào)用父類的同名方法, 但屬性則不同雀瓢,父類沒有優(yōu)先權(quán)

接口的繼承:

1、Java中的接口也可以實現(xiàn)接口玉掸,且可以有多個父接口

2刃麸、當(dāng)父接口中存在同名方法時,需要在自己的接口李創(chuàng)建自己的同名方法司浪,不用任何一個父接口里的方法

內(nèi)部類:

定義:

在Java中泊业,可以將一個類定義在另一個類里面或者一個方法里面,這樣的類稱為內(nèi)部類

分類:

  • 成員內(nèi)部類(普通內(nèi)部類)
  • 靜態(tài)內(nèi)部類
  • 方法內(nèi)部類(局部內(nèi)部類)
  • 匿名內(nèi)部類
成員內(nèi)部類:
* 內(nèi)部類在外部使用時啊易,無法直接實例化吁伺,需要借由外部類信息才能完成實例化 
* 內(nèi)部類的訪問修飾符,可以任意租谈,但是訪問范圍會受到影響
* 內(nèi)部類可以直接訪問外部類的成員篮奄;如果出現(xiàn)同名屬性,優(yōu)先訪問內(nèi)部類中定義的
* 可以使用外部類.this.成員的方式割去,訪問外部類中同名的信息 
* 外部類訪問內(nèi)部類信息窟却,需要通過內(nèi)部類實例,無法直接訪問 
* 內(nèi)部類編譯后.class文件命名:外部類$內(nèi)部類.class
* 內(nèi)部類中是否可以包含與外部類相同方法簽名的方法呻逆?以及如何調(diào)用夸赫?



如何獲取內(nèi)部類實例對象:

方法一:

//獲取成員內(nèi)部類對象實例,方式1:new 外部類.new 內(nèi)部類
Person.Heart myHeart=new Person().new Heart();
System.out.println(myHeart.beat());

方法二:

 //獲取成員內(nèi)部類對象實例咖城,方式2:外部類對象.new 內(nèi)部類
myHeart=lili.new Heart();
System.out.println(myHeart.beat());

方法三:

//獲取成員內(nèi)部類對象實例茬腿,方式3:外部類對象.獲取方法
myHeart=lili.getHeart();
System.out.println(myHeart.beat());
靜態(tài)內(nèi)部類:
  • 靜態(tài)內(nèi)部類中,只能直接訪問外部類的靜態(tài)成員宜雀,如果需要調(diào)用非靜態(tài)成員切平,可以通過對象實例

    static class Heart {
         int age = 13;
         int temp = 22;
    
         public String beat() {
                //對象實例
             new Person().eat();
             return new Person.age + "歲的心臟在跳動";
         }
     }
    
  • 靜態(tài)內(nèi)部類對象實例時,可以不依賴于外部類對象

  • 可以通過外部類.內(nèi)部類.靜態(tài)成員的方式州袒,訪問內(nèi)部類中的靜態(tài)成員

  • 當(dāng)內(nèi)部類屬性與外部類屬性同名時揭绑,默認直接調(diào)用內(nèi)部類中的成員;

  • 如果需要訪問外部類中的靜態(tài)屬性郎哭,則可以通過 外部類.屬性 的方式他匪;

  • 如果需要訪問外部類中的非靜態(tài)屬性,則可以通過 new 外部類().屬性的方式夸研;

獲取靜態(tài)內(nèi)部類對象實例方法:

Person.Heart myHeart=new Person.Heart();
System.out.println(myHeart.beat()); 
方法內(nèi)部類:
  • 定義在方法內(nèi)部邦蜜,作用范圍也在方法內(nèi)
  • 和方法內(nèi)部成員使用規(guī)則一樣,class前面不可以添加public亥至、private悼沈、protected贱迟、static
  • 類中不能包含靜態(tài)成員
  • 類中可以包含final、abstract修飾的成員
public Object getHeart() {
    
        class Heart {
            public final int age = 13;
            int temp = 22;

            public final void say() {
                System.out.println("hello");
            }

            public void eat() {

            }

            public String beat() {
                new Person().eat();
                return Person.age + "歲的心臟在跳動";
            }
        }
        return new Heart().beat();
        // new Heart().temp=12;
        //// temp=33;
        // return new Heart();
    }
##### 匿名內(nèi)部類:
定義:
對某個類的實例只會使用一次絮供,這個類的名字對于整個程序而言就可有可無了衣吠,這時我們將類的定義與累的創(chuàng)建放到一起 完成
  • 匿名內(nèi)部類沒有類型名稱、實例對象名稱
  • 編譯后的文件命名:外部類$數(shù)字.class
  • 無法使用private壤靶、public缚俏、protected、abstract贮乳、static修飾
  • 無法編寫構(gòu)造方法忧换,可以添加構(gòu)造代碼塊
  • 不能出現(xiàn)靜態(tài)成員
  • 匿名內(nèi)部類可以實現(xiàn)接口也可以繼承父類,但不可兼得
test.getRead(new Person(){
            {
                //構(gòu)造代碼塊
            }
//          public static int age=12;
            @Override
            public void read() {
                // TODO Auto-generated method stub
                System.out.println("男生喜歡看科幻類書籍");
            }
            
        });
        test.getRead(new Person(){

            @Override
            public void read() {
                // TODO Auto-generated method stub
                System.out.println("女生喜歡讀言情小說");
            }
            
        });

單例模式:

要點:

    1向拆、某個類只能有一個實例
    2亚茬、必須自行創(chuàng)建實例
    3、必須自行向整個系統(tǒng)提供這個實例

實現(xiàn):

    1浓恳、只提供私有的構(gòu)造方法
    2刹缝、含有一個該類的靜態(tài)私有對象
    3、提供一個靜態(tài)的公有方法用于創(chuàng)建奖蔓、獲取靜態(tài)私有對象
餓漢式:對象創(chuàng)建過程中實例化
package com.imooc.singleton;

//餓漢式:創(chuàng)建對象實例的時候直接初始化  空間換時間
public class SingletonOne {
    //1赞草、創(chuàng)建類中私有構(gòu)造
    private SingletonOne(){
        
    }
    
    //2、創(chuàng)建該類型的私有靜態(tài)實例
    private static SingletonOne instance=new SingletonOne();
    
    //3吆鹤、創(chuàng)建公有靜態(tài)方法返回靜態(tài)實例對象
    public static SingletonOne getInstance(){
        return instance;
    }
}
懶漢式:靜態(tài)公有方法中實例化
package com.imooc.singleton;
//懶漢式:類內(nèi)實例對象創(chuàng)建時并不直接初始化厨疙,直到第一次調(diào)用get方法時,才完成初始化操作
//時間換空間
public class SingletonTwo {
    //1疑务、創(chuàng)建私有構(gòu)造方法
    private SingletonTwo(){
        
    }
    
    //2沾凄、創(chuàng)建靜態(tài)的該類實例對象
    private static SingletonTwo instance=null;
    
    //3、創(chuàng)建開放的靜態(tài)方法提供實例對象
    public static SingletonTwo getInstance(){
        if(instance==null)
            instance=new SingletonTwo();
        
        return instance;
    }
}

優(yōu)點:

1知允、在內(nèi)存中只有一個對象撒蟀,節(jié)省內(nèi)存空間

2、避免頻繁的創(chuàng)建銷毀對象温鸽,提高性能

3保屯、避免對共享資源的多重占用

缺點:

1、擴展比較困難

2涤垫、如果實例化后的對象長期不利用姑尺,系統(tǒng)將默認為垃圾進行回收,造成對象狀態(tài)丟失

使用場景:

1蝠猬、創(chuàng)建對象時占用資源過多切蟋,單同時有需要用到該類對象

2、系統(tǒng)內(nèi)資源要求同一讀寫榆芦,如讀寫配置信息

3柄粹、當(dāng)多個實例存在可能引起程序邏輯錯誤喘鸟,如號碼生成器

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市驻右,隨后出現(xiàn)的幾起案子什黑,更是在濱河造成了極大的恐慌,老刑警劉巖堪夭,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兑凿,死亡現(xiàn)場離奇詭異,居然都是意外死亡茵瘾,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門咐鹤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拗秘,“玉大人,你說我怎么就攤上這事祈惶〉裰迹” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵捧请,是天一觀的道長凡涩。 經(jīng)常有香客問我,道長疹蛉,這世上最難降的妖魔是什么活箕? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮可款,結(jié)果婚禮上育韩,老公的妹妹穿的比我還像新娘。我一直安慰自己闺鲸,他們只是感情好筋讨,可當(dāng)我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著摸恍,像睡著了一般悉罕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上立镶,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天壁袄,我揣著相機與錄音,去河邊找鬼谜慌。 笑死然想,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的欣范。 我是一名探鬼主播变泄,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼令哟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了妨蛹?” 一聲冷哼從身側(cè)響起屏富,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蛙卤,沒想到半個月后狠半,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡颤难,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年神年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片行嗤。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡已日,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出栅屏,到底是詐尸還是另有隱情飘千,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布栈雳,位于F島的核電站护奈,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏哥纫。R本人自食惡果不足惜霉旗,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望磺箕。 院中可真熱鬧奖慌,春花似錦、人聲如沸松靡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽雕欺。三九已至岛马,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間屠列,已是汗流浹背啦逆。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留笛洛,地道東北人夏志。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像苛让,于是被迫代替她去往敵國和親沟蔑。 傳聞我的和親對象是個殘疾皇子湿诊,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,960評論 2 355

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

  • 1.什么是設(shè)計模式 設(shè)計模式(Design pattern)是一套被反復(fù)使用的、多數(shù)人知曉的瘦材、經(jīng)過分類編目的厅须、代碼...
    滄海一粟謙閱讀 330評論 0 1
  • 單例模式概述 滾滾歷史,朝代不斷更迭食棕,但卻存在著永恒定律朗和,比如一個朝代皇帝無論怎么更換,有且只有一個簿晓,而對于軍隊而...
    若兮緣閱讀 315評論 0 6
  • 滾滾歷史眶拉,朝代更迭,永恒定律: 一個朝代皇帝只有一憔儿,軍隊的最高司令官只有一個镀层,一山不容二虎 計算機系統(tǒng):1、驅(qū)動程...
    西紅柿蓋澆面閱讀 216評論 0 0
  • Lecture1 設(shè)計模式概述 設(shè)計模式:一套被反復(fù)使用皿曲、多數(shù)人知曉、經(jīng)過分類編目的代碼設(shè)計經(jīng)驗的總結(jié)(是軟件開發(fā)...
    Mr董先森閱讀 302評論 0 0
  • 要點 某個類只能有一個實例 必須自行創(chuàng)建實例 必須向整個系統(tǒng)提供這個實例 優(yōu)點 在內(nèi)存中只有一個對象吴侦,節(jié)省內(nèi)存空間...
    媛猿YY閱讀 130評論 0 0