interface

19 April 2020

Interface

Interface

  • 不是class,是一種type,故可以當function, method的參數
  • 定義一個class該要有的methods、property,當用這個type的class,要implement這些method(跟abstract class很像),只要定義名字,不用寫method內容。
  • Java不允許一個class同時繼承兩個base Class(C++可以),透過interface,一個class可以同時implement數個interface來達到繼承數個base class的效果
  • interface內的method沒有限制型別,但會建議Object,一來有較高的scalability(想要的人自己cast),二來就算是特定type,也是要handle如果type不符的狀況或者null handle,那乾脆一開始就用Object當參數
  • 可以定義變數,但一定要是public, static, final,因此可以不寫,反正都只能這樣了,而且不能修改,所以宣告static正好, 所以interface的變數不能修改
  • 目的在於能夠同時繼承多個interface,不像class只能繼承一個class,當要繼承其他class時就GG, 但不能繼承class, 只能繼承多個interface, 反之, abstract可以繼承一個class或interface

Reference: Abstract vs Median

// 先告interface
public interface Order{
    public boolean percede(Object obj);    // method(壹定要public,不然後面人沒辦法修改)
                                           //不寫代表public
}

要使用該interface來implement一個新的class

public class order1 implements order{
    // 實作order interface要有的method
    public boolean percede(Object obj){...}

}

Abstract class implement interface

如果覺得每次都要重新implement interface裡的method麻煩,可以先用abstract class共同implement一些interface裡的class。 又或者在使用他的class某些method的功能都依樣,就可以用abstract class先implement(就不用每個class都重寫一遍)

public abstract class test implements order{
    public boolean percede(Object obj){...}
}

Derived Interface

interface也是可以繼承interface的,使用這個繼承的interface除了derived interface要做,base interface的method也要做

public interface order3 extedns order{...}

Interface inconsistency

class不允許同時繼承兩個base class就是因為怕兩個base class的method或變數衝突, Interface就還好,反正就只定義名稱,method的詳細內容是implement class自己決定, 但interface如果有定義變數但值不同的話也會incosistence

配合法

  1. 先定義多個interface
  2. 用一個abstract class implements 這多個interface
  3. 需要的class在繼承這個abstract class

or 假設A->C B->C , A,B都是base class而且有object的,C繼承A,B

  1. Interface A, Interface B
  2. abstract class或直接implement A,B產生A,B base class
  3. abstract class c implements A,B產生class c

Example

see page p.765-767

Cloneable

在clone時,如果是object而且有mutable的instance,那clone會導致privacy leak又或者clone會出現exception,因此要重新定義clone method,這時要用Cloneable interface,因此這時就要繼承Cloneable的class來override,但java只能繼承一個class,因此假設Cloneable是base class的話,那這個修改clone method的class就別想繼承其他class了,故採用interface。這樣修改clone,不但可以避免object privacy leak又能處理exception public Object clone(){

}

子類別cloneable方法

  1. 先在base class定義好cloneable interface,並定義好clone的method
  2. derived class繼承後,也寫一個override的clone method
  3. 先呼叫super.clone()將base class的variable(繼承來的)clone好,在接續把自己獨有的instance clone好,super.clone地方不用特別寫exception handle了,理論上base class就把它處理好,所以理論上derived class呼叫的super.clone()都是呼叫base class的method在間接呼叫Object的clone,但base class有exception handle,所以derived class不用handle。

Comparable interface

  • 定義在java.lang裡,不用特別import
  • 有點像定義所有Object的sorting,就不用換一個class就重寫一次

compareTo

public int compareTo(Object other);

  • 回傳負數 : 如果呼叫的數比other還前面
  • 回傳0 : 呼叫的數和other相同
  • 回傳正數 : 呼叫的數在other之後

數字就比大小,字串就比字典序,要自己定義的話要符合下述規則

  1. no object o會是最前面的
  2. 三一律,只會有一個成立: a>b, a<b, a=b
  3. 遞移律,a>b b>c 則 a>c
做sort的function,這樣算是寫一個general type的sorting的class,之後就可以用這個
class的sort來sort不同method。
public static void sort(Comparable[] a){
    if(a.compareTo(...)>0){...}
}

Inner Class

  1. 宣告在某個class裡面的class,可以是public/private(但這裡只考慮private class)
  2. 可以寫在任何地方,不像super有限制要寫在第一行
  3. 相當於Class A(outer class)的一個instance variable或method
public class A{
    private class B{
    ...
    }
    private B b;
    public A(){
        b = new B();
    }
}

A test = new A();    //產生A和同時new一個b

好處

  1. 更好的封裝,能做到更多事情
  2. outerclass, inner class的private method, private variable是互相通用的可以互用
    • inner class呼叫outerclass簡單,就直接呼叫method, inner class找不到該method會去outer class找
    • outer class呼叫inner class method時要先建立inner class的object才能呼叫

Static inner class

non-static 跟static inner class差別在於 static innerclass實際上跟outer class沒什麼連結,他不用invoke outer class產生object才產生inner class的object 而是外面的人可以直接呼叫static inner class的東西

情況

  1. 如果你outerclass有static function呼叫inner class的東西時,inner class一定要用static inner class,不然可能呼叫時候根本沒有outer class object。
  2. inner class有static method或static instance時一定要用static inner class不然就不能呼叫

static inner class剩下的部分跟其他class依樣,就是宣告一堆instance、method,然後看要private還是public,但不能invoke outerclass的nonstatic method或instance

public inner class

就外面也可以呼叫的inner class

Non-static inner class

因為inner class跟outer class一定有關係,所以在invoke inner class前一定要有outer class的Object

public class A1{           // A1的constructor並沒有順便建立A2的Object,所以
    public class A2{...}   //class A1外要建立A2 Object的話要自己new
}                          // 如果class A1 constructor有順便建立A2的話,就不用自己new

// outside class A1
A1 test = new A1();
A1.A2 test2 = test.new A2(); //要用invoke來construct或呼叫A2(inner class)

重點

1

在inner class外建立了inner class(像上述例子)的Object,並不能夠呼叫outer class的method,只能呼叫inner class的method 只有在inner class的method、definition內可以呼叫outer class的method,在inner class 外建立的object不能呼叫outer class的method

2

public static inner class的語法跟non-static inner class不同

non static:
A1.A2 test2 = test.new A2();

static:
A1.A2 test2 = new A1.A2();    //合理因為static,我以A1根本不用先建立object

而且此public static inner class可以在各處呼叫自己的static/nonstatic method。 甚至呼叫時可以省略outer class,但最好還是寫

A1.A2.method();
A2.method();
test2 = new A1.A2();
test2.method();

3

如果outer class跟inner class有method overload,那在inner class內呼叫的話會叫到inner class的method。 假設希望叫道outer class的method

BankAccount.this.getBalance();    //加上this就會呼叫到outer class的method

Inheritance

  1. 繼承outerclass的話買一送一,也會有inner class,
  2. 可以直接用inner class當base class繼承(不深入)
  3. outer class跟inner class可以是分別繼承自不同base class

Anonymous class

就是懶得給class名字來建立object,這種Anonymous class是inner class

public interface Interface{...}

Interface sample = new Interface(){implementation}
// 這裡等於利用Interface這個interface建立一個class,
然後這個class沒有名字,把implementation寫在new的地方
這樣來建立Object