02.Java面向對象問題

目錄介紹

  • 2.0.0.1 重載和重寫的區別?重載和重寫綁定機制有何區別?父類的靜態方法可否被子類重寫?
  • 2.0.0.2 封裝、繼承、多態分別是什麼?
  • 2.0.0.3 接口和抽象類的區別是什麼?接口的意義是什麼?抽象類的意義是什麼?如何選擇抽象類和接口?
  • 2.0.0.4 什麼是內部類,有哪些?有什麼做用?靜態內部類和非靜態內部類的區別?
  • 2.0.0.5 爲何內部類調用的外部變量必須是final修飾的?
  • 2.0.0.6 Java實現多態有哪些必要條件?具體怎麼實現?多態的實現原理?多態的做用?
  • 2.0.0.7 什麼是多態?多態的實現方式有哪些?多態有哪些弊端?
  • 2.0.0.9 靜態變量和成員變量的區別?代碼塊有哪些?構造代碼塊和構造方法哪個先執行?
  • 2.0.1.0 抽象類具備什麼特色?抽象類和普通類有何區別?抽象類能夠new嗎?會出現什麼問題?

好消息

  • 博客筆記大彙總【15年10月到至今】,包括Java基礎及深刻知識點,Android技術博客,Python學習筆記等等,還包括平時開發中遇到的bug彙總,固然也在工做之餘收集了大量的面試題,長期更新維護而且修正,持續完善……開源的文件是markdown格式的!同時也開源了生活博客,從12年起,積累共計500篇[近100萬字],將會陸續發表到網上,轉載請註明出處,謝謝!
  • 連接地址:https://github.com/yangchong211/YCBlogs
  • 若是以爲好,能夠star一下,謝謝!固然也歡迎提出建議,萬事起於忽微,量變引發質變!全部博客將陸續開源到GitHub!

2.0.0.1 重載和重寫的區別?重載和重寫綁定機制有何區別?父類的靜態方法可否被子類重寫?

  • 重載
    • 發生在同一個類中,方法名必須相同,參數類型不一樣、個數不一樣、順序不一樣,方法返回值和訪問修飾符能夠不一樣,發生在編譯時。   
  • 重寫
    • 重寫表示子類重寫父類的方法
    • 發生在父子類中,方法名、參數列表必須相同,返回值範圍小於等於父類,拋出的異常範圍小於等於父類,訪問修飾符範圍大於等於父類;若是父類方法訪問修飾符爲 private 則子類就不能重寫該方法。
  • 重載和重寫綁定機制有何區別?
    • 重載:類內多態,靜態綁定機制(編譯時已經知道具體執行哪一個方法),方法同名,參數不一樣
    • 重寫:類間多態,動態綁定機制(運行時肯定),實例方法,兩小兩同一大(方法簽名相同,子類的方法所拋出的異常、返回值的範圍不大於父類的對應方法,子類的方法可見性不小於父類的對應方法)方法簽名相同,子類的方法所拋出的異常、返回值的範圍不大於父類的對應方法,子類的方法可見性不小於父類的對應方法
  • 父類的靜態方法可否被子類重寫
    • 父類的靜態方法是不能被子類重寫的,其實重寫只能適用於實例方法,不能用於靜態方法,對於上面這種靜態方法而言,咱們應該稱之爲隱藏。
    • 技術博客大總結
    • Java靜態方法形式上能夠重寫,但從本質上來講不是Java的重寫。由於靜態方法只與類相關,不與具體實現相關。聲明的是什麼類,則引用相應類的靜態方法(原本靜態無需聲明,能夠直接引用)。而且static方法不是後期綁定的,它在編譯期就綁定了。換句話說,這個方法不會進行多態的判斷,只與聲明的類有關。

