書接上回,繼承性體現了類與類之間的層次關系。本章我們在掌握繼承的基礎上,深入地學習一下面向對象的多态性。
多态性是面向對象思想中的重中之重!對于初學者來說,不僅理解起來比較費勁,應用上更是捉襟見肘。
但多态性的應用,在我們日常開發過程中,可以說随處可見,是各種框架的靈魂知識點之一,是三大特性中最重要的特性,沒有之一,所以必須認真掌握。
那麼多态性的概念是什麼呢?
多态性統籌的理解,指的是同一種行為,具有不同的表現形式。
多态性從應用上分成兩大類:靜态多态性,動态多态性。
靜态多态性:
靜态多态性又稱編譯期多态性,在程序被編譯的時候,就确定類的對象與函數的調用關系,主要體現在方法重載、運算符重載。
動态多态性:
動态多态性又稱運行時多态性,在程序運行期間,根據傳入的對象不同,決定調用的是哪個對象的函數,主要體現在方法重寫!
靜态多态性對于大家來說,應該耳熟能詳了,接下來我們主要學習下,動态多态性的相關知識體系。
動态多态性地實現基礎,就是對象之間的轉型。在面向對象編程語言中,數據類型的轉換方式有三種:
1.值類型的相互轉換,轉換規則:按取值範圍。
2.值類型與引用類型之間的轉換,轉換規則:裝箱與拆箱。
3.引用類型之間的轉換,轉換規則:建立在繼承的基礎上。
對象之間的類型轉換,我們注意三個要素:
1.必須建立在繼承的基礎上,例如A、B、C三個類,B繼承于A,C為獨立的類,那麼在路上相遇,A可以讓B叫爸爸,但不能讓C叫爸爸,這樣會挨揍的!因為A與C是屬于陌生人的存在。
2.向上轉型:父類引用指向子類對象,屬于自動、隐式轉換,例如:A a = new B();兒子聽老子的話,屬于天經地義的事。
3.向下轉型:必須建立在向上轉型的基礎上,屬于強制轉換,因為你想說服你的父輩,總是很艱難的,需要使用一些非常手段,比如躺地上耍賴[吐舌]。也就是說,如果你希望實現向下轉型的操作,那麼前提是發生了一次向上轉型操作。
例如:A a = new B();這屬于父類指向子類,或者将子類對象賦值給父類,屬于向上轉型。我們可以在這個基礎上,B b = (B)a;來實現向下轉型的操作,通過這種方式,來回歸自我。
例如:A a = new A();在這個基礎上,B b = (B)a;這種方式是完全錯誤的!因為向下轉型,沒有建立在向上轉型的基礎上。
總結一下:
父類指向子類,那麼就是子類向上轉型操作,用周傑倫的話,就是聽媽媽的話!如果子類指向父類的對象,則是父類要向子類向下轉型,需要強制的類型轉換。
看了這麼多,接下來搞一題,讓我們熱乎熱乎身子。兩個類A、B的故事,A是父類,B繼承了A,A中有一個字段x,B中有一個字段y,就是這麼簡單的結構,就是這麼簡單的題目。
那麼A類指向自己的子類B,A的對象能夠訪問字段x,還是字段y,或者x、y都可以訪問呢?
答案估計與你想得不太一樣,A類的對象a,可以訪問的變量竟是自己的字段x!
怎麼樣,多态性的邪惡一面逐漸展現,讓很多小夥伴們摸不清頭腦。沒關系,再堅持一下,離放棄很近了[泣不成聲],我們來分析一波,就真相大白了!
引用類型的創建,可以擁有兩個類型,一個是編譯類型,一個是運行時類型。
編譯時類型:由聲明該變量時使用的類型決定。
運行時的類型:由該變量指向的對象類型決定。
當變量的編譯時類型和運行時類型不一緻時,通過變量訪問它所引用的對象的實例時,該實例變量的值由聲明該變量的類型決定。
例如:A a = new B();等号左邊的A為編譯時類型,等号右邊的B為運行時類型。所以訪問的内容範圍,是由編譯器類型A決定的,所以這就是為什麼A可以訪問自己類中的成員變量,無法訪問B類中定義内容的原因所在。
當編譯時類型和運行時類型不一緻,就會出現多态性。
接下來我們學習下,實現面向對象多态性編程的三個步驟(三個步驟缺一不可):
1.建立繼承關系,無兄弟,不籃球。無繼承,不多态。
2.子類重寫父類的方法,多态性指的是行為的多樣化,同樣的行為,對于不同的對象有着不同的實現方式。
例如:你爺爺吃飯喜歡吃肉,你爹吃飯喜歡吃菜,你姑喜歡吃面條,而你卻鐘愛螺蛳粉。一種吃的行為,對于不同的子類有着不同的實現方式。
3.父類型指向子類型(向上轉型),一般将父類型作為方法的參數,或者方法的返回值。
我們學習了多态性的概念,基礎知識體系,以及編程方式。接下來看看多态性的好處是什麼?為什麼在編程過程中,需要頻繁地使用該特性。
在這裡用一個案例,可以充分地說明,多态性在編程上的優勢所在!比如:動物園有若幹動物,狗、貓、駱駝,還有飼養員。
那麼對于飼養員來說,喂動物是一個方法,如果為每個動物定義一個喂食的方法,程序實在太冗餘了,而且缺乏擴展性,如果動物園引進新的動物,我們難道還要繼續編寫新的方法?這肯定不是明智之舉。
所以我們采用多态性的特點,将動物抽象成一個父類,分别繼承這個父類,以父類作為參數的入口,既可以簡化方法的定義,又可以實現程序的功能,何樂而不為呢?
總結一下:
無論靜态多态性,方法重載。還是動态多态性,方法重寫!本質解決的問題,都是簡化了方法的定義,避免方法定義的冗餘性。
通過這樣的原理,寫出的程序,更有健壯性,擴展性也更好!
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!