1. 引用數(shù)據(jù)類型的類型轉(zhuǎn)換
引用數(shù)據(jù)類型轉(zhuǎn)換的前提是:轉(zhuǎn)換的兩個(gè)對(duì)象之間必須存在繼承或者實(shí)現(xiàn)關(guān)系
引用數(shù)據(jù)類型的轉(zhuǎn)換就是一般與特殊之間的轉(zhuǎn)換
1.1 上溯造型(子類對(duì)象自動(dòng)轉(zhuǎn)換成父類對(duì)象)
燕子類是特殊的,是子類;鳥(niǎo)類是一般的,是父類。
邏輯上“將燕子類看做成鳥(niǎo)類”是說(shuō)得通,可以理解為“將子類看做成父類”。
Parent p; //父類對(duì)象
Child c = new Child(); //子類對(duì)象
p = c; //上溯造型
可以簡(jiǎn)寫為
Parent p = new Child();
子類對(duì)象轉(zhuǎn)換成父類對(duì)象后,會(huì)丟失自己特有的屬性和行為。
燕子被看做成鳥(niǎo)類之后,不再具有燕子的特征。
鳥(niǎo)類
public class Bird {
public String name;
public void eat() {
System.out.println(name+"正在吃");
}
}
燕子類
public class Swallow extends Bird{
public void fly() {
System.out.println(name+"正在飛");
}
}
測(cè)試類
public class Test {
public static void main(String[] args) {
Swallow s = new Swallow();
s.name="燕子";
s.eat();
s.fly();
System.out.println("======================");
Bird b = new Swallow();
b.name = "燕子";
b.eat();
//b.fly(); //將燕子當(dāng)做鳥(niǎo)看待,丟失燕子的特性
}
}
1.2 下溯造型(父類對(duì)象強(qiáng)制轉(zhuǎn)換成子類對(duì)象)
下溯造型成功的前提:父類對(duì)象必須經(jīng)過(guò)該子類的上溯造型后,再進(jìn)行下溯造型才能成功。
- Swallow -> Bird -> Swallow OK
- Bird -> Swallow NG
- Swallow -> Bird -> Other NG
下溯造型的示例,可以看出,只有new的是Cat時(shí),才能轉(zhuǎn)成Cat。不能轉(zhuǎn)成其他。(new的是哪個(gè)類就能轉(zhuǎn)換成哪個(gè)類的對(duì)象)
public class Test {
public static void main(String[] args) {
Animal a = new Cat(); //上溯造型
Cat c = (Cat) a;//下溯造型
c.climb(); //下溯造型成功
System.out.println("===========");
Animal x = new Cat(); //上溯造型
Dog d = (Dog) a;//下溯造型
d.swim(); //下溯造型失敗
System.out.println("===========");
Animal z = new Animal();//普通動(dòng)物
Cat y = (Cat) z;//下溯造型
y.climb();//下溯造型失敗
}
}

上下溯造型的內(nèi)存理解
順著句柄的方向能夠訪問(wèn)到類型即可轉(zhuǎn)換成功,否則轉(zhuǎn)換失敗