2.0.0.2 面向對象編程的四大特性及其含義?封裝、繼承、多態分別是什麼?

  • 封裝
    • 將某事物的屬性和行爲包裝到對象中,構成一個不可分割的獨立實體。
    • 封裝把一個對象的屬性私有化,同時提供一些能夠被外界訪問的屬性的方法,若是屬性不想被外界訪問,咱們大可沒必要提供方法給外界訪問。可是若是一個類沒有提供給外界訪問的方法,那麼這個類也沒有什麼意義了。
  • 繼承
    • 繼承是使用已存在的類的定義做爲基礎創建新類的技術,新類的定義能夠增長新的數據或新的功能,也能夠用父類的功能,但不能選擇性地繼承父類。經過使用繼承咱們可以很是方便地複用之前的代碼。
    • 注意
      • 子類擁有父類非 private 的屬性和方法。
      • 子類能夠擁有本身屬性和方法,即子類能夠對父類進行擴展。
      • 子類能夠用本身的方式實現父類的方法。
  • 多態
    • 所謂多態就是指程序中定義的引用變量所指向的具體類型和經過該引用變量發出的方法調用在編程時並不肯定,而是在程序運行期間才肯定,即一個引用變量倒底會指向哪一個類的實例對象,該引用變量發出的方法調用究竟是哪一個類中實現的方法,必須在由程序運行期間才能決定。
    • 在Java中有兩種形式能夠實現多態:繼承(多個子類對同一方法的重寫)和接口(實現接口並覆蓋接口中同一方法)。
  • 抽象
    • 對現實世界的事物進行歸納,抽象爲在計算機虛擬世界中有意義的實體

2.0.0.3 接口和抽象類的區別是什麼?接口的意義是什麼?抽象類的意義是什麼?如何選擇抽象類和接口?

  • 接口和抽象類的區別是什麼
    • 接口的方法默認是 public,全部方法在接口中不能有實現(Java 8 開始接口方法能夠有默認實現),抽象類能夠有非抽象的方法
    • 接口中的實例變量默認是 final 類型的,而抽象類中則不必定
    • 一個類能夠實現多個接口,但最多隻能實現一個抽象類
    • 一個類實現接口的話要實現接口的全部方法,而抽象類不必定
    • 接口不能用 new 實例化,但能夠聲明,可是必須引用一個實現該接口的對象 從設計層面來講,抽象是對類的抽象,是一種模板設計,接口是行爲的抽象,是一種行爲的規範。
  • 接口的做用是什麼
    • 技術博客大總結
    • 一、重要性:在Java語言中, abstract class 和interface 是支持抽象類定義的兩種機制。正是因爲這兩種機制的存在,才賦予了Java強大的 面向對象能力。
    • 二、簡單、規範性:若是一個項目比較龐大,那麼就須要一個能理清全部業務的架構師來定義一些主要的接口,這些接口不只告訴開發人員你須要實現那些業務,並且也將命名規範限制住了(防止一些開發人員隨便命名致使別的程序員沒法看明白)。
    • 三、維護、拓展性:好比你要作一個畫板程序,其中裏面有一個面板類,主要負責繪畫功能,而後你就這樣定義了這個類。但是在不久未來,你忽然發現這個類知足不了你了,而後你又要從新設計這個類,更糟糕是你可能要放棄這個類,那麼其餘地方可能有引用他,這樣修改起來很麻煩。
    • 若是你一開始定義一個接口,把繪製功能放在接口裏,而後定義類時實現這個接口,而後你只要用這個接口去引用實現它的類就好了,之後要換的話只不過是引用另外一個類而已,這樣就達到維護、拓展的方便性。
    • 四、安全、嚴密性:接口是實現軟件鬆耦合的重要手段,它描敘了系統對外的全部服務,而不涉及任何具體的實現細節。這樣就比較安全、嚴密一些(通常軟件服務商考慮的比較多)。
  • 抽象類的意義是什麼
    • 1.由於抽象類不能實例化對象,因此必需要有子類來實現它以後才能使用。這樣就能夠把一些具備相同屬性和方法的組件進行抽象,這樣更有利於代碼和程序的維護。
    • 2.當又有一個具備類似的組件產生時,只須要實現該抽象類就能夠得到該抽象類的那些屬性和方法。
  • 如何選擇抽象類和接口?
    • 使用接口:
      • 須要讓不相關的類都實現一個方法,例如不相關的類均可以實現 Compareable 接口中的 compareTo() 方法;
      • 須要使用多重繼承。
    • 使用抽象類:
      • 須要在幾個相關的類中共享代碼。
      • 須要能控制繼承來的成員的訪問權限,而不是都爲 public。
      • 須要繼承非靜態和很是量字段。

