Java筆記-面向?qū)ο?多態(tài)

多態(tài):一個(gè)對(duì)象具備多種形態(tài)旷偿。(父類的引用類型變量指向了子類的對(duì)象)
或者是接口 的引用類型變量指向了接口實(shí)現(xiàn)類的對(duì)象)

運(yùn)行時(shí)多態(tài)存在的三個(gè)必要條件:

  1. 要有繼承(包括接口的實(shí)現(xiàn))值依;
  2. 要有重寫鳄乏;
  3. 父類引用指向子類對(duì)象籍茧。 父類 a = new 子類();

運(yùn)行時(shí)多態(tài)的解釋:
1.運(yùn)行時(shí)多態(tài)是指程序中定義的引用變量所指向的具體類型
2.通過該引用變量發(fā)出的方法調(diào)用在編程時(shí)并不確定闷板,而是在程序運(yùn)行期間才確定架谎,即一個(gè)引用變量倒底會(huì)指向哪個(gè)類的實(shí)例對(duì)象讲冠,該引用變量發(fā)出的方法調(diào)用到底是哪個(gè)類中實(shí)現(xiàn)的方法先鱼,必須在由程序運(yùn)行期間才能決定.

多態(tài)的好處:
1.可替換性(substitutability)俭正。多態(tài)對(duì)已存在代碼具有可替換性。例如焙畔,多態(tài)對(duì)圓Circle類工作掸读,對(duì)其他任何圓形幾何體,如圓環(huán)宏多,也同樣工作儿惫。
2.可擴(kuò)充性(extensibility)。多態(tài)對(duì)代碼具有可擴(kuò)充性伸但。增加新的子類不影響已存在類的多態(tài)性肾请、繼承性,以及其他特性的運(yùn)行和操作更胖。實(shí)際上新加子類更容易獲得多態(tài)功能铛铁。例如,在實(shí)現(xiàn)了圓錐却妨、半圓錐以及半球體的多態(tài)基礎(chǔ)上饵逐,很容易增添球體類的多態(tài)性。
3.接口性(interface-ability)管呵。多態(tài)是超類通過方法簽名梳毙,向子類提供了一個(gè)共同接口,由子類來完善或者覆蓋它而實(shí)現(xiàn)的捐下。超類Shape規(guī)定了兩個(gè)實(shí)現(xiàn)多態(tài)的接口方法账锹,computeArea()以及computeVolume()。子類坷襟,如Circle和Sphere為了實(shí)現(xiàn)多態(tài)奸柬,完善或者覆蓋這兩個(gè)接口方法。
4.靈活性(flexibility)婴程。它在應(yīng)用中體現(xiàn)了靈活多樣的操作廓奕,提高了使用效率。
5.簡(jiǎn)化性(simplicity)。多態(tài)簡(jiǎn)化對(duì)應(yīng)用軟件的代碼編寫和修改過程桌粉,尤其在處理大量對(duì)象的運(yùn)算和操作時(shí)蒸绩,這個(gè)特點(diǎn)尤為突出和重要。

多態(tài)的應(yīng)用:

  1. 多態(tài)用于形參類型的時(shí)候铃肯,可以接收更多類型的數(shù)據(jù) 患亿。
  2. 多態(tài)用于返回值類型的時(shí)候,可以返回更多類型的數(shù)據(jù)押逼。

多態(tài)要注意 的細(xì)節(jié):
1. 多態(tài)情況下步藕,子父類存在同名的成員變量時(shí),訪問的是父類的成員變量挑格。
2. 多態(tài)情況下咙冗,子父類存在同名的非靜態(tài)的成員函數(shù)時(shí),訪問的是子類的成員函數(shù)漂彤。
3. 多態(tài)情況下雾消,子父類存在同名的靜態(tài)的成員函數(shù)時(shí),訪問的是父類的成員函數(shù)显歧。

4.  多態(tài)情況下仪或,不能訪問子類特有的成員。

總結(jié):多態(tài)情況下士骤,子父類存在同名的成員時(shí)范删,訪問的都是父類的成員,除了在同名非靜態(tài)函數(shù)時(shí)才是訪問子類的拷肌。

