參考:https://www.cnblogs.com/ChrisMurphy/p/5054256.html
父類引用指向子類對象指的是:
例如父類Animal,子類Cat,Dog。其中Animal可以是類也可以是接口,Cat和Dog是繼承或實現Animal的子類。
Animal animal = new Cat();
即聲明的是父類,實際指向的是子類的一個對象。
那這么使用的優點是什么,為什么要這么用?可以用這幾個關鍵詞來概括:多態、動態鏈接,向上轉型
也有人說這是面向接口編程,可以降低程序的耦合性,即調用者不必關心調用的是哪個對象,只需要針對接口編程就可以了,被調用者對於調用者是完全透明的。讓你更關注父類能做什么,而不去關心子類是具體怎么做的,你可以隨時替換一個子類,也就是隨時替換一個具體實現,而不用修改其他.
以后結合設計模式(如工廠模式,代理模式)和反射機制可能有更深理解。
下面介紹java的多態性和其中的動態鏈接,向上轉型:
面向對象的三個特征:封裝、繼承和多態;
封裝隱藏了類的內部實現機制,可以在不影響使用者的前提下修改類的內部結構,同時保護了數據;
繼承是為了重用父類代碼,子類繼承父類就擁有了父類的成員。
方法的重寫、重載與動態連接構成多態性。Java之所以引入多態的概念,原因之一是它在類的繼承問題上和C++不同,后者允許多繼承,這確實給其帶來的非常強大的功能,但是復雜的繼承關系也給C++開發者帶來了更大的麻煩,為了規避風險,Java只允許單繼承,派生類與基類間有IS-A的關系(即“貓”is a “動物”)。這樣做雖然保證了繼承關系的簡單明了,但是勢必在功能上有很大的限制,所以,Java引入了多態性的概念以彌補這點的不足,此外,抽象類和接口也是解決單繼承規定限制的重要手段。同時,多態也是面向對象編程的精髓所在。
理解多態,首先要知道“向上轉型”。
我定義了一個子類Cat,它繼承了Animal類,那么后者就是前者是父類。我可以通過
Cat c = new Cat();
實例化一個Cat的對象,這個不難理解。但當我這樣定義時:
Animal a = new Cat();
這代表什么意思呢?
很簡單,它表示我定義了一個Animal類型的引用,指向新建的Cat類型的對象。由於Cat是繼承自它的父類Animal,所以Animal類型的引用是可以指向Cat類型的對象的。這就是“向上轉型”。
那么這樣做有什么意義呢?因為子類是對父類的一個改進和擴充,所以一般子類在功能上較父類更強大,屬性較父類更獨特, 定義一個父類類型的引用指向一個子類的對象既可以使用子類強大的功能,又可以抽取父類的共性。 所以,父類類型的引用可以調用父類中定義的所有屬性和方法,而對於子類中定義而父類中沒有的方法,父類引用是無法調用的;
那什么是動態鏈接呢?當父類中的一個方法只有在父類中定義而在子類中沒有重寫的情況下,才可以被父類類型的引用調用; 對於父類中定義的方法,如果子類中重寫了該方法,那么父類類型的引用將會調用子類中的這個方法,這就是動態連接。