父類引用指向子類對(duì)象:假設(shè)我有一個(gè)Animal類敛熬,和一個(gè)Dog類泰讽,則:Animal animal = new Dog();此為父類引用指向子類對(duì)象
1.為什么要用父類的引用指向子類的對(duì)象卒蘸?
有句話我覺(jué)得很精辟:現(xiàn)在寫的代碼校辩,被將來(lái)的代碼調(diào)用,這都不算事「缛遥現(xiàn)在寫的代碼霉旗,能調(diào)用將來(lái)的代碼,這才牛逼勒蛀骇。
具體來(lái)說(shuō):假如有一個(gè)類厌秒,這個(gè)類需要實(shí)現(xiàn)吃各種水果的方法。那如果我們?cè)陬惱锩娑x方法:
public ?void eat(Banana banana) { }
public ?void eat(Apple apple) { }
擅憔。鸵闪。。暑诸。蚌讼。。
這樣就顯得很麻煩个榕,但要是我要是把這個(gè)方法寫成: public void eat(Fruit fruit){} ?這樣只要繼承Fruit或者實(shí)現(xiàn)Fruit接口篡石,就都可以作為eat的參數(shù)。這樣就簡(jiǎn)化了程序西采。
再比如:
寫一個(gè)畫圖程序的時(shí)候凰萨,你想畫方,畫圓,畫線胖眷。方武通,圓,線都屬于Shape類型珊搀。那么就應(yīng)該有
class Shape{}
class Fang extends Shape{}
class Yuan extends Shape{}
class Xian extends Shape{}
然后把他們畫出來(lái)的方法在某個(gè)類里冶忱,這個(gè)方法接收一個(gè)圖形,不管是什么樣的形狀境析,你只要給我一個(gè)圖形囚枪,我就可以把它畫出來(lái),public void draw();
子類里面重寫這個(gè)方法簿晓。如果你的參數(shù)定義成Shape s眶拉,那么就可以接受繼承Shape的所有實(shí)際形狀 public void draw(Shape s);這就實(shí)現(xiàn)了多態(tài)的概念。
2.這樣做有什么意義憔儿?
子類是對(duì)父類的一個(gè)改進(jìn)和擴(kuò)充忆植,所以一般子類在功能上較父類更強(qiáng)大,屬性較父類更獨(dú)特谒臼, 定義一個(gè)父類類型的引用指向一個(gè)子類的對(duì)象既可以使用子類強(qiáng)大的功能朝刊,又可以抽取父類的共性。
3為什么父類引用子類對(duì)象時(shí)蜈缤,不能調(diào)用子類特有的方法拾氓?
比如說(shuō):
定義一個(gè)父類Animal,一個(gè)子類Bird底哥,Bird有個(gè)獨(dú)有的方法:飛行咙鞍。我現(xiàn)在 Animal animal = new Bird ? ?(); 你要調(diào)用 animal.fly()趾徽;這是不符合邏輯的续滋,因?yàn)閯?dòng)物不是都會(huì)飛。這就要回歸到問(wèn)題2:定義一個(gè)父類類型的引用指向一個(gè)子類的對(duì)象既可以使用子類強(qiáng)大的功能孵奶,又可以抽取父類的共性疲酌。
4.這樣做的好處是什么?
總的來(lái)說(shuō)有三方面:一,實(shí)現(xiàn)多態(tài)了袁。二朗恳,減小耦合。三载绿,增加了程序的可移植性粥诫。
5.子類能覆蓋父類的變量嗎(父類引用指向子類對(duì)象時(shí))?答案是不能
比如我在Animal中:int i =1; ?在Dog中: int i = 1000 ;
然后 Animal animal = new Dog()崭庸;
輸出animal.i怀浆,結(jié)果為1.