# extends ```java class MyClass extends MySuperClass { // ... } ``` 一個class只能最多extends一個class 如果 classA extends classB classB extends classC 此時 classB為classA的"superclass" (父類別) classA為classB的"subclass" (子類別) classC為classA的"indirect superclass" (間接父類別) classA為classC的"indirect subclass" (間接子類別) ### Constructor 假設有class Parent, class Child extends Parent 並且假設Parent有`()`建構子: 在`new Child`時, 雖然說會直接呼叫Child的建構子沒錯 但是, Child的第一行會有個`super();`, 它會先去呼叫父類的建構子 如果Parent沒有`()`建構子, (詳見super用法) 底下是一個範例 ```java= class Printer { public Printer() { System.out.println("init Printer"); } public void print(String s) { System.out.println(s); } } class MyPrinter extends Printer { public MyPrinter() { // super(); System.out.println("init MyPrinter"); } public void myPrint(String s) { System.out.println("[A] " + s); } } public class Main { public static void main(String[] args){ // child class MyPrinter p = new MyPrinter(); // init Printer // init MyPrinter p.myPrint("hello"); // [A] hello p.print("hello"); // hello // parent class Printer pa = new Printer(); // init Printer pa.print("hello"); // hello } } ``` ## java.lang.Object https://docs.oracle.com/javase/tutorial/java/IandI/objectclass.html Object class 是整個Class樹的根,每個類別都會是Object的子類別。 如果你的class沒有繼承任何類別, 那該class會繼承Object ![image](https://hackmd.io/_uploads/rkXu5ZLTa.png) 因此每個物件都可以有toString(), equals(), hashCode()等預設方法 這些全部都是從java.lang.Object繼承來的 ```java // 建立Copy protected Object clone() throws CloneNotSupportedException // 預設會是 == public boolean equals(Object obj) // 被GC呼叫時, 查看參考用 protected void finalize() throws Throwable // 取得hashcode public int hashCode() // 取得String表示 public String toString() ``` ### clone() 如果物件有implement Cloneable, 即可調用clone()方法 預設會建立新的物件, 成員變數會與原物件的成員變數相同。 ## Casting 可以把變數Child轉成Parent, Parent轉成Child, (instance是同一個) ```java= public class Main { public static void main(String[] args) { MyPrinter p = new MyPrinter(); Printer p2 = p; //upcasting System.out.println(p2 == p); //true Printer p3 = new MyPrinter(); MyPrinter p4 = (MyPrinter) p3; System.out.println(p3 == p4); //true // Not castable Printer p5 = new Printer(); MyPrinter p6 = (MyPrinter) p5; // ClassCastException } } ``` # instanceof 可以來判斷一個instance是不是屬於某一個class/interface(child也行)的instance ```java= public class Main { public static void main(String[] args){ Printer s = new Printer(); MyPrinter v = new MyPrinter(); boolean b = s instanceof Printer; boolean b2 = s instanceof MyPrinter; boolean b3 = v instanceof Printer; boolean b4 = v instanceof MyPrinter; System.out.println(b); //true System.out.println(b2); //false System.out.println(b3); //true System.out.println(b4); //true } } ``` # @Override 子類別在繼承父類別時, 會繼承父類別的Method(non-static non-final) 如果想要在子類別中,改寫從父類別繼承下來的方法 直接寫一個跟你要改寫的Method一樣的修飾符,Method名,參數 並且可以加一個``@Override`` Annotation (強烈建議寫@Override) 以下範例, 我想讓MyPrinter從Printer繼承下來print方法, 在MyPrinter中要改寫 ```java= class Printer { public void print(String s) { System.out.println(s); } } class MyPrinter extends Printer { @Override public void print(String s) { System.out.println("[A] " + s); } } public class Main { public static void main(String[] args) { // child class MyPrinter p = new MyPrinter(); p.print("hello"); // [A] hello // parent class Printer p2 = new Printer(); p2.print("hello"); // hello } } ``` # Super super 用來呼叫父類別的方法/建構子 ### 呼叫父類別的method 如果子類別override print()方法, super.print()可以使用父類別的print()方法。 (未被override) ```java= class Printer { public void print(String s) { System.out.println(s); } } class MyPrinter extends Printer { @Override public void print(String s) { System.out.println("[A] " + s); } public void parentPrint(String s) { super.print(s); } } public class Main { public static void main(String[] args) { // child class MyPrinter p = new MyPrinter(); p.print("hello"); // [A] hello p.parentPrint("hello"); // hello // parent class Printer p2 = new Printer(); p2.print("hello"); // hello } } ``` ### Constructor的參數問題: 假設父類別的constructor - 沒有implict constructor - 每個constructor都需要parameter 我們需要用super(...)在子類別手動呼叫父類別的constructor ```java= class Printer { private int version; public Printer(int version) { this.version = version; System.out.println(ersion); } public void print(String s) { System.out.println(s); } } class MyPrinter extends Printer { public MyPrinter() { super(0); // 一定要手動呼叫, 因為預設的super()不能用了 } public MyPrinter(int version) { super(version); // 一定要手動呼叫, 因為預設的super()不能用了 } public void myPrint(String s) { System.out.println("[A] " + s); } } public class Main { public static void main(String[] args) { MyPrinter p = new MyPrinter(); // 0 MyPrinter p2 = new MyPrinter(1); // 1 Printer p3 = new Printer(2); // 2 } } ```