2.0.0.4 什麼是內部類,有哪些?有什麼做用?靜態內部類和非靜態內部類的區別?

  • 什麼是內部類
    • 內部類就是定義在另一個類裏面的類。它隱藏在外部類中,封裝性更強,不容許除外部類外的其餘類訪問它;但它可直接訪問外部類的成員。
  • 內部類有哪些
    • 成員內部類:成員內部類是外圍類的一個成員,是依附於外圍類的,因此,只有先建立了外圍類對象纔可以建立內部類對象。也正是因爲這個緣由,成員內部類也不能含有 static 的變量和方法;
    • 靜態內部類:靜態內部類,就是修飾爲static的內部類,該內部類對象不依賴於外部類對象,就是說咱們能夠直接建立內部類對象,但其只能夠直接訪問外部類的全部靜態成員和靜態方法;
    • 局部內部類:局部內部類和成員內部類同樣被編譯,只是它的做用域發生了改變,它只能在該方法和屬性中被使用,出了該方法和屬性就會失效;
    • 匿名內部類:定義匿名內部類的前提是,內部類必需要繼承一個類或者實現接口,格式爲 new 父類或者接口(){定義子類的內容(如函數等)}。也就是說,匿名內部類最終提供給咱們的是一個 匿名子類的對象。
  • 靜態內部類和非靜態內部類的區別有:
    • 靜態內部類是指被聲明爲static的內部類,可不依賴外部類實例化;而非靜態內部類須要經過生成外部類來間接生成。
    • 靜態內部類只能訪問外部類的靜態成員變量和靜態方法,而非靜態內部類因爲持有對外部類的引用,能夠訪問外部類的所用成員

2.0.0.5 爲何內部類調用的外部變量必須是final修飾的?

  • 爲何內部類調用的外部變量必須是final修飾的?
    • 簡單解答:一方面,因爲方法中的局部變量的生命週期很短,一旦方法結束變量就要被銷燬,爲了保證在內部類中能找到外部局部變量,經過final關鍵字可獲得一個外部變量的引用;另外一方面,經過final關鍵字也不會在內部類去作修改該變量的值,保護了數據的一致性。
    • 詳細一點能夠這樣說:由於生命週期的緣由。方法中的局部變量,方法結束後這個變量就要釋放掉,final保證這個變量始終指向一個對象。首先,內部類和外部類實際上是處於同一個級別,內部類不會由於定義在方法中就會隨着方法的執行完畢而跟隨者被銷燬。問題就來了,若是外部類的方法中的變量不定義final,那麼當外部類方法執行完畢的時候,這個局部變量確定也就被GC了,然而內部類的某個方法尚未執行完,這個時候他所引用的外部變量已經找不到了。若是定義爲final,java會將這個變量複製一份做爲成員變量內置於內部類中,這樣的話,因爲final所修飾的值始終沒法改變,因此這個變量所指向的內存區域就不會變。爲了解決:局部變量的生命週期與局部內部類的對象的生命週期的不一致性問題

2.0.0.7 什麼是多態?多態實現條件?多態的實現方式有哪些?

  • 什麼是多態?
    • 多態是指程序中定義的引用變量所指向的具體類型和經過該引用變量發出的方法調用在編程時並不肯定,而是在程序運行期間才肯定,即一個引用變量倒底會指向哪一個類的實例對象,該引用變量發出的方法調用究竟是哪一個類中實現的方法,必須在由程序運行期間才能決定。由於在程序運行時才肯定具體的類,這樣,不用修改源程序代碼,就可讓引用變量綁定到各類不一樣的類實現上,從而致使該引用調用的具體方法隨之改變,即不修改程序代碼就能夠改變程序運行時所綁定的具體代碼,讓程序能夠選擇多個運行狀態,這就是多態性。
  • 多態實現條件?
    • Java實現多態有三個必要條件:繼承、重寫、向上轉型。
    • 繼承:在多態中必須存在有繼承關係的子類和父類。
    • 重寫:子類對父類中某些方法進行從新定義,在調用這些方法時就會調用子類的方法。
    • 向上轉型:在多態中須要將子類的引用賦給父類對象,只有這樣該引用纔可以具有技能調用父類的方法和子類的方法。
  • 多態的實現方式有哪些?php

    • 多態做用:多態性就是相同的消息使得不一樣的類作出不一樣的響應。
    • 第一種實現方式:基於繼承實現的多態java

      • 基於繼承的實現機制主要表如今父類和繼承該父類的一個或多個子類對某些方法的重寫,多個子類對同一方法的重寫能夠表現出不一樣的行爲。多態的表現就是不一樣的對象能夠執行相同的行爲,可是他們都須要經過本身的實現方式來執行,這就要得益於向上轉型了。git

        public class MainJava {
        public static void main(String[] args) {
            //定義父類數組
            Wine[] wines = new Wine[2];
            //定義兩個子類
            Test1 test1 = new Test1();
            Test2 test2 = new Test2();
            Wine win e = new Wine();
            //父類引用子類對象
            wines[0] = test1;
            wines[1] = test2;
            for(int i = 0 ; i < 2 ; i++){
                System.out.println(wines[i].toString() + "--" + wines[i].drink());
            }
            System.out.println("-------------------------------");
            System.out.println(test1.toString() + "--" + test1.drink());
            System.out.println(test2.toString() + "--" + test2.drink());
        }
        public static class Wine {
            private String name;
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
            public String drink(){
                return "喝的是 " + getName();
            }
            public String toString(){
                return null;
            }
        }
        
        public static class Test1 extends Wine{
            public Test1(){
                setName("Test1");
            }
            public String drink(){
                return "喝的是 " + getName();
            }
            public String toString(){
                return "Wine : " + getName();
            }
        }
        
        public static class Test2 extends Wine{
            public Test2(){
                setName("Test2");
            }
            public String drink(){
                return "喝的是 " + getName();
            }
            public String toString(){
                return "Wine : " + getName();
            }
        }
        }
    • 第二種實現多態的方式:基於接口實現的多態
      • 繼承是經過重寫父類的同一方法的幾個不一樣子類來體現的,那麼就可就是經過實現接口並覆蓋接口中同一方法的幾不一樣的類體現的。
      • 在接口的多態中,指向接口的引用必須是指定這實現了該接口的一個類的實例程序,在運行時,根據對象引用的實際類型來執行對應的方法。
      • 繼承都是單繼承,只能爲一組相關的類提供一致的服務接口。可是接口能夠是多繼承多實現,它可以利用一組相關或者不相關的接口進行組合與擴充,可以對外提供一致的服務接口。因此它相對於繼承來講有更好的靈活性。
  • 多態有哪些弊端?

