1. 程式人生 > >Java高階篇整理

Java高階篇整理

面試中常常會問及Java細節相關的問題,而由於往往在平時中不會過多的涉及,所以不能得心應手。而通過閱讀課本和網上資料,會有一定的幫助,但紙上得來終覺淺,絕知此事須躬行。以部落格的形式梳理思路,通過一行行程式碼,深入理解Java細節,從而對於Java高階特性進行全面掌握。

Java三大特性

封裝

  • 封裝三大好處 
    • 良好的封裝減少耦合
    • 類內部的結構可以自由修改(無須修改客戶程式碼)
    • 可以對成員進行精確控制(年齡範圍,性別控制等)
    • 隱藏資訊,實現細節(物件的屬性私有化)

繼承

通過繼承(is-a)實現程式碼的複用。

  • 繼承特點 
    • 子類擁有父類非private的屬性和方法
    • 子類可以擁有自己的屬性和方法
    • 子類可以用自己的方式實現父類的方法(重寫)
  • 構造器 
    • 只能被呼叫,不能被繼承,super()呼叫父類的構造器。
    • 子類會預設呼叫父類的構造器。
    • 如果沒有預設的父類構造器,子類必須顯示呼叫指定父類的構造器,而且必須在子類構造器中的第一行程式碼實現呼叫。
public class Person {
    protected String name;
    protected int age;
    protected String sex;

    Person(String name){
        System.out.println("Person Constrctor-----"
+ name); } } public class Husband extends Person{ private Wife wife; Husband(){ super("chenssy"); System.out.println("Husband Constructor..."); } public static void main(String[] args) { Husband husband = new Husband(); } } Output: Person Constrctor-----chenssy Husband Constructor...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • protected關鍵字 
    • 儘可能隱藏,但是允許子類的成員訪問。
    • 指明就類使用者而言,他是private,但是對於任何繼承與此類的子類而言或者其他任何位於同一個包的類而言,他卻是可以訪問的。
public class Person {
    private String name;
    private int age;
    private String sex;

    protected String getName() {
        return name;
    }

    protected void setName(String name) {
        this.name = name;
    }

    public String toString(){
        return "this name is " + name;
    }

    /** 省略其他setter、getter方法 **/
}

public class Husband extends Person{
    private Wife wife;

    public  String toString(){
        setName("chenssy");    //呼叫父類的setName();
        return  super.toString();    //呼叫父類的toString()方法
    }

    public static void main(String[] args) {
        Husband husband = new Husband();

        System.out.println(husband.toString());
    }
}

Output:
this name is chenssy
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 向上轉型 
    • 專用型別向較通用型別轉換,所以總是安全的。
    • 可能帶來屬性和方法的丟失。
public class Person {
    public void display(){
        System.out.println("Play Person...");
    }

    static void display(Person person){
        person.display();
    }
}

