1. 程式人生 > 實用技巧 >Java學習_面向物件程式設計

Java學習_面向物件程式設計

  • 抽象類
    • 一個class定義了方法,但沒有具體執行程式碼,這個方法就是抽象方法,抽象方法用abstract修飾。因為抽象類本身被設計成只能用於被繼承,因此,抽象類可以強迫子類實現其定義的抽象方法,否則編譯會報錯。因此,抽象方法實際上相當於定義了“規範”。
    • 抽象方法的類都是抽象類,抽象類不全是抽象方法。
    • 面向抽象程式設計的本質就是:

      • 上層程式碼只定義規範(例如:abstract class Person);

      • 不需要子類就可以實現業務邏輯(正常編譯);

      • 具體的業務邏輯由不同的子類實現,呼叫者並不關心。

  • 介面
    • 如果一個抽象類沒有欄位,且所有方法全部都是抽象方法,就可以把該抽象類改寫為介面:interface
    • 介面中屬性預設public static final 修飾 方法預設public abstract修飾
    • 一個具體的class去實現一個interface時,需要使用implements關鍵字。
    • 一個類可以實現多個interface。
    • 一個interface可以繼承自另一個interfaceinterface繼承自interface使用extends,它相當於擴充套件了介面的方法。
      1 interface Hello {
      2     void hello();
      3 }
      4 
      5 interface Person extends Hello {
      6     void run();
      7     String getName();
      
      8 }
      View Code
    • 在Java虛擬機器執行的時候,JVM只看完整類名,因此,只要包名不同,類就不同。
    • 包沒有父子關係。java.util和java.util.zip是不同的包,兩者沒有任何繼承關係。
    • 位於同一個包的類,可以訪問包作用域的欄位和方法。不用publicprotectedprivate修飾的欄位和方法就是包作用域
    • import

      • 直接寫出完整類名 mr.jun.Arrays arrays = new mr.jun.Arrays();
      • import語句,匯入Arrays,然後寫簡單類名。
         1 // Person.java
         2 package ming;
        
        3 4 // 匯入完整類名: 5 import mr.jun.Arrays; 6 7 public class Person { 8 public void run() { 9 Arrays arrays = new Arrays(); 10 } 11 }
      • import static 包名,它可以匯入一個類的靜態欄位和靜態方法。

         1 package main;
         2 
         3 // 匯入System類的所有靜態欄位和靜態方法:
         4 import static java.lang.System.*;
         5 
         6 public class Main {
         7     public static void main(String[] args) {
         8         // 相當於呼叫System.out.println(…)
         9         out.println("Hello, world!");
        10     }
        11 }
      • 如果是簡單類名,按下面的順序依次查詢:

        • 查詢當前package是否存在這個class

        • 查詢import的包是否包含這個class

        • 查詢java.lang包是否包含這個class

      •  因此,編寫class的時候,編譯器會自動幫我們做兩個import動作:
        • 預設自動import當前package的其他class

        • 預設自動import java.lang.*

        • 自動匯入的是java.lang包,但類似java.lang.reflect這些包仍需要手動匯入。
        • 如果有兩個class名稱相同,例如,mr.jun.Arraysjava.util.Arrays,那麼只能import其中一個,另一個必須寫完整類名。
  • 內部類
    • 普通類有個最大的不同,就是Inner Class的例項不能單獨存在,必須依附於一個Outer Class的例項。
       1 public class Main {
       2     public static void main(String[] args) {
       3         Outer outer = new Outer("Nested"); // 例項化一個Outer
       4         Outer.Inner inner = outer.new Inner(); // 例項化一個Inner
       5         inner.hello();
       6     }
       7 }
       8 
       9 class Outer {
      10     private String name;
      11 
      12     Outer(String name) {
      13         this.name = name;
      14     }
      15 
      16     class Inner {
      17         void hello() {
      18             System.out.println("Hello, " + Outer.this.name);
      19         }
      20     }
      21 }
    • Inner Class和普通Class相比,除了能引用Outer例項外,還有一個額外的“特權”,就是可以修改Outer Class的private欄位,因為Inner Class的作用域在Outer Class內部,所以能訪問Outer Class的private欄位和方法。(Inner Class除了有一個this指向它自己,還隱含地持有一個Outer Class例項,可以用Outer.this訪問這個例項。)
    • 匿名內部類
      •   不需要在Outer Class中明確地定義這個Class,而是在方法內部,通過匿名類(Anonymous Class)來定義。
         1 public class Main {
         2     public static void main(String[] args) {
         3         Outer outer = new Outer("Nested");
         4         outer.asyncHello();
         5     }
         6 }
         7 
         8 class Outer {
         9     private String name;
        10 
        11     Outer(String name) {
        12         this.name = name;
        13     }
        14 
        15     void asyncHello() {
        16         Runnable r = new Runnable() {        //重寫父類或者介面的方法
        17             @Override
        18             public void run() {
        19                 System.out.println("Hello, " + Outer.this.name);
        20             }
        21         };
        22         new Thread(r).start();
        23     }
        24 }
    •   靜態內部類
      •  1 public class Main {
         2     public static void main(String[] args) {
         3         Outer.StaticNested sn = new Outer.StaticNested();   //外部類無需例項化
         4         sn.hello();
         5     }
         6 }
         7 
         8 class Outer {
         9     private static String NAME = "OUTER";
        10 
        11     private String name;
        12 
        13     Outer(String name) {
        14         this.name = name;
        15     }
        16 
        17     static class StaticNested {
        18         void hello() {
        19             System.out.println("Hello, " + Outer.NAME);
        20         }
        21     }
        22 }
      • static修飾的內部類和Inner Class有很大的不同,它不再依附於Outer的例項,而是一個完全獨立的類,因此無法引用Outer.this,但它可以訪問Outerprivate靜態欄位和靜態方法。如果把StaticNested移到Outer之外,就失去了訪問private的許可權。
  • classpath和jar

    • classpath和jar
    • 圖1
    • 圖2 
  • 模組
  • 多型
    • 在繼承關係中,子類如果定義了一個與父類方法簽名完全相同的方法,被稱為覆寫(Override)。
    • Java的例項方法呼叫是基於執行時的實際型別的動態呼叫,而非變數的宣告型別。(多型
    • public void runTwice(Person p) {
          p.run();
          p.run();
      }

      它傳入的引數型別是Person,我們是無法知道傳入的引數實際型別究竟是Person,還是Student,還是Person的其他子類,因此,也無法確定呼叫的是不是Person類定義的run()方法。

  • 覆寫Object方法

    • toString():把instance輸出為String
    • equals():判斷兩個instance是否邏輯相等;Java equals方法學習
    • hashCode():計算一個instance的雜湊值。
  • 在子類的覆寫方法中,如果要呼叫父類的被覆寫的方法,可以通過super來呼叫。
    class Person {
        protected String name;
        public String hello() {
            return "Hello, " + name;
        }
    }
    
    Student extends Person {
        @Override
        public String hello() {
            // 呼叫父類的hello()方法:
            return super.hello() + "!";
        }
    }
  • 方法標記為final。用final修飾的方法不能被Override
  • 類本身標記為final。用final修飾的類不能被繼承:
  • final修飾的欄位(包括區域性變數)在初始化後不能被修改。
    • 可以在構造方法中初始化final欄位123
      1 class Person {
      2     public final String name;
      3     public Person(String name) {
      4         this.name = name;
      5     }
      6 }
  • 抽象類
    • 一個class定義了方法,但沒有具體執行程式碼,這個方法就是抽象方法,抽象方法用abstract修飾。因為抽象類本身被設計成只能用於被繼承,因此,抽象類可以強迫子類實現其定義的抽象方法,否則編譯會報錯。因此,抽象方法實際上相當於定義了“規範”。
    • 抽象方法的類都是抽象類,抽象類不全是抽象方法。
    • 面向抽象程式設計的本質就是:

      • 上層程式碼只定義規範(例如:abstract class Person);

      • 不需要子類就可以實現業務邏輯(正常編譯);

      • 具體的業務邏輯由不同的子類實現,呼叫者並不關心。

  • 介面
      • 如果一個抽象類沒有欄位,且所有方法全部都是抽象方法,就可以把該抽象類改寫為介面:interface
      • 介面中屬性預設public static final 修飾 方法預設public abstract修飾
      • 一個具體的class去實現一個interface時,需要使用implements關鍵字。
      • 一個類可以實現多個interface。
      • 一個interface可以繼承自另一個interfaceinterface繼承自interface使用extends,它相當於擴充套件了介面的方法。 View Code
      • 在Java虛擬機器執行的時候,JVM只看完整類名,因此,只要包名不同,類就不同。
      • 包沒有父子關係。java.util和java.util.zip是不同的包,兩者沒有任何繼承關係。
      • 位於同一個包的類,可以訪問包作用域的欄位和方法。不用publicprotectedprivate修飾的欄位和方法就是包作用域
      • import

        • 直接寫出完整類名 mr.jun.Arrays arrays =new mr.jun.Arrays();
        • import語句,匯入Arrays,然後寫簡單類名。
           1 // Person.java
           2 package ming;
           3 
           4 // 匯入完整類名:
           5 import mr.jun.Arrays;
           6 
           7 public class Person {
           8     public void run() {
           9         Arrays arrays = new Arrays();
          10     }
          11 }
        • import static 包名,它可以匯入一個類的靜態欄位和靜態方法。

           1 package main;
           2 
           3 // 匯入System類的所有靜態欄位和靜態方法:
           4 import static java.lang.System.*;
           5 
           6 public class Main {
           7     public static void main(String[] args) {
           8         // 相當於呼叫System.out.println(…)
           9         out.println("Hello, world!");
          10     }
          11 }
        • 如果是簡單類名,按下面的順序依次查詢:

          • 查詢當前package是否存在這個class

          • 查詢import的包是否包含這個class

          • 查詢java.lang包是否包含這個class

        •  因此,編寫class的時候,編譯器會自動幫我們做兩個import動作:
          • 預設自動import當前package的其他class

          • 預設自動import java.lang.*

          • 自動匯入的是java.lang包,但類似java.lang.reflect這些包仍需要手動匯入。
          • 如果有兩個class名稱相同,例如,mr.jun.Arraysjava.util.Arrays,那麼只能import其中一個,另一個必須寫完整類名。

內部類

      • 普通類有個最大的不同,就是Inner Class的例項不能單獨存在,必須依附於一個Outer Class的例項。
         1 public class Main {
         2     public static void main(String[] args) {
         3         Outer outer = new Outer("Nested"); // 例項化一個Outer
         4         Outer.Inner inner = outer.new Inner(); // 例項化一個Inner
         5         inner.hello();
         6     }
         7 }
         8 
         9 class Outer {
        10     private String name;
        11 
        12     Outer(String name) {
        13         this.name = name;
        14     }
        15 
        16     class Inner {
        17         void hello() {
        18             System.out.println("Hello, " + Outer.this.name);
        19         }
        20     }
        21 }
      • Inner Class和普通Class相比,除了能引用Outer例項外,還有一個額外的“特權”,就是可以修改Outer Class的private欄位,因為Inner Class的作用域在Outer Class內部,所以能訪問Outer Class的private欄位和方法。(Inner Class除了有一個this指向它自己,還隱含地持有一個Outer Class例項,可以用Outer.this訪問這個例項。)
      • 匿名內部類
        •   不需要在Outer Class中明確地定義這個Class,而是在方法內部,通過匿名類(Anonymous Class)來定義。
           1 public class Main {
           2     public static void main(String[] args) {
           3         Outer outer = new Outer("Nested");
           4         outer.asyncHello();
           5     }
           6 }
           7 
           8 class Outer {
           9     private String name;
          10 
          11     Outer(String name) {
          12         this.name = name;
          13     }
          14 
          15     void asyncHello() {
          16         Runnable r = new Runnable() {        //重寫父類或者介面的方法
          17             @Override
          18             public void run() {
          19                 System.out.println("Hello, " + Outer.this.name);
          20             }
          21         };
          22         new Thread(r).start();
          23     }
          24 }
      •   靜態內部類
        •  1 public class Main {
           2     public static void main(String[] args) {
           3         Outer.StaticNested sn = new Outer.StaticNested();   //外部類無需例項化
           4         sn.hello();
           5     }
           6 }
           7 
           8 class Outer {
           9     private static String NAME = "OUTER";
          10 
          11     private String name;
          12 
          13     Outer(String name) {
          14         this.name = name;
          15     }
          16 
          17     static class StaticNested {
          18         void hello() {
          19             System.out.println("Hello, " + Outer.NAME);
          20         }
          21     }
          22 }
        • static修飾的內部類和Inner Class有很大的不同,它不再依附於Outer的例項,而是一個完全獨立的類,因此無法引用Outer.this,但它可以訪問Outerprivate靜態欄位和靜態方法。如果把StaticNested移到Outer之外,就失去了訪問private的許可權。

  • classpath和jarclasspath和jar