作為一個資深的菜雞,既然稍微弄通了一點點的繼承多态
那當然要寫個部落格裝一下咯吼吼吼吼吼
首先溫習一下繼承的概念:子類可以繼承父類的公有屬性和方法并進行重寫
public class a extends b{
}
重點1:super和this的使用小解
那麼自然而然會想到一個十分哲學的問題:
我想用我父親的方法該怎麼用:
答案是:super函數!
下面簡單介紹一下super函數的一個用法:
super函數是唯一一個可以顯式調用父類方法:
①構造方法鍊:構造方法可以調用重載的構造方法。如果父類和子類的構造方法都沒有被顯式的調用,那麼編譯器就會自動地将super()作為構造方法的第一句。
public className(){
//some statements
}
等價于
public className(){
super();
//some statements
}
②調用父類方法:super.方法名(參數)
this函數指向類中的屬性,也可以指向構造方法;
super和this函數綜合
例如:
public class a extends b{
public static void main(String[] args) {
new a();
}
public a(){
System.out.print("invoke a");
}
}
class b extends c{
public b(){
this.b("invoke b");
}
public b(String s){
System.out.print(s);
}
}
class c{
public c(){
System.out.print("invoke c");
}
}
以上程式相當于
public class a extends b{
public static void main(String[] args) {
new a();
}
public a(){
//b的super函數
super();
System.out.print("invoke a");
}
}
class b extends c{
public b(){
//有this的顯式調用,不加super函數
this.b("invoke b");
}
public b(String s){
//c的super函數
super();
System.out.print(s);
}
}
class c{
public c(){
System.out.print("invoke c");
}
}
調用順序即為
a()super → b()this → b()super → c()
重點2:方法重寫
方法頭不變,方法體可以改寫,改寫過後可以用super通路父類的未改寫的方法;
區分方法重寫和方法重載
//方法重寫:不改變方法頭
public class a {
public String toString(){A;}
}
public class b extends a{
public String toString(){B;}
}
//方法重載,參數清單改變
public void A(double a){}
public void A(int a){}
重點3:多态
概念:每個可以調用父類執行個體的地方都能調用子類;
Object o = new GeometricObject();
System.out.print(o.toString());
上程式中o調用的是GeometricObject的方法
為什麼呢?
上程式中的解釋應該是這樣的:
建立一個Object類型的引用,指向GeometricObject類型的執行個體
那也就是:o類型是Object,指向GeometricObject類的執行個體
這樣就會引到動态綁定的問題:
動态綁定工作機制:
假設對象o是類C1,C2,……,Cn-1,Cn的執行個體,其中C1是C2的子類,C2是C3的子類……Cn是Cn-1的子類,那麼就有一個繼承串
C1→C2→C3→……→Cn-1→Cn
那麼假如o想調用一個方法p,那麼JVM會依次在C1,C2……查找方法p,一旦找到并實作後不再繼續查找;
例如:
public class Test{
public static void main(String[] args) {
new Person().printPerson;
new Student().printPerson;
}
}
class Student extends Person{
public String getInfo(){
return "Student";
}
}
class Person{
public String getInfo(){
return "Person";
}
public void printPerson(){
System.out.println(getInfo);
}
}
這個程式的傳回是
Person
Student
對第二個的解釋:
new Studen().printPerson();
定義後,JVM開始從Student深挖,Student中沒有該方法,則調用Person中的該方法,在調用printPerson方法是又需要調用getInfo函數,從Student開始找,在Student中找到,return并輸出,程式完成。
對象轉換規則和Instanceof函數
對象轉換規則:适用于多态的實作
方法:
小轉大直接轉,大轉小強制轉
如:
Object o = new Student();
Student b = (Student)o;
(注意轉型的文法,比較像資料類型的強制轉型)
既然o已經是Student的執行個體了,為什麼還要強制轉型?
解釋:
小轉大直接轉的原因是小的總會是大的的子類,是以Student的對象始終也是Object的執行個體
而大轉小時,Object中的執行個體不一定是Student的執行個體,是以需要強制轉型規定範圍;
instanceof函數:判斷子類是不是父類的子類
如:
A instanceof B :判斷A是不是B的執行個體,是的話傳回true,否的話傳回false;
而子類的執行個體也是父類的執行個體
是以
A instanceof B傳回true
public class A extends C{}
C instanceof B也傳回true
暫時到這