編譯看左邊到旦,運(yùn)行不一定看右邊。

編譯看左邊:java編譯器在編譯的時(shí)候巨缘,會(huì)檢查引用類型變量所屬的類是否具備指定的成員添忘,如果不具備馬上編譯報(bào)錯(cuò)

  • 成員內(nèi)部類
    第一種:內(nèi)部類:

一個(gè)類定義在另外一個(gè)類的內(nèi)部,那么該類就稱作為內(nèi)部類若锁。

內(nèi)部類的class文件名: 外部類$內(nèi)部類. 好處:便于區(qū)分該class文件是屬于哪個(gè)外部類的搁骑。

內(nèi)部類的類別:
成員內(nèi)部類:
成員內(nèi)部類的訪問方式:

1.在外部類提供一個(gè)方法創(chuàng)建內(nèi)部類的對(duì)象進(jìn)行訪問。

2.在其他類直接創(chuàng)建內(nèi)部類的對(duì)象又固。 格式:
外部類.內(nèi)部類 變量名 = new 外部類().new 內(nèi)部類();

注意: 如果是一個(gè)靜態(tài)內(nèi)部類仲器,那么在其他類創(chuàng)建 的格式:
外部類.內(nèi)部類 變量名 = new 外部類.內(nèi)部類();

內(nèi)部類的應(yīng)用場(chǎng)景: 我們?cè)诿枋鯝事物的時(shí)候,發(fā)現(xiàn)描述的A事物內(nèi)部還存在另外一個(gè)比較復(fù)雜的事物B時(shí)候仰冠,而且這個(gè)比較復(fù)雜事物B還需要訪問A事物的屬性等數(shù)據(jù)乏冀,那么這時(shí)候我們就可以使用內(nèi)部類描述B事物。
內(nèi)部類的好處:內(nèi)部類可以直接訪問外部類的所有成員洋只。

內(nèi)部類要注意的細(xì)節(jié):

  1. 如果外部類與內(nèi)部類存在同名的成員變量時(shí)辆沦,在內(nèi)部類中默認(rèn)情況下是訪問內(nèi)部類的成員變量昼捍。
    可以通過"外部類.this.成員變量名" 指定訪問外部類的 成員。
  2. 私有的成員內(nèi)部類只能在外部類提供一個(gè)方法創(chuàng)建內(nèi)部類的對(duì)象進(jìn)行訪問肢扯,不能在其他類創(chuàng)建對(duì)象了妒茬。
  3. 成員內(nèi)部類一旦出現(xiàn)了靜態(tài)的成員,那么該類也必須 使用static修飾蔚晨。

第二種:局部?jī)?nèi)部類

局部?jī)?nèi)部類: 在一個(gè)類 的方法內(nèi)部定義另外一個(gè)類郊闯,那么另外一個(gè)類就稱作為局部?jī)?nèi)部類。

局部?jī)?nèi)部類要注意的細(xì)節(jié):
如果局部 內(nèi)部類訪問了一個(gè)局部變量蛛株,那么該局部變量必須使用final修飾、

第三種:匿名內(nèi)部類
:沒有類名的類就稱作為匿名內(nèi)部類育拨。

匿名內(nèi)部類的好處:簡(jiǎn)化書寫谨履。

匿名內(nèi)部類的使用前提:必須存在繼承或者實(shí)現(xiàn)關(guān)系才能使用。

public class UserAccount {

    public void print() {
        
        /// 需求: 在方法內(nèi)部定義一個(gè)類繼承自Person類熬丧,然后執(zhí)行eat和sleep方法笋粟,
        
        /**
         * 第一種方式:局部?jī)?nèi)部類的方式,此種方式比較麻煩
         
        class Student extends Person {
            public Student(String name) {
                super(name);
                // TODO Auto-generated constructor stub
            }

            @Override
            public void eat() {
                // TODO Auto-generated method stub
                System.out.println(name +"吃飯");
            }
            
            @Override
            public void sleep() {
                // TODO Auto-generated method stub
                System.out.println(name +"睡覺");
            }
            
            
            
        }
        /// 創(chuàng)建對(duì)象調(diào)用run和sleep方法
        Student student = new Student("楊孝遠(yuǎn)");
        student.eat();
        student.sleep();
        */
        
        /*
         * 第二種方式: 匿名內(nèi)部類
         */
        Person person = new Person("楊孝遠(yuǎn)") {
            
            @Override
            public void sleep() {
                // TODO Auto-generated method stub
                System.out.println(name +"睡覺覺");
            }
            
            @Override
            public void eat() {
                // TODO Auto-generated method stub
                System.out.println(name +"池吃吃吃");
            }
        };
        
        person.sleep();
        person.eat();
    }
}