2.0.0.9 靜態變量和成員變量的區別?代碼塊有哪些?構造代碼塊和構造方法哪個先執行?

  • 靜態變量和成員變量的區別
    • A:所屬不一樣
      • 靜態變量屬於類,因此也稱爲類變量
      • 成員變量屬於對象,因此也稱爲實例變量(對象變量)
    • B:內存中位置不一樣
      • 靜態變量存儲於方法區的靜態區
      • 成員變量存儲於堆內存
    • C:內存出現時間不一樣
      • 靜態變量隨着類的加載而加載,隨着類的消失而消失
      • 成員變量隨着對象的建立而存在,隨着對象的消失而消失
    • D:調用不一樣
      • 靜態變量能夠經過類名調用,也能夠經過對象調用
      • 成員變量只能經過對象名調用
  • 代碼塊有哪些
    • A:代碼塊概述
      • 在Java中,使用{}括起來的代碼被稱爲代碼塊。
    • B:代碼塊分類
      • 根據其位置和聲明的不一樣,能夠分爲局部代碼塊,構造代碼塊,靜態代碼塊,同步代碼塊。
    • C:常見代碼塊的應用
      • a:局部代碼塊
        • 在方法中出現;限定變量生命週期,及早釋放,提升內存利用率
      • b:構造代碼塊
        • 在類中方法外出現;多個構造方法方法中相同的代碼存放到一塊兒,每次調用構造都執行,而且在構造方法前執行
      • c:靜態代碼塊
        • 在類中方法外出現,加了static修飾
        • 在類中方法外出現,並加上static修飾;用於給類進行初始化,在加載的時候就執行,而且只執行一次。
  • 構造代碼塊和構造方法哪個先執行?

2.0.1.0 抽象類具備什麼特色?抽象類和普通類有何區別?抽象類能夠new嗎?會出現什麼問題?

  • 抽象類具備什麼特色
    • 抽象類和抽象方法都使用 abstract 關鍵字進行聲明。抽象類通常會包含抽象方法,抽象方法必定位於抽象類中。
  • 抽象類和普通類有何區別程序員

    • 抽象類和普通類最大的區別是,抽象類不能被實例化,須要繼承抽象類才能實例化其子類。github

      public abstract class AbstractClassExample {
      protected int x;
      private int y;
      public abstract void func1();
      
      public void func2() {
          System.out.println("func2");
      }
      }

    public class AbstractExtendClassExample extends AbstractClassExample {br/>@Override
    public void func1() {
    System.out.println("func1");
    }
    }面試

     
  • 抽象類能夠new嗎?會出現什麼問題?
    • 注意抽象類是不能被實例化的,也就是不能new出來的!
    • 若是執意須要new,則會提示
    • image

其餘介紹

01.關於博客彙總連接

02.關於個人博客

相關文章
相關標籤/搜索