版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、第4章 Java面向?qū)ο缶幊?下),4.1 繼承,4.2 對象的轉(zhuǎn)型,4.3 多態(tài),4.4抽象類,4.5接口,4.6 終止繼承,4.7 權(quán)限修飾符,4.8 綜合實例:航班管理,4.1 繼承,4.1.1 繼承的定義 在Java語言中,用extends關(guān)鍵字來聲明一個類繼承了另一個類,其語法格式是: class extends 例如,下面的代碼片段定義了一個子類son類,繼承了父類farther類: class father public class son extends father ,4.1.1 繼承的定義,注意,Java只支持單繼承,例如,下面的son類試圖繼承兩個類: class gra
2、ndFather class farther public class son extends farther, grandFather / 錯誤,不允許繼承兩個類 【例4.1】計算箱子的體積和重量。,4.1.2 初始化基類,當(dāng)創(chuàng)建一個子類的對象時,該對象包含了一個基類對象。這個基類對象與用子類直接創(chuàng)建的對象是一樣的。二者的區(qū)別在于,后者來自于外部,而基類對象被包裝在子類對象內(nèi)部。Java虛擬機會確保在子類構(gòu)造器中調(diào)用基類的構(gòu)造器來初始化基類。 【例4.2】子類構(gòu)造器C調(diào)用基類的構(gòu)造器A來初始化基類。,4.1.3 方法的重寫,子類通過extends關(guān)鍵字聲明繼承了父類的屬性和方法,但子類可能覺
3、得從父類繼承過來的方法不能滿足自己的要求,怎么辦呢?解決方法是子類可以重寫(或覆蓋)父類的方法。例如在下面的代碼片段中,子類重寫了父類的run()方法: class Animal void run() / 慢跑 class Tiger extends Animal void run() / 快跑 【例4.3】子類Employee重寫父類的getInfo()方法。,4.1.3 方法的重寫,在使用方法重寫時,以下幾點需要注意。 (1) 子類重寫的方法必須與父類被重寫的方法具有相同的方法名稱、參數(shù)列表和相同或相容的返回值類型,否則不構(gòu)成重寫。如:父類定義了方法:int f(int i) 。若子類方法
4、重寫時寫成:byte f(int i),由于返回值類型是Java基本數(shù)據(jù)類型,必須要相同。因而編譯程序會報錯。但是,若父類定義了方法:Object get(),子類方法重寫時寫成Point get(),雖然返回值類型不同,但由于Point是Object的子類,因而是允許的。即對于返回值類型是引用,則要求相容。這種方式的重寫很有用。,4.1.3 方法的重寫,(2) 子類重寫的方法不能比父類中被重寫的方法擁有更嚴(yán)格的訪問權(quán)限。例如,在下面的代碼片段中,子類試圖縮小父類方法的訪問權(quán)限: class Base . public void method() . public class Sub exte
5、nds Base . private void method() / 編譯錯誤,子類方法縮小父類方法的訪問權(quán)限 . ,4.1.3 方法的重寫,(3) 父類的靜態(tài)方法不能被子類重寫為非靜態(tài)的方法。同樣,父類中的實例方法也不能被子類重寫為靜態(tài)方法。例如下面的代碼片段: class Base . static void method() . public class Sub extends Base . void method() / 編譯錯誤 . ,4.1.3 方法的重寫,(4) 方法重寫只針對實例方法,父類中的靜態(tài)方法,子類只能隱藏、重載和繼承。 (5) 父類中能被子類繼承的實例方法,才會在子類
6、中被重寫。 (6) 子類重寫的方法不能比父類中被重寫的方法聲明拋出更多的異常。 方法重寫和方法重載具有以下相同點: 都要求方法同名。 都可以用于抽象方法和非抽象方法之間。 方法重寫和方法重載具有以下不同點: 方法重寫要求參數(shù)簽名必須一致,而方法重載要求參數(shù)簽名必須不一致。 方法重寫要求返回類型必須一致,而方法重載對此不做限制。 方法重寫只能用于子類從父類繼承的實例方法,方法重載用于同一個類的所有方法(包括從父類中繼承而來的方法)。 方法重寫對方法的訪問權(quán)限和拋出的異常有特殊的要求,而方法重載在這方面沒任何限制。 父類的一個方法只能被子類重寫一次,而一個方法在所在的類中可以被重載多次。 構(gòu)造方法
7、能被重載,但不能被重寫。,4.1.4 super關(guān)鍵字,若子類重寫了父類中的方法或子類隱藏了父類中的數(shù)據(jù)成員,但又想訪問父類的成員變量和方法,怎么辦?解決的辦法是使用super關(guān)鍵字。 【例4.4】子類SubClass使用super關(guān)鍵字,訪問父類SuperClass的成員變量和構(gòu)造方法。,4.2 對象的轉(zhuǎn)型,例如,B類是A類的子類或間接子類,當(dāng)子類B創(chuàng)建一個對象,并把這個對象賦給類A的引用變量,那么,稱這個A類對象a是子類對象b的向上轉(zhuǎn)型的對象。這個向上轉(zhuǎn)型的對象還可以通過強制類型轉(zhuǎn)換還原成它本來的類型,被稱為對象的向下轉(zhuǎn)型。 class A class B extends A A a; B
8、 b1 = new B(); a = b1;/ 向上轉(zhuǎn)型 B b2 = (B) a;/ 向下轉(zhuǎn)型 向上轉(zhuǎn)型的對象具有如下特點: (1) 向上轉(zhuǎn)型對象不能操作子類新增的成員屬性和方法(失掉了這部分功能)。 (2) 向上轉(zhuǎn)型對象可以操作子類繼承或隱藏的成員變量,也可以使用子類繼承的或重寫的方法。 (3) 向上轉(zhuǎn)型對象操作子類繼承或重寫的方法時,就是通知對應(yīng)的子類對象去調(diào)用這些方法。因此,如果子類重寫了父類的某個方法后,對象的向上轉(zhuǎn)型對象調(diào)用這個方法時,一定是調(diào)用了這個重寫的方法。 (4) 可以將向上轉(zhuǎn)型對象再強制轉(zhuǎn)換到它本來的類型,該對象又具備了其所有屬性和方法。 【例4.5】測試對象轉(zhuǎn)型的特點,
9、使用instanceof判斷一個實例對象是否屬于某個類。,4.2 對象的,instanceof可以判斷一個引用變量所指向的對象是否屬于某個類,所以在執(zhí)行下面第一條語句返回true,執(zhí)行第二條語句發(fā)生了對象的向上轉(zhuǎn)型,Person類的引用變量指向 System.out.println(p instanceof Employee); p = new Employee(Mary, 3000); Employee對象,如圖4.1的箭頭。但這時引用變量p所能訪問的內(nèi)容只限于Employee對象的父類Person對象,也就是箭頭所指向的區(qū)域。在執(zhí)行下面的這條語句時,發(fā)生了對象的向下轉(zhuǎn)型。 Employee
10、 e1 = (Employee) p; Employee類的引用變量e1同樣指向Employee對象。這時引用變量e1能訪問Employee對象的所有內(nèi)容,也就是箭頭所指向的區(qū)域。,圖4.1 程序執(zhí)行的內(nèi)存布局,4.2 對象的,程序運行結(jié)果: true true true false Mary true true 3000 I am working hard! Lily 4000 I am studying hard! name is:Lily studentId is:4000 name is:John studentId is:18 name is:Lucy studentId is:20
11、00,4.3 多態(tài),運行Cast.java程序,可以發(fā)現(xiàn)testCase()方法接受一個Person引用。那么在這種情況下,編譯器怎樣才能知道這個Person引用指向的是Student對象還是Employee對象?實際上,編譯器無法得知,解決的方法就是動態(tài)綁定。它的含義就是在運行期間(而非編譯期間)判斷所引用對象的實際類型并根據(jù)對象的類型進行綁定,從而調(diào)用恰當(dāng)?shù)姆椒?。只要滿足類之間有繼承關(guān)系、子類重寫父類的方法、父類引用指向子類對象這三個條件,動態(tài)綁定就會自動發(fā)生,從而實現(xiàn)多態(tài)。多態(tài)不但能夠改善代碼的組織結(jié)構(gòu)和可讀性,還能夠創(chuàng)建可擴展的程序,消除類型之間的耦合關(guān)系。多態(tài)方法調(diào)用允許一種類型表現(xiàn)
12、出與其他相似類型之間的區(qū)別,只要它們都是繼承同一基類。 【例4.6】Polymorphism程序滿足多態(tài)條件,根據(jù)對象的類型調(diào)用恰當(dāng)?shù)姆椒ā?4.4 抽象類,在Java中,只聲明而沒有實現(xiàn)的方法稱為抽象方法,其語法規(guī)則如下: abstract (); 用abstract修飾的類稱為抽象類,其語法規(guī)則如下: 訪問修飾符abstract class 下面的Graphix類定義為抽象類,方法calArea()定義為抽象方法: abstract class Graphix / 抽象類 abstract void calArea(); / 抽象方法 class Rect extends Graphix
13、void calArea() / 重寫抽象方法 System.out.println(計算長方形面積); ,4.4 抽象類,抽象類具有以下特性: (1) 含有抽象方法的類必須被聲明為抽象類,抽象類必須被繼承,抽象方法必須被實現(xiàn)。 (2) 抽象類中不是所有的方法都是抽象方法,可以在抽象類中聲明并實現(xiàn)方法。 (3) 抽象類的子類必須實現(xiàn)父類的所有抽象方法后才能實例化,否則這個子類也成為一個抽象類。 (4)抽象類不能實例化。 【例4.7】Dog類繼承Animal類并實現(xiàn)抽象方法run()。,4.5 接口,接口的定義格式如下: publicinterface extends 關(guān)鍵字interface用
14、于定義接口,接口通常都定義為public類型。例如,定義一個接口: public interface Runner int id = 1;/ 等價于public static final int id = 1; public void start();/ 等價于public abstract void start(); public void run(); public void stop(); ,4.5 接口,接口具有以下特性: (1) 接口中的常量默認(rèn)為public static final,并且也只能是public static final。 (2) 接口中只能定義抽象方法,而且這些方法
15、默認(rèn)為public abstract,并且也只能是public abstract類型。 (3) 接口可以繼承其他的接口,并添加新的屬性和抽象方法。 (4) 在接口中聲明方法時,不能使用native、static、final、synchronized、private、protected等修飾符。 (5)Java中不允許類的多繼承,但允許接口的多繼承。 (6) 不允許創(chuàng)建接口的實例,但允許定義接口類型的引用變量,該變量引用實現(xiàn)了該接口的類的實例。 (7) 一個類只能繼承另外一個類,但能同時實現(xiàn)多個接口,并且重寫的方法必須顯式聲明為public。 【例4.8】測試接口的多種特性。,4.6 終止繼承,
16、final具有“不可改變”的含義,它可以修飾非抽象類、非抽象成員方法和變量。 (1) 用final修飾的類不能被繼承,沒有子類。 (2) 用final修飾的方法不能被子類的方法重寫或隱藏。 (3) 用final修飾的變量表示常量,只能被賦值一次。 (4) 父類中用private修飾的方法不能被子類的方法重寫,因此private類型的方法默認(rèn)是final類型的。,4.6.1 final類,繼承關(guān)系的弱點是打破封裝,子類能夠訪問父類的實現(xiàn)細(xì)節(jié),而且能以方法重寫的方式改變實現(xiàn)細(xì)節(jié)。在以下情況下。可以考慮把類設(shè)計為final類型,使得這個類不能被繼承。 (1) 不是專門為繼承而設(shè)計的類,類本身的方法之
17、間有復(fù)雜的調(diào)用關(guān)系。如果隨意創(chuàng)建這些類的子類,子類有可能錯誤地修改父類的實現(xiàn)細(xì)節(jié)。 (2) 出于安全的原因,類的實現(xiàn)細(xì)節(jié)不允許有任何改動。 (3) 在創(chuàng)建對象模型時,確信這個類不會再被擴展。例如java.lang.String類是final類。,4.6.1 final類,【例4.9】定義類T為final類。 TestFinal.java final class T int i = 3; int j = 6; void f() System.out.println(i+j); public class TestFinal public static void main(String args)
18、T n = new T(); n.f(); n.i = 20; n.j+; 程序運行結(jié)果: 9,4.6.2 final方法,假如父類允許子類繼承父類的某些方法或重寫某些方法,但保留某些方法,使得這些方法不能被子類繼承,那么父類可以將這些方法聲明為final類型。例如在java.lang.Object類中,getClass()方法為final類型,而equals()方法不是final類型。 如果父類的某個方法是private,子類將無法繼承該方法,自然也就無法重寫或隱藏該方法。 【例4.10】分別在Parent類中定義不同訪問權(quán)限的final方法。 程序運行結(jié)果: Son.method1() P
19、arent.method2() Son.method3(),4.6.3 final變量,一個變量被限定為final,其實是將它定義為一個符號常量。例如,在類ConstValue中定義了三個final變量,如下所示。 class ConstValue final int CONST1 = 10; static final int CONST2 = 20; public static final int CONST3 = 30; final變量具有以下特點: (1) final修飾符可以修飾靜態(tài)變量、實例變量和局部變量,分別表示靜態(tài)常量、實例常量和局部常量。 【例4.11】使用靜態(tài)常量、實例常量和
20、局部常量。,4.6.3 final變量,(2) final成員變量應(yīng)該顯式初始化,否則final類型的實例變量會導(dǎo)致編譯錯誤。對于final類型的實例變量可以先聲明,不必立即賦值,這時又叫空白final,可以在構(gòu)造方法中或?qū)ο蟮某跏蓟瘔K中對它進行初始化。對于final類型的靜態(tài)變量,可以在定義變量時進行初始化,也可以在靜態(tài)初始化塊中進行初始化,若沒有顯式初始化,則系統(tǒng)自動初始化為默認(rèn)值,并且final類型變量只能被賦值一次,即使兩次賦值的值相同也不行,例如,在下面的代碼片段中試圖對final類型的變量賦值兩次。 public class FinalInitialize final int a
21、= 1; / 合法,final變量被顯式初始化 final int b; / 編譯出錯,因為后邊沒有對b進行顯式初始化 final int c; / 空白final final static int d = 9;/ 靜態(tài)final變量被顯式初始化 / 靜態(tài)final變量f沒有顯式初始化,則int類型的f值的默認(rèn)值是0 final static int f ; FinalInitialize() a = 1; / 編譯出錯,final變量只能被賦值一次 c = 5; / 空白final在構(gòu)造器中得到初始化 ,4.7 權(quán)限修飾符,1private訪問權(quán)限 如果一個成員方法或成員變量使用了priva
22、te訪問控制符,那么這個成員只能在這個類的內(nèi)部使用,其他類不能訪問。 2默認(rèn)訪問權(quán)限 如果一個成員方法或成員變量沒有使用任何訪問控制符,就稱這個成員是默認(rèn)的或者包類型的。對于默認(rèn)的訪問控制成員,可以被這個包中的其他類訪問。位于同一個包中的子類可以訪問父類中的默認(rèn)訪問控制成員。但如果子類與父類位于不同的包中,子類則不能訪問父類中的默認(rèn)訪問控制成員。 3受保護的訪問權(quán)限 如果一個成員方法或成員變量前使用了protected訪問控制符,那么這個成員既可以被同一個包中的其他類訪問,也可以被位于不同包繼承此父類的子類訪問,但不能被不同包的類訪問。 4公有的訪問權(quán)限 如果一個成員方法或成員變量前使用了pu
23、blic訪問控制符,那么這個成員可以被所有的類訪問,不管訪問類與被訪問的類是否位于同一個包中,以及是否有繼承關(guān)系。,4.7.1 類內(nèi)部,在一個類的內(nèi)部,其定義的四種不同的成員變量和成員方法,在整個類中都是可見的。 【例4.12】定義四種不同的成員變量和方法。,4.7.2 同一個包的類,除了private類型的所有成員變量和成員方法,一個類可以訪問位于同一個包中的另一個類中的成員變量和成員方法。 【例4.13】訪問位于同一個包中的其他類的成員變量和成員方法。,4.7.3 不同包的子類,如果類B繼承位于不同包的類A,那么類B只能訪問類A中protected與public類型的成員變量和成員方法,不
24、能訪問類A中private與default類型的成員變量和成員方法。 【例4.14】訪問不同包的子類的成員變量和方法。,4.7.4 通用性,如果類B與類A位于不同包,并且兩者之間并沒有繼承關(guān)系,那么類B只能訪問類A中public類型的成員變量和成員方法,其他類型的都不能訪問。 【例4.15】訪問不同包的類的成員變量和方法。 TestAccess4.java package org.approach2; import org.approach1.TestAccess1; public class TestAccess4 public static void main(String args) T
25、estAccess1 access1 = new TestAccess1(); /System.out.println(access1.var1); /System.out.println(access1.var2); /System.out.println(access1.var3); System.out.println(access1.var4); /access1.f1(); /access1.f2(); /access1.f3(); access1.f4(); ,4.7.4 通用性,程序的運行結(jié)果: public variable public method 現(xiàn)在對以上情況進行歸納,
26、如表4.1所示。,表4.1 權(quán)限修飾符,4.7.5 訪問權(quán)限與繼承,父類中哪些成員能夠被子類繼承?其遵循如下規(guī)則: (1) 構(gòu)造方法是不能被繼承的。 (2) private修飾的成員是不能被繼承的。 (3) 默認(rèn)訪問權(quán)限的成員,可能被繼承,也可能不能被繼承。當(dāng)子類與父類處于同一包中時,這些成員會被繼承,當(dāng)子類與父類處于不同包時,這些成員不能被繼承。 (4) protected與public修飾的成員總是能被繼承的。 (5) 能被子類訪問的成員,才會被子類繼承。 (6) 能被子類繼承的實例方法,才會被子類重寫或重載。 (7) 能被子類繼承的static方法,才會被子類隱藏或重載。 (8) 能被子
27、類繼承的數(shù)據(jù)成員,才會被子類隱藏。,4.8 綜合實例:航班管理,某航空公司對航班進行管理,管理控制臺用如下幾條命令進行管理: 命令:create命令 格式:create 功能:創(chuàng)建一個航班。 命令2:reserve命令 格式:reserve 功能:旅客預(yù)訂座位,返回預(yù)訂號。要求:同一批的旅客必須安排在同一排且座位相鄰,每一位旅客返回一個預(yù)訂號。預(yù)訂號自已定義,只要不重號即可。若安排不下(條件不能滿足),則顯示反饋信息。 命令3:Cancel命令 格式:Cancel 功能:取消預(yù)訂 命令:list命令 格式:list 功能:顯示座位預(yù)訂情況 命令:exit命令 功能:退出程序。,4.8 綜合實例
28、:航班管理,實現(xiàn)上述功能需要定義2個接口和3個類,兩個接口分別是旅客接口和航班接口,三個類分別是旅客接口的實現(xiàn)類、航班接口的實現(xiàn)類和用戶界面操作類。 (1)定義旅客接口PassengerInterface.java package plane; public interface PassengerInterface public String getName();/ 獲取姓名 public int getBookingNumber();/ 獲取預(yù)訂號 public int getRow();/ 獲取座位排數(shù) public int getSeatPosition(); / 獲取座
29、位號 (2)實現(xiàn)該接口的旅客類Passenger.java,4.8 綜合實例:航班管理,(3)定義航班接口PassengerInterface.java package plane; public interface PassengerInterface public String getName(); public int getBookingNumber(); public int getRow(); public int getSeatPosition(); 實現(xiàn)航班接口的航班類Flight.java 在航班類中,要實現(xiàn)創(chuàng)建座位、完成客戶座位的預(yù)訂和取消座位的預(yù)訂。航班類
30、的源程序。 其中: 創(chuàng)建航班座位 passengerList =new Passengerrow * rowLength; 預(yù)訂航班座位,4.8 綜合實例:航班管理,取消預(yù)訂航班座位 public boolean cancel(int bookingNumber) boolean Status = false; for (int i = 0; i row * rowLength; i+) if (passengerListi != null 用戶航班命令輸入和處理Client.java。 在Client.java中,能夠?qū)刂婆_輸入的命令進行分析并且進行相應(yīng)的處理,命令功能包括客戶預(yù)訂航班座位
31、、取消航班預(yù)訂和客戶尋求幫助。源程序。 其中: 對控制臺輸入的指令進行分析,4.8 綜合實例:航班管理,客戶預(yù)訂航班座位 private void reserveCommand(String cmds) / 用戶名放在cmds1,cmds2,. if (cmds.length = 1) System.out.println(reserve command error!); return; String names = new Stringcmds.length - 1; for (int i = 0; i names.length; i+) namesi = new String(cmdsi + 1); int bn = flight.reserve(name
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 私立醫(yī)院內(nèi)部財務(wù)制度
- 鐵路施工企業(yè)財務(wù)制度
- 設(shè)計師財務(wù)制度
- 商業(yè)保理財務(wù)制度
- 劉中八年級分班制度
- 關(guān)于軟件修改制度
- 公司內(nèi)部部門制度
- 養(yǎng)老院老人康復(fù)理療師表彰制度
- 養(yǎng)老院老人健康飲食營養(yǎng)師職業(yè)道德制度
- 施工現(xiàn)場施工防化學(xué)事故傷害制度
- 2020年高考中考考試工作經(jīng)費項目績效評價報告
- 包裝12二片罐、三片罐
- 倉庫貨物擺放標(biāo)準(zhǔn)培訓(xùn)課件
- 2023年運動控制工程師年度總結(jié)及下一年展望
- 江蘇省高級人民法院勞動爭議案件審理指南
- 低蛋白血癥的護理查房知識ppt
- 2023自愿離婚協(xié)議書范文(3篇)
- 眼科常見疾病診療規(guī)范診療指南2022版
- 30以內(nèi)加法運算有進位1000題1
- 戰(zhàn)略成本1-6章toc經(jīng)典案例
- 新藥臨床使用觀察表
評論
0/150
提交評論