1. 程式人生 > >java 類 介面

java 類 介面

面向物件設計:將一個應用分解成多個物件,將問題分解成多個易處理和維護的小問題

java語言的5個特點

  1. 萬物皆為物件
  2. 程式是物件的集合 它們通過傳送訊息來告知彼此所要做的                                                                              
    想要請求一個物件 就必須對某個特定物件的方法的呼叫請求
  3. 每個物件都有自己的由其他物件所構成的儲存 可以通過將其建立包含現有物件的包的方式來建立新型別的物件 複雜性隱藏在物件的簡單性背後
  4. 每個物件都擁有其型別  "每個物件都是某個類的一個例項"
  5. 某一特定型別的所有物件都可以接受同樣的訊息 "圓形"同時也是"幾何形"型別的物件 所以"圓形"能夠接受''幾何形''的物件的訊息   這樣意味著可以編寫與"幾何形"互動並自動處理所有與幾何形性質相關的事物的程式碼 這種可替代性 是OOP中最強有力的概念

java中物件分配在系統"堆"記憶體中 

final

  • final 修飾變數 -->常量 不能被修改 
  • 1.宣告時初始化
  • 2.建構函式內初始化(例項變數)      靜態變數(初始化程式碼塊內進行賦值)
  • final修飾方法 -->該方法實現是穩定不變的,不允許覆蓋,但可以被過載
  • final修飾類     -->該類不能被繼承
  • final 避免了動態繫結
  • 在探查式系統中可以確定哪些方法是未被覆蓋的 並且可以 "最優先地"將其內聯 就像是對待final修飾的一樣、

static

在static方法內部

不能呼叫非靜態方法 ,非靜態方法可以呼叫static

JVM只為靜態分配一次記憶體,在載入類的過程中完成 只要類被載入了 就可以通過類名進行訪問(不推薦使用this進行訪問)

靜態方法內不能用this super關鍵字 不能直接訪問例項變數和例項方法

不能用靜態方法覆蓋例項方法,可以用例項方法的過載可以是靜態的

main()方法在頂端類 則必須宣告為static 若不在則不能宣告為 static


一  類

類可以包含 變數(欄位)   方法(函式)    其他類    程式碼塊

只有public, protected, private, static, final, transient 和 volatile 能修飾成員變數

 

class Test{
    public int num;                 //例項變數:  每個物件例項都有其自己的一組例項變數
    public static int count = 0;    //靜態變數(類變數):  由一個物件的全體例項共享static 修飾
    Test(int i){
        this.num = i;
        count++;
    }
    
//當該類的物件建立以後,例項方法才分配了入口地址,該類的所有物件共享例項方法的入口地址
    protected void printf(){     
        System.out.println("count is "+this.count+" "+"num="+this.num);
    }
    public class InteriorClass{    //內部類
        {
            this.SayHello();       //程式碼塊 
        }
        public static  SayHello(){    //靜態方法(類方法) 
                                      //靜態方法通過類名呼叫
            System.out.println("Hello")
        }
    }
} 

 1.1訪問欄位和方法

1.同一類中,

  • 可以直接通過名字訪問和呼叫類方法   (注意當方法中的變數與例項變數重名,則區域性變數會在方法中遮蔽 例項變數的名字,可以通過this指標顯示的引用當前物件的例項變數)
  • 使用 this 顯示的引用當前物件或當前物件的一個成員

