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
配合法
- 先定義多個interface
- 用一個abstract class implements 這多個interface
- 需要的class在繼承這個abstract class
or 假設A->C B->C , A,B都是base class而且有object的,C繼承A,B
- Interface A, Interface B
- abstract class或直接implement A,B產生A,B base class
- 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方法
- 先在base class定義好cloneable interface,並定義好clone的method
- derived class繼承後,也寫一個override的clone method
- 先呼叫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之後
數字就比大小,字串就比字典序,要自己定義的話要符合下述規則
- no object o會是最前面的
- 三一律,只會有一個成立: a>b, a<b, a=b
- 遞移律,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
- 宣告在某個class裡面的class,可以是public/private(但這裡只考慮private class)
- 可以寫在任何地方,不像super有限制要寫在第一行
- 相當於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
好處
- 更好的封裝,能做到更多事情
- 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的東西
情況
- 如果你outerclass有static function呼叫inner class的東西時,inner class一定要用static inner class,不然可能呼叫時候根本沒有outer class object。
- 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
- 繼承outerclass的話買一送一,也會有inner class,
- 可以直接用inner class當base class繼承(不深入)
- 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