# 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

因此每個物件都可以有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
}
}
```