2. 重載
重載也被為overload,編譯時(shí)多態(tài)。
重載體現(xiàn)現(xiàn)實(shí)世界中,某個(gè)事物在某個(gè)行為上有多種表現(xiàn)形式。比如:麻雀既吃糧食也吃害蟲(chóng)。
體現(xiàn)在編程上某個(gè)類中的同名方法名出現(xiàn)多次。
重載的要求:
- 方法名必須一致
- 參數(shù)列表必須不一致
(1)參數(shù)個(gè)數(shù)不同
public void eat() {}
public void eat(int a) {}
(2)參數(shù)類型不同
public void eat(int a) {}
public void eat(String a) {}
(3)參數(shù)類型順序不同
public void eat(int a, String b) {}
public void eat(String a, int b) {}
- 與返回值類型無(wú)關(guān)
重載有關(guān)筆試題:
已知某個(gè)類中定義了public void display()方法,以下哪個(gè)方法不能存在在該類中
- public int display(int a) OK
- public int display() NG
- public double displya() OK (方法名不一致,正常定義方法)
- public void display(int a, String b) OK
- public void display(String a) OK
3. 重寫(覆蓋)
重寫也被為override,運(yùn)行時(shí)多態(tài)。
重寫體現(xiàn)現(xiàn)實(shí)世界中,子類和父類在某個(gè)行為上有不同表現(xiàn)形式,不同子類之間有不同表現(xiàn)形式。比如:鳥(niǎo)類在吃的行為可以認(rèn)為是雜食的,老鷹這類鳥(niǎo)吃肉,蜂鳥(niǎo)吃蜂蜜。
體現(xiàn)在編程上子類改寫(覆蓋)父類同名,同參數(shù),同返回值類型方法的行為,子類方法的訪問(wèn)權(quán)限必須大于等于父類方法的訪問(wèn)權(quán)限。
重寫的要求:
- 必須發(fā)生在繼承或?qū)崿F(xiàn)關(guān)系中
- 子類方法的方法名必須與父類方法的方法名一致
- 子類方法的參數(shù)列表必須與父類方法的參數(shù)列表一致
- 子類方法的返回值類型必須與父類方法的返回值一致
- 子類方法的訪問(wèn)權(quán)限必須不低于父類方法的訪問(wèn)權(quán)限
鳥(niǎo)類
public class Bird {
public void eat() {
System.out.println("父類:鳥(niǎo)類可以吃任何東西");
}
}
麻雀類
public class Sparrow extends Bird{
@Override
public void eat() {
System.out.println("子類:麻雀吃東西");
}
}
測(cè)試類
public class Test {
public static void main(String[] args) {
Bird b = new Bird();
b.eat();
Sparrow s = new Sparrow();
s.eat(); //子類方法覆蓋掉父類方法,結(jié)果顯示子類內(nèi)容
}
}
經(jīng)典筆面試題1:重載與重寫的區(qū)別?
重載:同一個(gè)類,方法名同名不同參,與返回值無(wú)關(guān)
重寫:繼承關(guān)系中,子類改寫父類同名同參同返回值類型,訪問(wèn)權(quán)限大于等于父類
經(jīng)典筆面試題2:已知某個(gè)父類中定義了public void display()方法,以下哪個(gè)方法不能存在在該類的子類中
(1) public void display() OK 重寫
(2) public void display(int a) OK 重載(從父類繼承了public void display()方法)
(3) public int display(int a) OK 重載
(4) public int display() NG 重名了但既不是重寫也不是重載
(5) public int displya() OK 不重名
4. 多態(tài)的形成
多態(tài):同一個(gè)行為在類自身中有多種表現(xiàn)形式,或者在繼承關(guān)系中,子類與父類表現(xiàn)的不一致。
- 重載
編譯時(shí)多態(tài) - 重寫
運(yùn)行時(shí)多態(tài)
(1)繼承或?qū)崿F(xiàn)關(guān)系
(2)重寫
(3)上溯造型(父類的引用,子類的實(shí)例化)

動(dòng)物類
public class Animal {
public void sound() {
System.out.println("動(dòng)物會(huì)叫");
}
}
貓類
ublic class Cat extends Animal{
@Override
public void sound() {
System.out.println("貓:喵喵");
}
}
測(cè)試類
public class Test {
public static void main(String[] args) {
Animal a = new Cat();
a.sound(); //執(zhí)行的Cat類中sound方法
}
}
筆試和面試題一般都會(huì)與多態(tài)相關(guān)的問(wèn)題。
public class Parent{
public void haha(){
System.out.println("Parent Method Invoke");
}
}
public class Child extends Parent{
public void haha(){
System.out.println("Child Method Invoke");
}
}
public class Test{
public void static main(String[] args){
Parent p = new Child();
p.haha();
}
}
運(yùn)行答案:Child Method Invoke