`2.其他類 可以通過引用來訪問物件的成員 點號 ( . )

對於靜態方法(類方法)可以直接通過類名進行呼叫 不用建立例項

對於例項方法 必須通過例項或物件呼叫

1.2 修改static final 組合在一起修飾的變數,則可能重新編譯使用了該類的所有程式碼

因為編譯器允許在引用這些值得類中對其"內聯"

1.3 靜態方法

關鍵字 static

可以通過類名由名字直接呼叫它,在此無需任何物件

1.4 初始化塊

定義:在類的範圍中直接宣告一個程式碼塊 {使用大括號 擴起的一些語句}  

        可以用static修飾    宣告為靜態即 靜態程式碼塊(靜態初始化塊),不能存在方法體中

       構造程式碼塊(初始化塊):直接在類中宣告 ,位於所有成員、構造器以及宣告之外,構造塊會在建立物件時被呼叫,每次建立時都會被呼叫,優先於類建構函式執行。只有當所有的構造器都宣告某個檢查型異常時,初始化塊才可以丟擲該異常

        在方法體中  區域性程式碼塊,在程式碼塊中宣告的變數,在程式碼塊結束時銷燬 

               區域性程式碼塊可以用synchronize(同步監視器)修飾   表示在同一時間只能有一個執行緒進入到該方法快中,是一種多執行緒保護機制 同步程式碼塊需要寫在方法中

 

載入:此程式碼塊不屬於任何方法,會在構造物件時執行一次;若標明程式碼塊為static 則會在類載入時執行一次

作用:為類或一個物件例項完成額外的準備工作

  1. 靜態初始化塊的優先順序最高,最先執行,並且僅在類第一次被載入時執行
  2. 靜態程式碼塊不能存在於任何方法體內。
  3. 靜態程式碼塊不能直接訪問例項變數和例項方法,需要通過類的例項物件來訪問
  4. 非靜態初始化塊和建構函式後執行,並且在每次生成物件時執行一次;
  5. 非靜態初始化塊的程式碼會在類建構函式之前執行。因此若要使用,應當養成把初始化塊寫在建構函式之前的習慣,便於除錯;
  6. 靜態初始化塊既可以用於初始化靜態成員變數,也可以執行初始化程式碼
  7. 非靜態初始化塊可以針對多個過載建構函式進行程式碼複用。即將過載的建構函式 相同部分寫在程式碼塊中
  8. )當所有必要的類靜態變數和靜態程式碼塊 初始化程式碼塊載入完畢,開始執行main()方法體

2.1關於方法 

宣告:  修飾符 返回值 方法名( 引數列表 );

實現:   修飾符 返回值 方法名( 引數列表 ) {  //....  }

1 區域性變數的初始化

要確保使用到的區域性變數,在執行路徑上一定會存在賦值語句

2 引數的傳遞

基本型別值傳遞,物件傳引用

1.通常引用的相關操作將會影響到實際物件例項

2.若將引用指向另一個物件 則只會影響區域性變數的引用  ---->避免這樣的情況的方法: 將obj包裝在某類物件之中 例:可以將物件包裝起來作為某陣列中的獨立元素  TestObj [] test = new TestObj[]{ obj };

3.可變長度的引數列表

variable length argument lists   或 varargs

例子 :printf()

宣告: Object ... list (類似於陣列,使用同陣列)

在宣告varags之前也可以新增普通形參

void printObj (Object ... list ){
    for(Object o : list)
        System.out.println( o );
}

2.2建構函式

  • 要求: 1.建構函式名必須與類名相同
  •           2.必須,若自己沒有定義則編譯器會提供一個空的預設建構函式
  •           3.不能宣告為 abstract synchronized final 
  •           4.沒有返回型別
  •           5..若一個建構函式要呼叫另一個建構函式 則必須 將該呼叫語句 作為第一條
  •           6.super() this()  該建構函式   this()可以使用類名字首呼叫 類名.this()
  • 允許過載    不允許覆蓋
  • 類的靜態員在類首次載入即得到初始化 ,在建構函式中呼叫靜態成員是安全的

3.1派生子類

使用 extends 關鍵字在宣告 為另一個類的子類   例如:class ArrayTest extends Arrays ; 

子類可以從超類中繼承未指定private方法和變數,就如同自己宣告的變數和方法

子型別可以賦值給父類 反之不行

單繼承性

介面實現多繼承

1).遮蔽父類變數:

實現:子類可以宣告與父類同名的例項變數,引用該變數時 由其作用域決定到底引用的是哪個變數

作用: 通過遮蔽可以實現修改其型別或可見性 ,但若將子類賦值給父類,在呼叫其變數,將得到該變數在父類中的形式

2).覆蓋方法

  • 物件:   父類中的方法 如:實現介面的抽象方法
  • 要求:   1. 必須擁有完全相同的引數數目 順序 和型別
  •             2.返回值可以將其修改為原型別的子型別,否則不能修改其型別
  •             3.不可降低方法的可見性
  • 作用 : 改變物件的行為 實現子型別多型性
  • 覆蓋方法 "派生層次最低的類的方法總會覆蓋其他的方法" 與遮蔽變數不同
  • 超類中的靜態方法由子類中的靜態方法所遮蔽,(用final標記除外)    不能用非靜態方法覆蓋靜態方法
  • @Override 標記,告訴編譯器 該方法為覆蓋,非必須
  • 覆蓋方法發生在執行時,即動態繫結
  • 新的方法可選擇丟擲與被覆蓋的方法完全相同的受查異常,也可以丟擲更為具體的子型別 新的方法可以重定義throws子句,使其更具體,這種技術稱為協變.
  •  

3)方法過載

  • 意義:實現特別多型性
  • 物件: 本類中的方法或父類中的方法
  • 要求:必須 引數數目 引數順序 或引數型別  不同 
  •          返回值和可見修飾符不同則不能算過載 編譯的時候直接報方法名重複錯
  • 方法過載由編譯器來選定過載方法,不是在執行時發生的工作

4 強制型別轉換

1).條件: java中 只有同一體系結構中的物件之間進行的強制型別轉換才是合法的

         強制型別轉換需通過編譯器和執行時系統的檢查,

2).影響: 會影響引用的處理,會影響編譯時元素(如變數和過載方法的選擇)

          不會改變覆蓋方法,不會改變實際物件的形式,僅改變編譯器的"看法"

3).通過使用泛型減少前值型別轉換

5.內部類

本質 每個內部類最後都將被編譯成一個獨立的類,生成一個被編譯為一個獨立的類。內部類是java編譯器的概念

內部類方便地訪問外部類的私有變數

內部類可以宣告為 private 從而對外完全隱蔽

      1.   頂級類 : 在檔案和包一級獨立地進行宣告 不能被修飾成靜態

      2.    內部類 :  宣告在大括號內,屬於 方法 或 類  內部類可以直接訪問外部類 外部類訪問內部類必須通過建立內部類例項訪問

       3.         靜態內部類 (巢狀類) 和靜態變數 靜態方法的位置一樣 修飾符為static  

  •          限定名為    外部類名.靜態內部類名
  •          外部      >使用>     非private靜態內部類     方式:  外部類名.靜態內部類名    
  •          外部類  >使用>     靜態內部類     外部類名.靜態內部類名  或 靜態內部類名
    •                                                         
      建立 範圍
      外部類名.靜態內部類名  引用名 = new 外部類名.靜態內部類名 (); 同包下的其他類              外包
       外部類名.靜態內部類名  引用名 = new 靜態內部類名();                               外部類
          靜態內部類名  引用名 = new 內部類名(); 外部類
  •              靜態內部類   >使用>     外部類   
  •                   可以訪問外部類的私有成員或方法
  •                  (類名.靜態變數或靜態方法    或者直接使用變數名或方法名)訪問靜態變數和方法
  •                   不能訪問例項變數和方法

       4       成員內部類:和靜態內部類相比 沒有static修飾符 除了靜態變數和靜態方法 還可以訪問外部類的成員變數和成員方法

  •  成員內部類   >訪問>   外部類   1. 無重名情況  :  直接通過名字訪問外部類的變數及成員
  •                                                  2. 有重名情況   :   外部類.this.xxx 訪問外部類變數和成員
  • 限制: 內部類的變數和方法 不允許用static修飾  (唯一例外用 static  final修飾變數
  • 建立: 內部類物件: 成員內部類物件總是和一個外部類物件相連的
  •          1.建立外部類物件 2. 外部類.內部類   物件名  =  外部類物件名.new 內部類( );

      5.       方法內部類 :只能在定義的方法中使用 可以訪問方法中的被final修飾的引數和區域性變數

          靜態方法中的內部類:     能訪問外部類中靜態變數和靜態常量  方法中的被final修飾的引數和區域性變數

          例項方法中的內部類:     能訪問外部類的例項/靜態 變數和方法

public class Test{
    private static int i = 1;
    private static char c ='A';
    private static void print_i(){
        System.out.println("外部類 :i  "+i);
    }    
    public void t() {
        inner t = new inner();
        t.innerMethod();
    }

    public void inner
    static class inner{
       public int i=10101; // 1.可以重名
       inner(){
            System.out.println("通過類名.靜態成員訪問和本類有重名的 i="+Test.i);
            System.out.println("通過 私有靜態成員的名字 訪問c="+c);
            print_i();//通過 私有靜態方法的名字呼叫
        }
        public void innerMethod(){
            System.out.println("我是靜態內部類的例項方法");
        }
    }
}
//實質
public class Test{
    private static int i = 1;
    private static char c ='A';
    private static void print_i(){
        System.out.println("外部類 :i  "+i);
    }
    public void t() {
        inner t = new inner();
        t.innerMethod();
    }    
    public void t() {
        Test$inner t = new Test$inner();
        t.innerMethod();
    }
    static int access$0(){
        return i;
    }
。。。。
   
}
static class Test$inner{
       public int i=10101; // 1.可以重名
       inner(){
            System.out.println("通過類名.靜態成員訪問和本類有重名的 i="+Test.i);
            System.out.println("通過 私有靜態成員的名字 訪問c="+c);
            print_i();//通過 私有靜態方法的名字呼叫
    }

 

        6 匿名內部類  

 在建立物件的同時,定義內部類  new 父類(引數){//內部類的實現 };

                   new 介面 ( ){//內部類的實現 };

  匿名內部類是唯一一種沒有構造器的類。大部分匿名內部類用於介面回撥。匿名內部類在編譯的時候由系統自動起名為外部類$1.class 同一外部類編號從1開始。一般來說,匿名內部類用於繼承其他類或是實現介面,並不需要增加額外的方法,只是對繼承方法的實現或是重寫,通常寫在 方法內 或引數列表  --->方法中的被final修飾的引數和區域性變數

//2. 內部類
class Animal{      //Animal中任何位置都可以直接通過名字來直接飲用Brain和performBehavior()
        
        class Brain{   //可以值訪問Animal中宣告的所有變數和方法
                       //內部類Brain總包含在Animal的一個例項中,稱此例項為 包圍例項
               ...
        }

        void performBehavior()//可以處理Brain類並建立Brain例項
        {...}
}

//訪問內部類
Animal monkey = new Animal();
Animal.Brain monkeyBrain = monkey.new Brain();

//6.匿名內部類
iterator getIterator(){
    return new Iterator(){
        int element =0;
        boolean hasNext(){
               return elemnt< employees.length;
        }
        Object next(){
            if( hasNext() )
                return employess[ element++ ];
            else
                throw new UnsupportedOperationException();
       }
    }; //
}

用途 1 作為介面卡  匿名內部類的介面卡特別適合與事件處理

內部類的工作原理 

         編譯器 將內部類建立為一個正常的頂級類 為之命名: 將類名與美元符號嘉禾 Animal$Brain

可以在同一檔案中 頂層類外建立類 該類僅頂層類可見

可用於建立該頂層類專用的資料結構等

//檔名 Test.java
class DateType{    //不能被宣告為static 與 public protected private 無可見修飾符
    String name ;
    int age ;
    DateType(String a , int v){
        this.name =a ;
        age = v;
    }
}

public class Test{
    DateType newA = new DateType("Y",12);
//....
    public static void main(String[] agrs){
        Test a = new Test();
//...
    }
}

  抽象介面
抽象類與介面之間可以相互巢狀

abstract 

  • 僅能修飾類和方法
  • abstract方法 僅能存在與 abstract 類中
  • abstract類中可以沒有abstract方法

1.1抽象方法

宣告:   abstract 返回型別 方法名 ( 引數列表 );  // 僅有宣告無實現

1.2抽象類

0).宣告 abstract class Test{           //用abstract修飾類即可   }

1).內容:1.包含零個抽象方法, 抽象方法要被實現,所以不能是靜態的,也不能是私有的。

            2.可以包含非抽象方法和變數,可以有靜態的main 方法

2).不能被例項化

3).對於子類的要求:

  •               若子類實現一部分抽象方法,則它也必須宣告為abstract
  •               子類將所有抽象方法覆蓋

4)抽象類可以繼承實體類 但實體類的建構函式,必須有明確的建構函式

5) 可以 實現介面 ,對於介面內的方法抽象類可以實現全部.部分.0. 個方法

6)如果要例項化,抽象類變數必須指向實現所有抽象方法的子類物件,介面變數必須指向實現所有介面方法的類物件。


2.介面interface  

頂層類 可見性 預設(預設) public

宣告在類內部 時 可public protected default(預設) private

宣告在介面 public

0).用interface關鍵字 定義介面

interface Animal{ //僅允許也是預設的 : public abstract
    boolean  live();
    void     eat();
}

1).implement子句宣告實現介面 

   class dog implement Animal {
        String name;
        boolean dogLive;
        boolean live(){
            if(this.dogLive == true)
                return true;
            else
                return false;
        }
        void eat(){
            if(dogLive == fasle)
                return ;
             else{
                System.out.println("Hi"+this.name+"eat");
            }    
        }
 }

3).介面定義了類 必須實現的一組方法

4).一個類可以實現多個介面 (多個介面之間逗號間隔)

5).可以宣告變數為一種介面型別,也可以宣告方法的引數wei 介面型別 可指定一個方法返回一個介面型別

6).屬性的預設(也僅允許)是public static final   通過介面的名稱來引用它

    方法是預設(也僅允許)public abstract 

 7).空介面 作為標記,表示一個類由特殊性 如java,io.Serializable  希望得到串型化的類

 8).java8中 介面可以有實現方法 使用default修飾

2.1子介面

1).定義: 介面型別繼承另一個或多個介面型別 (用逗號分隔 ,)

2).方法的衝突與覆蓋

           衝突: 存在方法具有相同的名稱

          覆蓋:   若具有完全相同的簽名和返回型別,則無問題  (ps: 方法的簽名 與名稱和引數列表有關)

                      若它們在過載方式有所不同,則必須對不同方法簽名的一一覆蓋

                      若具有相同的名稱,但返回型別或異常型別有區別,則該類無法將兩個方法都實現,並且會發生編譯錯誤

3.

如果要例項化,抽象類變數必須指向實現所有抽象方法的子類物件,介面變數必須指向實現所有介面方法的類物件。

接口裡定義的變數只能是公共的靜態的常量,抽象類中的變數是普通變數

抽象方法只能申明,不能實現,介面是設計的結果 ,抽象類是重構的結果

普通類不能有抽象方法

三 

1. 編譯單元

       java類的原始碼被組織為編譯單元,一個簡單的編譯單元僅包含一個類定義,並以類名來命名

        將類劃分至各自的編譯單元中是非常重要的 

2.package

  •      包名 採用以點號分隔的命名約定,按層次體系來構造(包的名稱空間實際上是平坦的)
  •               預設下,包名的各部分對應目錄名,充當唯一的路徑,以供編譯器和執行時系統定位java原始檔和類
  • package語句宣告一個類屬於一個特定的包   必須作為檔案的第一條語句 作用於整個檔案 

3.匯入類 

 import 語句 應用於整個編譯單元 

完全限定名 :  包名.類名

簡單名(短名): 類名

宣告:        import 類的完全限定名 ;

                import 包名.*; //匯入該包內的所有類

4.未命名包

若一個類定義與某個編譯單元 而此編譯單元未指定包,則該類將落入 未命名包

為命名包內的類可以通過簡單名相互引用

編譯和執行時 這些類的路徑即認為當前路徑

四 訪問修飾符

private 僅自身類的例項可以訪問
default 包中的類
protected 包中的類 子類(包括其他包中的子類)
public 所有類

 

 

 

 

interface  ['ɪntəfeɪs]  詳細X

基本翻譯

n. 介面;<計>介面;交介面

v. (使通過介面或介面)接合,連線;[計算機]使聯絡

vi. 相互作用(或影響);交流,交談

網路釋義

Interface: 介面

Communication Interface: 通訊介面

pattern interface: 介面模式