摘要:實現(xiàn)多態(tài)的三個必要條件繼承在多態(tài)中必須存在有繼承關系的子類和父類。參考面試題解惑系列九繼承多態(tài)重載和重寫面向對象三大特性封裝,繼承,多態(tài)以及抽象接口的介紹
1. 面向對象編程的三大特性版權聲明:本文由吳仙杰創(chuàng)作整理,轉載請注明出處:https://segmentfault.com/a/1190000009141566
Java 面向對象編程有三大特性:封裝、繼承、多態(tài)。
1.1 封裝(Encapsulation)封裝
: 隱藏對象的屬性和實現(xiàn)細節(jié),僅對外公開訪問方法,控制在程序中屬性的讀和寫的訪問級別。
增強安全性和簡化編程,使用者不必了解具體的實現(xiàn)細節(jié),而只要通過對外公開的訪問方法,來使用類的成員。
1.1.2 封裝的基本要求把所有的屬性私有化。
對每個屬性提供 getter 和 setter 方法。
如果有一個帶參的構造函數(shù)的話,那一定要寫一個不帶參的構造函數(shù)。
建議重寫 toString 方法,但這不是必須的。
1.2 繼承(Inheritance)繼承
: 可以理解為,在一個現(xiàn)有類的基礎之上,增加新的方法或重寫已有方法,從而產(chǎn)生一個新類。
我們在編寫 Java 代碼時,每一個類都是在繼承。因為在 Java 中存在一個所有類的父類(基類、超類):java.lang.Object。
1.2.1 繼承和權限子類不能繼承父類中訪問權限為 private 的成員變量和方法,也不能繼承父類的構造方法。子類可以重寫父類的方法,及命名與父類同名的成員變量。
有時候我們會有這樣的需求:我們需要將某些事物盡可能地對這個世界隱藏,但是仍然允許子類的成員來訪問它們。這個時候就需要使用到 protected。
類成員訪問修飾符與訪問能力之間的關系:
類型 | private | 無修飾 | protected | public |
---|---|---|---|---|
同一類 | 可訪問 | 可訪問 | 可訪問 | 可訪問 |
同一包中的子類 | 不可訪問 | 可訪問 | 可訪問 | 可訪問 |
同一包中的非子類 | 不可訪問 | 可訪問 | 可訪問 | 可訪問 |
不同包中的子類 | 不可訪問 | 不可訪問 | 可訪問 | 可訪問 |
不同包中的非子類 | 不可訪問 | 不可訪問 | 不可訪問 | 可訪問 |
Java 中類可分為以下三種:
普通類:使用 class 定義且不含有抽象方法的類。
抽象類:使用 abstract class 定義的類,它可以含有或不含有抽象方法。
接口:使用 interface 定義的類。
上述三種類存在以下的繼承規(guī)律:
普通類可以繼承(extends)普通類,可以繼承(extends)抽象類,可以繼承(implements)接口。
抽象類可以繼承(extends)普通類,可以繼承(extends)抽象類,可以繼承(implements)接口。
接口只能繼承(extends)接口。
注意:
上述的繼承規(guī)律中,每種繼承都有各自使用的關鍵字 extends 和 implements,不可混淆使用。
上述描述中,我們沒有對 implements 關鍵字使用實現(xiàn)這種說法,是因為從概念上來講,它也是一種繼承關系,而且對于抽象類 implements 接口而言,它并不要求一定要實現(xiàn)這個接口中定義的方法。
各繼承規(guī)律中的約束:
一個普通類或一個抽象類,要么繼承一個普通類,要么繼承一個抽象類,即所謂的單繼承。
一個普通類或一個抽象類或一個接口,可以繼承任意多個接口。
一個普通類繼承一個抽象類后,必須實現(xiàn)這個抽象類中定義的所有抽象(abstract)方法,否則就只能被定義為抽象類。
一個普通類繼承一個接口后,必須實現(xiàn)這個接口中定義的所有方法,否則就只能被定義為抽象類。
抽象類繼承抽象類,或者實現(xiàn)接口時,可以部分、全部或者完全不實現(xiàn)父類抽象類的抽象(abstract)方法或父類接口中定義的方法。
1.2.3 繼承的優(yōu)點繼承給我們的編程帶來的好處就是對原有類的復用(重用)。除了繼承之外,我們還可以使用組合的方式來復用類。
所謂組合就是把原有類定義為新類的一個屬性,通過在新類中調(diào)用原有類的方法來實現(xiàn)復用。從抽象概念上來講,新定義類所代表的事物是原有類所代表的事物的一種,那么這時組合就是實現(xiàn)復用更好的選擇。下面這個例子就是組合方式的一個簡單示例:
/** * 寶馬 */ public class BMW { private Car car = new Car(); public void driveBMW() { // 復用汽車類的通用駕駛方法 car.drive(); // 再寫寶馬車的特定駕駛方法 } } /** * 汽車 */ class Car { public void drive() { // 開車 } }
使用繼承和組合復用原有的類,都是一種增量式的開發(fā)模式,這種方式帶來的好處是不需要修改原有的代碼,因此不會給原有代碼帶來新的 BUG,也不用因為對原有代碼的修改而重新進行測試,這對我們的開發(fā)顯然是有益的。因此,如果我們是在維護或者改造一個原有的系統(tǒng)或模塊,尤其是對它們的了解不是很透徹的時候,就可以選擇增量開發(fā)的模式,這不僅可以大大提高我們的開發(fā)效率,也可以規(guī)避由于對原有代碼的修改而帶來的風險。
1.3 多態(tài)(Polymorphism)多態(tài)
: 相同的事物,調(diào)用其相同的方法,參數(shù)也相同時,但表現(xiàn)的行為卻不同。
以下的例子,可幫助理解:
/** * 汽車接口 */ interface Car { // 汽車名稱 String getName(); // 獲得汽車售價 int getPrice(); } // 寶馬 class BMW implements Car { public String getName() { return "BMW"; } public int getPrice() { return 300000; } } // 奔馳 class BENZ implements Car { public String getName() { return "BENZ"; } public int getPrice() { return 400000; } } // 汽車出售店 public class CarShop { // 售車收入 private int money = 0; // 賣出一部車 public void sellCar(Car car) { System.out.println("車型:" + car.getName() + " 單價:" + car.getPrice()); // 增加賣出車售價的收入 money += car.getPrice(); } // 售車總收入 public int getMoney() { return money; } public static void main(String[] args) { CarShop carShop = new CarShop(); // 賣出一輛寶馬 carShop.sellCar(new BMW()); // 賣出一輛奔馳 carShop.sellCar(new BENZ()); System.out.println("總收入:" + carShop.getMoney()); } }
運行結果:
車型:BMW 單價:300000 車型:BENZ 單價:400000 總收入:700000
繼承是多態(tài)得以實現(xiàn)的基礎。針對上面的示例,多態(tài)就是一種類型(都是 Car 類型)表現(xiàn)出多種狀態(tài)(寶馬汽車的名稱是 BMW,售價是 300000;奔馳汽車的名稱是 BENZ,售價是 400000)。
綁定
: 將一個方法調(diào)用同這個方法所屬的主體(也就是對象或類)關聯(lián)起來,分前期綁定和后期綁定兩種。
前期綁定:在程序運行之前進行綁定,由編譯器和連接程序實現(xiàn),又叫做靜態(tài)綁定。比如 static 方法和 final 方法,注意,這里也包括 private 方法,因為它是隱式 final 的。
后期綁定:在運行時根據(jù)對象的類型進行綁定,由方法調(diào)用機制實現(xiàn),因此又叫做動態(tài)綁定,或者運行時綁定。除了前期綁定外的所有方法都屬于后期綁定。
多態(tài)就是在后期綁定這種機制上實現(xiàn)的。
多態(tài)給我們帶來的好處是消除了類之間的耦合關系,使程序更容易擴展。比如在上例中,新增加一種類型汽車的銷售,只需要讓新定義的類繼承 Car 類并實現(xiàn)它的所有方法,而無需對原有代碼做任何修改,CarShop 類的 sellCar(Car car) 方法就可以處理新的車型了。
1.3.1 實現(xiàn)多態(tài)的三個必要條件繼承:在多態(tài)中必須存在有繼承關系的子類和父類。
重寫:子類對父類中某些方法進行重新定義,在調(diào)用這些方法時就會調(diào)用子類的方法。
向上轉型:在多態(tài)中需要將子類的引用賦給父類對象,只有這樣該引用才能夠具備技能調(diào)用父類的方法和子類的方法。
只有滿足了上述三個條件,我們才能夠在同一個繼承結構中使用統(tǒng)一的邏輯實現(xiàn)代碼處理不同的對象,從而達到執(zhí)行不同的行為。
1.3.2 多態(tài)的實現(xiàn)方式基于繼承實現(xiàn)的多態(tài)
: 主要表現(xiàn)在父類和繼承該父類的一個或多個子類對某些方法的重寫,多個子類對同一方法的重寫可以表現(xiàn)出不同的行為。
基于接口實現(xiàn)的多態(tài)
: 在接口的多態(tài)中,指向接口的引用必須是指定這實現(xiàn)了該接口的一個類的實例,在運行時,根據(jù)對象引用的實際類型來執(zhí)行對應的方法。
繼承都是單繼承,只能為一組相關的類提供一致的服務接口。
接口是多繼承多實現(xiàn),它能夠利用一組相關或者不相關的接口進行組合與擴充,能夠對外提供一致的服務接口。所以它相對于繼承來說有更好的靈活性。
2. 重載(overloading)重寫(overriding)重載和重寫都是針對方法的概念,在弄清楚這兩個概念之前,我們先來了解一下什么叫方法的型構(signature)。
型構
: 指方法的組成結構,具體包括方法的名稱和參數(shù),涵蓋參數(shù)的數(shù)量、類型以及出現(xiàn)的順序,但是不包括方法的返回值類型,訪問權限修飾符,以及 abstract、static、final 等修飾符。
示例一、下面兩個是具有相同型構的方法:
public void method(int i, String s) { // do something } public String method(int i, String s) { // do something }
注意:在同一個類中,是不允許定義多于一個的具有相同型構的方法。
示例二、下面兩個是具有不同型構的方法:
public void method(int i, String s) { // do something } public void method(String s, int i) { // do something }
了解完型構的概念后我們再來看看重載和重寫:
重寫(overriding)
: 指在繼承情況下,子類中定義了與其父類中方法具有相同型構的新方法,就稱為子類把父類的方法重寫了。這是實現(xiàn)多態(tài)必須的步驟。
重載(overloading)
: 指在同一個類中定義了一個以上具有相同名稱,但是型構不同的方法。
為了加深理解,我們來考慮一個有趣的問題:構造器可以被重載嗎?
答案當然是可以的,我們在實際的編程中也經(jīng)常這么做。實際上構造器也是一個方法,構造器名就是方法名,構造器參數(shù)就是方法參數(shù),而它的返回值就是新創(chuàng)建的類的實例。但是構造器卻不可以被子類重寫,因為子類無法定義與父類具有相同型構的構造器。
3. 參考JAVA面試題解惑系列(九)——繼承、多態(tài)、重載和重寫
java 面向對象三大特性(封裝,繼承,多態(tài))以及抽象、接口的介紹
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://m.hztianpu.com/yun/67075.html
摘要:摘要本文章關注點是理解面向對象概念,從抽象的角度上去理解對象,重點包括理解對象的作用,以及理解面向對象的三大特征封裝,繼承,多態(tài)。特性多態(tài)不同對象以自己的方式響應相同的消息的能力叫做多態(tài)。 摘要:本文章關注點是理解面向對象概念,從抽象的角度上去理解對象,重點包括理解對象的作用,以及理解面向對象的三大特征(封裝,繼承,多態(tài))。本文重點關注的是理解概念。 在理解面向對象之前,首先回答幾個問...
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:多態(tài)性面向對象三大特性封裝繼承多態(tài)。面向對象多態(tài)性存在的三個必要條件繼承重寫父類引用指向子類對象多態(tài)性的實現(xiàn)方式重寫與重載靜態(tài)多態(tài)性方法重載方法重載允許類具有多個相同名稱的方法,但是方法參數(shù)列表不同。 多態(tài)性 面向對象(OOP)三大特性:封裝、繼承、多態(tài)。 多態(tài)性(polymorphism)指同一行為具有多種不同表現(xiàn)形式,在面向對象程序設計中表現(xiàn)為同一消息可以根據(jù)發(fā)送對象的類型不同,做...
閱讀 3079·2021-11-22 13:54
閱讀 3668·2021-11-16 11:44
閱讀 1446·2021-09-07 10:19
閱讀 1537·2019-08-29 17:30
閱讀 3254·2019-08-29 11:33
閱讀 3601·2019-08-26 12:18
閱讀 2945·2019-08-26 11:53
閱讀 1408·2019-08-26 10:47