/// 這樣調(diào)用
public static void main(String[] args) {
                UserAccount userAccount = new UserAccount();
                userAccount.print();
}

匿名內(nèi)部類一般是用于實(shí)參析蝴, 比如以下代碼

public static void main(String[] args) {
            test(new Dao() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                System.out.println("跑跑跑跑跑");
            }
        });
}

public static void test(Dao dao) {
              dao.run();
}

實(shí)現(xiàn)關(guān)系下匿名內(nèi)部類

/// 實(shí)現(xiàn)關(guān)系下的匿名函數(shù)
// 警告: the type is already defined 原因:接口名與其他接口名存在沖突相同害捕,修改下接口名即可
interface Dao {
    
    public abstract void run();
}

public class User {

    public void print() {
        
        /// 匿名函數(shù)
        new Dao() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                System.out.println("跑啊跑");
            }
        }.run();;
    }
}

疑問: 什么時(shí)候使用內(nèi)部類呢?
當(dāng)我們分析事物時(shí)闷畸,發(fā)現(xiàn)事物的內(nèi)部還有具體的事物尝盼,這時(shí)則應(yīng)該定義內(nèi)部類了。
比如人體是一個(gè)類佑菩,人體有心臟盾沫,心臟的功能在直接訪問人體的其他內(nèi)容。這時(shí)就將心臟定義在人體類中殿漠,作為內(nèi)部類存在赴精。
內(nèi)部類的優(yōu)勢(shì):成員內(nèi)部類作為外部類的成員,那么可以訪問外部類的任意成員绞幌。

  • java 異常處理 Throwable Error 和Exception

在Java中蕾哟,根據(jù)錯(cuò)誤性質(zhì)將運(yùn)行錯(cuò)誤分為兩類:錯(cuò)誤和異常。
在Java程序的執(zhí)行過程中莲蜘,如果出現(xiàn)了異常事件谭确,就會(huì)生成一個(gè)異常對(duì)象。生成的異常對(duì)象將傳遞Java運(yùn)行時(shí)系統(tǒng)菇夸,這一異常的產(chǎn)生和提交過程稱為拋棄(throw)異常琼富。
當(dāng)Java運(yùn)行時(shí)系統(tǒng)得到一個(gè)異常對(duì)象時(shí),它將會(huì)沿著方法的調(diào)用棧逐層回溯庄新,尋找處理這一異常的代碼鞠眉。找到能夠處理這類異常的方法后薯鼠,運(yùn)行時(shí)系統(tǒng)把當(dāng)前異常對(duì)象交給這個(gè)方法進(jìn)行處理,這一過程稱為捕獲(catch)異常械蹋。

Java中的所有異常都是由Throwable類的子類生成的對(duì)象出皇,所有的異常類都是Throwable類的子類或子類的子類。Throwable類是Object類的直接子類哗戈,Error類和Exception類是Throwable類的兩個(gè)直接子類郊艘。


java 異常處理 Throwable Error 和Exception.jpeg

Throwable常用的方法:
toString() 返回當(dāng)前異常對(duì)象的完整類名+病態(tài)信息。
getMessage()返回的是創(chuàng)建Throwable傳入的字符串信息唯咬。
printStackTrace() 打印異常的棧信息纱注。
比如以下代碼:

public class LoginTool {

    /// 登錄時(shí)拋出異常
    public void login(String user, String pwd) throws CustomException {
        if (user.length() == 0 || pwd.length() == 0) {
            /// 當(dāng)賬號(hào)或者密碼為空時(shí),就拋出異常
            throw new CustomException("賬號(hào)或密碼為空胆胰,請(qǐng)重新輸入后狞贱,在點(diǎn)擊登錄");
        } else {
            System.out.println("登錄成功哦");
        }
    }
    
}