public class Husband extends Person{
    public static void main(String[] args) {
        Husband husband = new Husband();
        Person.display(husband);      //向上轉型
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

多型

指向子類的父類引用由於向上轉型,只能訪問父類中擁有的方法和屬性,會丟失子類中存在,而父類中不存真的方法。若子類重寫了父類的某些方法,在呼叫方法的時候,必定會使用子類中定義的方法。(動態連線,動態呼叫。

public class Wine {
    public void fun1(){
        System.out.println("Wine 的Fun.....");
        fun2();
    }

    public void fun2(){
        System.out.println("Wine 的Fun2...");
    }
}

public class JNC extends Wine{
    /**
     * @desc 子類過載父類方法
     *        父類中不存在該方法,向上轉型後,父類是不能引用該方法的
     * @param a
     * @return void
     */
    public void fun1(String a){
        System.out.println("JNC 的 Fun1...");
        fun2();
    }

    /**
     * 子類重寫父類方法
     * 指向子類的父類引用呼叫fun2時,必定是呼叫該方法
     */
    public void fun2(){
        System.out.println("JNC 的Fun2...");
    }
}

public class Test {
    public static void main(String[] args) {
        Wine a = new JNC();
        a.fun1();
    }
}
-------------------------------------------------
Output:
Wine 的Fun.....
JNC 的Fun2...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 多型的實現 
    • 條件(繼承、重寫、 向上轉型)
    • 實現形式(繼承、介面)當子類重寫父類的方法被呼叫時,只有物件繼承鏈中的最末端的方法才會被呼叫
  • 經典案例分析
public class A {
    public String show(D obj) {
        return ("A and D");
    }

    public String show(A obj) {
        return ("A and A");
    } 

}

public class B extends A{
    public String show(B obj){
        return ("B and B");
    }

    public String show(A obj){
        return ("B and A");
    } 
}

public class C extends B{

}

public class D extends B{

}

public class Test {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new B();
        B b = new B();
        C c = new C();
        D d = new D();

        System.out.println("1--" + a1.show(b));//"A and A"
        System.out.println("2--" + a1.show(c));//"A and A"
        System.out.println("3--" + a1.show(d));//"A and D"
        System.out.println("4--" + a2.show(b));//"B and A"
        System.out.println("5--" + a2.show(c));//"B and A"
        System.out.println("6--" + a2.show(d));//"A and D"
        System.out.println("7--" + b.show(b));//"B and B"
        System.out.println("8--" + b.show(c));//"B and B"
        System.out.println("9--" + b.show(d));//"A and D"      
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

其實在繼承鏈中物件方法的呼叫存在一個優先順序:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。

四捨五入

  • ROUND_UP:遠離零方向舍入。向絕對值最大的方向舍入,只要捨棄位非0即進位。
  • ROUND_DOWN:趨向零方向舍入。向絕對值最小的方向輸入,所有的位都要捨棄,不存在進位情況。
  • ROUND_CEILING:向正無窮方向舍入。向正最大方向靠攏。若是正數,舍入行為類似於ROUND_UP,若為負數,舍入行為類似於ROUND_DOWN。Math.round()方法就是使用的此模式。
  • ROUND_FLOOR:向負無窮方向舍入。向負無窮方向靠攏。若是正數,舍入行為類似於ROUND_DOWN;若為負數,舍入行為類似於ROUND_UP。
  • HALF_UP:最近數字舍入(5進)。這是我們最經典的四捨五入。
  • HALF_DOWN:最近數字舍入(5舍)。在這裡5是要捨棄的。
  • HAIL_EVEN:銀行家舍入法。

使用序列化實現物件的拷貝

clone()方法存在缺陷,並不會將物件的所有屬性的全部拷貝過來,而是選擇性的拷貝。規則如下

  • 基本型別拷貝其值
  • 物件則拷貝地址引用,也就是說此時新物件與原來物件是公用該例項變數。
  • String字串,則拷貝其地址引用。但是在修改時,它會從字串池中重新生成一個新的字串,原有物件保持不變。

使用序列化來實現物件的深拷貝。在記憶體中通過位元組流的拷貝是比較容易實現的。把母物件寫入到一個位元組流中,再從位元組流中將其讀出來,這樣就可以建立一個新的物件了,並且該新物件與母物件之間並不存在引用共享的問題,真正實現物件的深拷貝。

public class CloneUtils {
    @SuppressWarnings("unchecked")
    public static <T extends Serializable> T clone(T obj){
        T cloneObj = null;
        try {
            //寫入位元組流
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ObjectOutputStream obs = new ObjectOutputStream(out);
            obs.writeObject(obj);
            obs.close();

            //分配記憶體,寫入原始物件,生成新物件
            ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(ios);
            //返回生成的新物件
            cloneObj = (T) ois.readObject();
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cloneObj;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

抽象類和介面

抽象類

  • 抽象類不能被例項化
  • 抽象方法必須由子類重寫
  • 子類中的抽象方法不能與父類的抽象方法同名。
  • abstract不能與final並列修飾同一個類
  • abstract 不能與private、static、final或native並列修飾同一個方法。

介面

介面是用來建立類與類之間的協議,它所提供的只是一種形式,而沒有具體的實現

  • Interface所有方法自動生命為public,當然你可以顯示的宣告為protected、private,編譯會出錯!
  • 介面中德成員變數會自動變為為public static final。可以通過類命名直接訪問:ImplementClass.name。
  • 實現介面的非抽象類必須要實現該介面的所有方法。抽象類可以不用實現。

抽象類和介面的區別

  • 語法層次
  • 設計層次 
    • 抽象層次不同。抽象類是對類進行抽象,介面是對行為的抽象。
    • 跨域不同。抽象類所跨域的是具有相似特點的類,而介面卻可以跨域不同的類。我們知道抽象類是從子類中發現公共部分,然後泛化成抽象類,子類繼承該父類即可,但是介面不同。實現它的子類可以不存在任何關係,共同之處。is-a和like-a
    • 設計層次不同。抽象類是自底向上抽象而來的,介面是自頂向下設計出來的。

內部類

為何需要內部類

每個內部類都能獨立繼承一個(介面)實現,無論外圍類是否已經繼承了某個介面的實現,對於內部類沒有影響。 
介面只是解決了部分問題,而內部類使得多重繼承的解決方案變得更加完整。

  • 內部類可以用於多個例項,每個例項都有自己的狀態資訊,並且與其他外圍物件的資訊相互獨立。
  • 在單個外圍類中,可以讓多個內部類以不同的方式實現同一介面,或者繼承同一個類。
  • 建立內部類物件的時刻並不依賴於外圍類物件的建立。
  • 內部類並沒有令人迷惑的“is-a”關係,他就是一個獨立的實體。

成員內部類

  • 成員內部類中不能存在任何static的變數和方法
  • 成員內部類是依附於外圍類的,所以只有先建立了外圍類才能夠建立內部類。
public class OuterClass {
    private String str;

    public void outerDisplay(){
        System.out.println(
            
           

相關推薦

Java高階整理

面試中常常會問及Java細節相關的問題,而由於往往在平時中不會過多的涉及,所以不能得心應手。而通過閱讀課本和網上資料,會有一定的幫助,但紙上得來終覺淺,絕知此事須躬行。以部落格的形式梳理思路,通過一行行程式碼,深入理解Java細節,從而對於Java高階特性進行全面掌握。 Java三大特性 封裝

Java高階(四)——反射

  之前寫到了設計模式的代理模式,因為下一篇動態代理等內容需要用到反射的知識,所以在之前Java篇的基礎上再寫一篇有關反射的內容,還是以實際的程式為主,瞭解反射是做什麼的、應該怎麼用。 一、什麼是反射   反射就是把Java類中的各個成分對映成一個個的Java物件。即在執行狀態中,對於任意一個類,都能夠知道這

Java高階-1-Java基礎知識快速過一遍

      在學習Java高階部分知識之前,我們來簡單梳理一下Java基礎語法部分的知識,不會太全,但是基本的,常用到的一一複習一下。 1.Java編碼規範        在這裡,還是要強調Java編碼標準或者規範。以前,我寫程式碼或者指令碼不多,也不知道這個重要性。突然

Java高階-2-裝箱和拆箱的基本概念

       前面一篇的結尾,我們畫了一張圖,對Java的資料型別進行了分類。其中,有8種基本資料型別,還有引用型別。我們先來看看下面這段程式。 package demo3; /** * create by Anthony on 2017/10/28 */ publ

Java高階 -- List選擇及優化

在java程式設計中,我們常常使用到java自帶的集合類List  以下為幾點簡單的優化建議: 1.Vector還是ArrayList    Vector有其特有有點,其每個方法都為同步方法【synchronized】,所以是執行緒安全的,在多執行緒環境下,若多個程序同時訪問受保護資源,用Vector就顯得

Java高階-5-Arrays類

       前面介紹了字串的操作的String類,這篇,我們學習陣列類,Java中提供了一個數組常見操作方法的類Arrays.java。其實前面也說過,String其實原始碼中就是用一個char[]

Java高階-0-為什麼要掌握Java高階知識

       好長時間了,就想要花時間系統去學習下Java的高階篇知識,這部分是我個人目前比較欠缺的,而且是急缺的知識。我認為的Java高階篇內容是這樣劃分的:對Java這個程式語言有基本瞭解,基本掌

【魯班學院】面試總結:Java高階(上):集合的型別以及重新認識HashMap

1.你用過哪些集合類?     大公司最喜歡問的Java集合類面試題     4

面試整理-Java綜合高階

Java面試總結 1.你用過哪些集合類? 大公司最喜歡問的Java集合類面試題 40個Java集合面試問題和答案 java.util.Collections 是一個包裝類。它包含有各種有關集合操作的靜態多型方法。 java.util.Collecti

最近整理的一些常見的面試題,面試大全,黑馬程式設計師面試寶典題庫---JavaWEE高階

一、 Filter 和 Listener(評論留言獲取原件) 可參見:https://www.cnblogs.com/libingbin/p/5985647.html 二、 AJAX 1. 談談你對 ajax 的認識? Ajax 是一種建立互動式網頁應用的的網頁開發技術;

Java內部類整理筆記——一讀懂內部類

Java內部類整理筆記一 . 內部類的總結      一般來說,內部類繼承自某個類或實現某個介面,內部類的程式碼操作建立它的外圍類的物件。所以,可以認為內部類提供了某種進入其外圍類的視窗。每個內部類都能獨立地繼承自一個介面的實現,所以無論外圍類是否已經繼承了某個介面的實現,對

第五套.java高階架構師(2017整理版)無加密

百度雲盤連結: https://pan.baidu.com/s/1q_sD3za2PuSnQBoC4NW51w 連結失效,加微信:sun_sha_tan   01-java高階架構師設計-基礎深入等多個檔案 02-java高階架構師設計-JavaEE拓展 03-ja

Java 併發程式設計之美:併發程式設計高階之一-chat

借用 Java 併發程式設計實踐中的話:編寫正確的程式並不容易,而編寫正常的併發程式就更難了。相比於順序執行的情況,多執行緒的執行緒安全問題是微妙而且出乎意料的,因為在沒有進行適當同步的情況下多執行緒中各個操作的順序是不可預期的。 併發程式設計相比 Java

Java 併發程式設計之美:併發程式設計高階之一

借用 Java 併發程式設計實踐中的話:編寫正確的程式並不容易,而編寫正常的併發程式就更難了。相比於順序執行的情況,多執行緒的執行緒安全問題是微妙而且出乎意料的,因為在沒有進行適當同步的情況下多執行緒中各個操作的順序是不可預期的。併發程式設計相比 Java 中其他知識點學習起

【轉】【NIO】Java面試高階Java NIO:淺析I/O模型面試題15期

在進入Java NIO程式設計之前,我們今天先來討論一些比較基礎的知識:I/O模型。本文先從同步和非同步的概念 說起,然後接著闡述了阻塞和非阻塞的區別,接著介紹了阻塞IO和非阻塞IO的區別,然後介紹了同步IO和非同步IO的區別,接下來介紹了5種IO模型,最後介紹了兩種和高

【備忘】Java菜鳥到大牛學習路線之高階

01-java高階架構師設計-基礎深入        J2SE深入講解        Java多執行緒與併發庫高階應用視訊教程下載        java反射機制        java設計模式視訊        資料結構視訊教程        Eclipse視訊教程.zip        MyEclipse

Java-面向物件(高階)--抽象類與介面的應用

抽象類與介面的應用 一. 抽象類的實際應用——模板設計 通過物件的多型性可以為抽象類例項化,那麼抽象類該如何使用那?假設人分為學生和工人,學生和工人都可以說話,但是說的內容不相同,那麼說話的功能是一樣的,而說的內容由學生和工人自己來決定,此時可以利用抽象類

Java面試題整理---Redis

線程 red redis redis主從 edi 為什麽 數據結構類型 nbsp 如何實現 1.redis支持五種數據結構類型? 2.redis內部結構? 3.redis持久化機制? 4.redis集群方案與實現? 5.redis為什麽是單線

【轉】java提高(二)-----理解java的三大特性之繼承

logs 了解 向上轉型 one 調用 adding nbsp eight 基礎 【轉】java提高篇(二)-----理解java的三大特性之繼承 原文地址:http://www.cnblogs.com/chenssy/p/3354884.html 在《Thi

Java面試題目整理

size 虛擬 ble 可復用 ringbuf 進步 組合 java 自己的 一、引言:本文主要整理遇到的面試題目,以及提供自己的見解,將會持續更新,如有問題,可評論交流,一起進步。 二、問題及我的見解: 1. n個結點可以組合成多少棵不同的二叉樹? 答:2^n-n棵 2.