// 在處理異常時(shí),可以直接直接捕獲異常進(jìn)行處理
public static void main(String[] args)  {  /// 直接將異常拋給jvm虛擬機(jī)處理
        
        LoginTool loginTool = new LoginTool();
        try {
            loginTool.login("sey", "");
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();  /// 打印異常拋出的堆棧信息
            System.out.println(e.getMessage());
        }
}

/// 也可以根據(jù)情況將異常繼續(xù)往上拋出, 在方面聲明后面throws CustomException
public static void main(String[] args)  throws CustomException  {  /// 直接將異常拋給jvm虛擬機(jī)處理
        
        LoginTool loginTool = new LoginTool();
        loginTool.login("sey", "111");
}

java中一般異常和運(yùn)行時(shí)異常的區(qū)別:

Java提供了兩類主要的異常:runtime exception和checked exception蜀涨。checked
異常也就是我們經(jīng)常遇到的IO異常瞎嬉,以及SQL異常都是這種異常。對(duì)于這種異常厚柳,
JAVA編譯器強(qiáng)制要求我們必需對(duì)出現(xiàn)的這些異常進(jìn)行catch氧枣。所以,面對(duì)這種異常
不管我們是否愿意别垮,只能自己去寫一大堆catch塊去處理可能的異常便监。
但是另外一種異常:runtime exception,也稱運(yùn)行時(shí)異常碳想,我們可以不處理
茬贵。當(dāng)出現(xiàn)這樣的異常時(shí),總是由虛擬機(jī)接管移袍。比如:我們從來沒有人去處理過
NullPointerException異常解藻,它就是運(yùn)行時(shí)異常,并且這種異常還是最常見的異
常之一葡盗。
出現(xiàn)運(yùn)行時(shí)異常后螟左,系統(tǒng)會(huì)把異常一直往上層拋,一直遇到處理代碼觅够。如果
沒有處理塊胶背,到最上層,如果是多線程就由Thread.run()拋出喘先,如果是單線程就
被main()拋出钳吟。拋出之后,如果是線程窘拯,這個(gè)線程也就退出了红且。如果是主程序拋
出的異常坝茎,那么這整個(gè)程序也就退出了。運(yùn)行時(shí)異常是Exception的子類暇番,也有一
般異常的特點(diǎn)嗤放,是可以被Catch塊處理的。只不過往往我們不對(duì)他處理罷了壁酬。也就
是說次酌,你如果不對(duì)運(yùn)行時(shí)異常進(jìn)行處理,那么出現(xiàn)運(yùn)行時(shí)異常之后舆乔,要么是線程
中止岳服,要么是主程序終止。
如果不想終止希俩,則必須撲捉所有的運(yùn)行時(shí)異常派阱,決不讓這個(gè)處理線程退出。
隊(duì)列里面出現(xiàn)異常數(shù)據(jù)了斜纪,正常的處理應(yīng)該是把異常數(shù)據(jù)舍棄,然后記錄日志文兑。
不應(yīng)該由于異常數(shù)據(jù)而影響下面對(duì)正常數(shù)據(jù)的處理盒刚。在這個(gè)場(chǎng)景這樣處理可能是
一個(gè)比較好的應(yīng)用,但并不代表在所有的場(chǎng)景你都應(yīng)該如此绿贞。如果在其它場(chǎng)景因块,
遇到了一些錯(cuò)誤,如果退出程序比較好籍铁,這時(shí)你就可以不太理會(huì)運(yùn)行時(shí)異常涡上,或
者是通過對(duì)異常的處理顯式的控制程序退出。

  • finally關(guān)鍵字

finally 塊拒名;

finally塊的 使用前提是必須要存在try塊才能使用吩愧。

finally塊的代碼在任何情況下都會(huì)執(zhí)行的,除了jvm退出的情況增显。

finally非常適合做資源釋放的工作雁佳,這樣子可以保證資源文件在任何情況下都 會(huì)被釋放。

try塊的三種組合方式:

第一種: 比較適用于有異常要處理同云,但是沒有資源要釋放的糖权。

         try{

            可能發(fā)生異常的代碼
    
            }catch(捕獲的異常類型 變量名){
                處理異常的代碼
            }

第二種:比較適用于既有異常要處理又要釋放資源的代碼。

        try{

            可能發(fā)生異常的代碼
    
            }catch(捕獲的異常類型 變量名){
                處理異常的代碼
            }finally{ 
                釋放資源的代碼;
            }

第三種: 比較適用于內(nèi)部拋出的是運(yùn)行時(shí)異常炸站,并且有資源要被釋放星澳。

           try{

            可能發(fā)生異常的代碼
    
            }finally{ 
                釋放資源的代碼;
            }

比如下面代碼

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

import javax.net.ssl.SSLContext;

public class FinallyDemo {
    public void demo() throws IOException {
        
        /// 在任何一個(gè)空閑的端口上創(chuàng)建一個(gè)套接字
        ServerSocket serverSocket = new ServerSocket();
        
        try {
            Socket socket = serverSocket.accept();
        } catch (Exception e) {
            // TODO: handle exception
            System.out.println("socket失敗");
        } finally {
            serverSocket.close();
            System.out.println("關(guān)閉成功");
        }
    }
}

這段代碼創(chuàng)建了一個(gè)套接字,并調(diào)用 accept 方法旱易。在退出該方法之前禁偎,您必須關(guān)閉此套接字腿堤,以避免資源漏洞。為了完成這一任務(wù)
finally 塊確保 close 方法總被執(zhí)行届垫,而不管 try 塊內(nèi)是否發(fā)出異常释液。因此,可以確保在退出該方法之前總會(huì)調(diào)用 close 方法装处。這樣您就可以確信套接字被關(guān)閉并且您沒有泄漏資源误债。在此方法中不需要再有一個(gè) catch 塊。在第一個(gè)示例中提供 catch 塊只是為了關(guān)閉套接字妄迁,現(xiàn)在這是通過 finally 關(guān)閉的寝蹈。如果您確實(shí)提供了一個(gè) catch 塊,則 finally 塊中的代碼在 catch 塊完成以后執(zhí)行登淘。

finally 塊必須與 try 或 try/catch 塊配合使用箫老。此外铜异,不可能退出 try 塊而不執(zhí)行其 finally 塊严肪。如果 finally 塊存在,則它總會(huì)執(zhí)行叠赦。(無論從那點(diǎn)看流妻,這個(gè)陳述都是正確的牲蜀。有一種方法可以退出 try 塊而不執(zhí)行 finally 塊。如果代碼在 try 內(nèi)部執(zhí)行一條 System.exit(0); 語句绅这,則應(yīng)用程序終止而不會(huì)執(zhí)行 finally 執(zhí)行涣达。另一方面,如果您在 try 塊執(zhí)行期間撥掉電源证薇,finally 也不會(huì)執(zhí)行度苔。)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市浑度,隨后出現(xiàn)的幾起案子寇窑,更是在濱河造成了極大的恐慌,老刑警劉巖箩张,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疗认,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡伏钠,警方通過查閱死者的電腦和手機(jī)横漏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來熟掂,“玉大人缎浇,你說我怎么就攤上這事「岸牵” “怎么了素跺?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵二蓝,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我指厌,道長(zhǎng)刊愚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任踩验,我火速辦了婚禮鸥诽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘箕憾。我一直安慰自己牡借,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布袭异。 她就那樣靜靜地躺著钠龙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪御铃。 梳的紋絲不亂的頭發(fā)上碴里,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音上真,去河邊找鬼咬腋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛谷羞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播溜徙,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼湃缎,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了蠢壹?” 一聲冷哼從身側(cè)響起嗓违,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎图贸,沒想到半個(gè)月后蹂季,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疏日,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年偿洁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沟优。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡涕滋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出挠阁,到底是詐尸還是另有隱情宾肺,我是刑警寧澤溯饵,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站锨用,受9級(jí)特大地震影響丰刊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜增拥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一啄巧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧跪者,春花似錦棵帽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至忘衍,卻和暖如春逾苫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背枚钓。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工铅搓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人搀捷。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓星掰,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親嫩舟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子氢烘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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