|
第十天 面向?qū)ο?繼承&抽象類【悟空教程】 第10天 面向?qū)ο?/span> 繼承是面向?qū)ο蟮暮诵奶匦?,是面向?qū)ο蟮膶W(xué)習(xí)重點(diǎn)。同時(shí)繼承是代碼復(fù)用的重要方式,可以表示類與類之間的關(guān)系,是所有面向?qū)ο笳Z(yǔ)言不可缺少的組成部分。 當(dāng)一個(gè)類的屬性與行為均與現(xiàn)有類相似,屬于現(xiàn)有類的一種時(shí),這一個(gè)類可以定義為現(xiàn)有類的子類。 或者換成相反的角度來(lái)看,如果多個(gè)類具有相同的屬性和行為,我們可以抽取出共性的內(nèi)容定義父類,這時(shí)再創(chuàng)建相似的類時(shí)只要繼承父類即可。 子類擁有父類的所有屬性與方法,無(wú)需重新定義。并且可以直接使用非私有的父類成員。 從類與類之間的設(shè)計(jì)關(guān)系來(lái)看,子類必須屬于父類的一種時(shí),才會(huì)繼承。 我們?cè)谕瓿梢粋€(gè)龐大項(xiàng)目體系的時(shí)候,都是將共性的內(nèi)容抽取出,后續(xù)構(gòu)建過(guò)程是從各種父類“向外”擴(kuò)散的。 下例展示了一個(gè)繼承關(guān)系 圖1-1 動(dòng)物繼承關(guān)系圖 動(dòng)物類可以有姓名、年齡的成員變量,可以有吃飯、睡覺的方法。 所有貓科與犬科均有動(dòng)物的成員變量與成員方法,且貓科與犬科均屬于動(dòng)物,所以貓科與全科均可以繼承動(dòng)物類。 貓科可以在動(dòng)物的基礎(chǔ)上再添加抓老鼠的方法 犬科可以在動(dòng)物的基礎(chǔ)上再添加看門的方法 犬科與貓科仍可以繼續(xù)出現(xiàn)子類,如波斯貓、巴厘貓、沙皮狗、斑點(diǎn)狗等,而其子類仍可以再出現(xiàn)該品種的特性。 class 子類 extends 父類{ //父類的非私有方法與屬性均繼承過(guò)來(lái) } 如: 父類的定義: class Person{ private String name; public void eat(){ System.out.println(“吃飯”); } get/set方法 } 子類繼承父類的定義: class Chinese extends Person{} 繼承關(guān)系的產(chǎn)生通常是為了定義出功能更為具體、更為強(qiáng)大的子類。所以,定義子類后,一般創(chuàng)建子類對(duì)象使用。子類可以直接使用父類非私有的成員變量與成員方法 (注:如果成員變量沒有使用private修飾,則子類也可直接訪問(wèn)。) 子類的使用: class Test{ public static void main(String[] args) { Chinese c = new Chinese(); c.setName(“張大力”); String name = c.getName(); System.out.println(name);//打印結(jié)果為張大力 c.eat(); //打印結(jié)果吃飯 } Java只支持單繼承,不支持多繼承。即只能有一個(gè)父類。 父類可以繼續(xù)有父類。 所有類均有父類,只有Object類沒有父類。 在所有使用父類類型的地方均可以傳入其子類對(duì)象。 /* * Animal的類 * 屬性 * name * age * 行為 * 吃 * 睡 */ public abstract class Animal { //成員變量 private String name; private int age; // //吃 // public abstract void eat(); //睡 public void sleep(){ System.out.println("睡"); } //-----------get/set------------------- public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } /* *定義一個(gè)貓類 * 屬性 * name * age * kind * 行為 * 吃 * 睡 * 抓老鼠 */ public class Cat extends Animal{ private String kind; // @Override // public void eat(){ // System.out.println("貓吃魚"); // } //貓?zhí)赜械墓δ? 抓老鼠 public void catchMouse(){ System.out.println("抓耗子"); } public String getKind() { return kind; } public void setKind(String kind) { this.kind = kind; } } /* *定義一個(gè)狗類 * 屬性 * name * age * kind * 行為 * 吃 * 睡 * 看門 */ public class Dog extends Animal{ private String kind; // @Override // public void eat(){ // System.out.println("狗吃肉"); // } //狗特有功能 看門 public void lookDoor(){ System.out.println("看門"); } public String getKind() { return kind; } public void setKind(String kind) { this.kind = kind; } } /* * 自定義類型 家 * * 地址 * * 行為 * 在家吃飯 */ public class Home { private String address; //動(dòng)物在家吃飯 //在所有使用父類類型的地方均可以傳入其子類對(duì)象。 public void eatAtHome(Animal a){ //調(diào)用Animal的eat方法 //a.eat(); } //狗在在家吃飯 // public void eatAtHome(Dog dog){ // System.out.println("狗在家吃了"); // //調(diào)用狗的eat方法 // dog.eat(); // } //貓?jiān)诩页燥?/span> // public void eatAtHome(Cat cat){ // System.out.println("貓?jiān)诩俪粤?/span>"); // //調(diào)用貓的eat方法 // cat.eat(); // } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } } /** * 測(cè)試家類 */ public class Test { public static void main(String[] args) { // 創(chuàng)建Home對(duì)象 Home home = new Home(); // Animal a = new Animal(); // home.eatAtHome(a); //在所有使用父類類型的地方均可以傳入其子類對(duì)象。 Dog d = new Dog(); home.eatAtHome(d); Cat c = new Cat(); home.eatAtHome(c); } } 當(dāng)子類繼承父類后,擁有了父類的成員并可以直接調(diào)用父類非私有方法。如果子類認(rèn)為父類提供的方法不夠強(qiáng)大,子類可以按照子類自身的邏輯重新定義繼承過(guò)來(lái)的父類方法,這個(gè)重新定義一個(gè)方法的過(guò)程叫做方法重寫。 (注:在學(xué)習(xí)完多態(tài)和抽象類后我們會(huì)對(duì)方法重寫有更深的理解) 子類中定義與父類一樣的方法便將父類的方法重寫了。此時(shí),當(dāng)創(chuàng)建子類對(duì)象,調(diào)用方法時(shí),會(huì)調(diào)用子類重寫后的方法。如: 子類中定義與父類一樣的方法聲明即是方法重寫。 如: 父類定義: public class Person{ private String name; public void eat(){ System.out.println(“吃飯”); } get/set } 子類定義: public class Chinese extends Person{ @override //@override是用于強(qiáng)制規(guī)定當(dāng)前定義的方法一定為重寫的方法 public void eat() { System.out.println(“按照中國(guó)的習(xí)慣,使用筷子吃”); } } 子類的使用: public class Test{ public static void main(String[] args) { Chinese c = new Chinese(); c.setName(“張大力”); //父類繼承方法直接調(diào)用 String name = c.getName(); //父類繼承方法直接調(diào)用 System.out.println(name); //打印結(jié)果為張大力 c.eat(); //方法重寫后調(diào)用的為重寫后的方法 //打印結(jié)果:按照中國(guó)的習(xí)慣,使用筷子吃 } } /** * 自定義類型 人類 * * 姓名 年齡 */ public class Person { String address; private String name; private int age; public void eat(){ System.out.println("吃"); } public void sleep(){ System.out.println("睡"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } /* * 定義類型 學(xué)生類 * * 姓名 年齡 * * 繼承 * 概念1 當(dāng)定義一個(gè)類時(shí),發(fā)現(xiàn)現(xiàn)有類與要定義的類類似,并且要定義的類屬于現(xiàn)有類的一種時(shí), * 就可以將這個(gè)類定義為現(xiàn)有類的子類 * * 子類擁有父類的所有屬性與方法,無(wú)需重新定義。并且可以直接使用非私有的父類成員。 * * 父類私用的成員變量 可以使用get/set方法 訪問(wèn) * 父類私有的方法 沒有辦法直接方法 雖然繼承了 但是相當(dāng)于沒有 * * 子類可以有自己特有的屬性和方法 * * 方法重寫 * 子類繼承父類后,可以直接使用父類的非私有成員,但是如果覺得父類的成員方法不夠強(qiáng)大,子類可以按照自身的邏輯 * 將繼承過(guò)來(lái)的父類方法,進(jìn)行重寫(方法重寫,方法復(fù)寫,方法覆蓋) * * 可以使用@Override來(lái)驗(yàn)證你的方法是不是重寫方法。 */ public class Student extends Person{ private String number; public void method(){ System.out.println(address); System.out.println(getName()); } //重寫父類eat方法 @Override public void eat(){ System.out.println("學(xué)生吃學(xué)生套餐"); } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } } /* * 測(cè)試?yán)^承后的Studnet */ public class Test { public static void main(String[] args) { //創(chuàng)建Studnet對(duì)象 Student s = new Student(); s.setName("柳柳"); s.setNumber("0900112"); s.eat(); // s.sleep(); String name = s.getName(); System.out.println(name); System.out.println(s.getNumber()); System.out.println("-----------------"); //子類調(diào)用自己特有的方法 s.method(); } } 子類重寫方法時(shí),在聲明前加@Override可檢測(cè)該方法是否為重寫的方法 訪問(wèn)權(quán)限相同或子類方法訪問(wèn)權(quán)限更大(訪問(wèn)權(quán)限順序public>默認(rèn)) class Fu{ void show(){} public void method(){} } class Zi extends Fu{ public void show(){} //編譯運(yùn)行沒問(wèn)題 void method(){} //編譯錯(cuò)誤 } 方法名稱必須相同 參數(shù)列表必須相同 返回值為基本類型時(shí)必須相同 返回值為引用類型時(shí)相同或子類小(了解) /* * 方法重寫的注意事項(xiàng) * 子類重寫方法時(shí),在聲明前加@Override可檢測(cè)該方法是否為重寫的方法 * 訪問(wèn)權(quán)限相同或子類方法訪問(wèn)權(quán)限更大(訪問(wèn)權(quán)限順序public>默認(rèn)) * 方法名稱必須相同 * 參數(shù)列表必須相同 * 返回值為基本類型時(shí)必須相同 * 返回值為引用類型時(shí)相同或子類小(了解) */ public class Fu { public void method(){ System.out.println(" 父類方法"); } public int sum(){ return 0; } public Person get(){ return null; } } public class Zi extends Fu{ //訪問(wèn)權(quán)限相同或子類方法訪問(wèn)權(quán)限更大(訪問(wèn)權(quán)限順序public>默認(rèn)) @Override public void method(){ System.out.println("子類方法"); } //返回值為基本類型時(shí)必須相同 @Override public int sum(){ return 100; } //返回值為引用類型時(shí)相同或子類小(了解) @Override public Student get(){ return null; } } 抽象類用來(lái)描述一種類型應(yīng)該具備的基本特征與功能, 具體如何去完成這些行為由子類通過(guò)方法重寫來(lái)完成,如: 犬科均會(huì)吼叫,但屬于犬科的狼與狗其吼叫內(nèi)容不同。所以犬科規(guī)定了有吼叫功能,但并不明確吼叫的細(xì)節(jié)。吼叫的細(xì)節(jié)應(yīng)該由狼與狗這樣的犬科子類重寫吼叫的方法具體實(shí)現(xiàn)。 類似上邊犬科中的吼叫功能,并不明確實(shí)現(xiàn)細(xì)節(jié)但又需要聲明的方法可以使用抽象方法的方式完成。即抽象方法指只有功能聲明,沒有功能主體實(shí)現(xiàn)的方法。 具有抽象方法的類一定為抽象類。 那么犬科就可以定義為抽象類,吼叫方法為抽象方法,沒有方法體。 抽象類定義的格式: abstract在class前修飾類: abstract class 類名 { } 抽象方法定義的格式: abstract在訪問(wèn)權(quán)限后,返回值類型前修飾方法,方法沒有方法體: public abstract 返回值類型 方法名(參數(shù)); 看如下代碼: //員工 abstract class Employee{ public abstract void work();//抽象函數(shù)。需要abstract修飾,并分號(hào);結(jié)束 } //講師 class Teacher extends Employee { public void work() { System.out.println("正在講解Java"); } } //助教 class Assistant extends Employee { public void work() { System.out.println("正在輔導(dǎo)學(xué)生"); } } //班主任 class Manager extends Employee { public void work() { System.out.println("正在管理班級(jí)"); } } 抽象類無(wú)法直接創(chuàng)建對(duì)象,只能被子類繼承后,創(chuàng)建子類對(duì)象。 子類需要繼承抽象父類并完成最終的方法實(shí)現(xiàn)細(xì)節(jié)(即重寫方法,完成方法體)。而此時(shí),方法重寫不再是加強(qiáng)父類方法功能,而是父類沒有具體實(shí)現(xiàn),子類完成了具體實(shí)現(xiàn),我們將這種方法重寫也叫做實(shí)現(xiàn)方法。 抽象類的意義 抽象類往往用來(lái)表示對(duì)問(wèn)題領(lǐng)域進(jìn)行分析、設(shè)計(jì)中得出的抽象概念。其存在的意義在于其設(shè)計(jì)性、復(fù)用性與擴(kuò)展性。 抽象類方便了具體類的定義。 抽象類僅是對(duì)功能和屬性的聲明,表示這類事物應(yīng)該具備這些內(nèi)容。限制程序員不能直接創(chuàng)建該抽象類對(duì)象,必須定義其子類才可使用。如我們可以聽一只狼的叫聲,也可以聽一只狗的叫聲,但是如果我們聽一只犬科的叫聲就顯然不合適了。 抽象類繼承細(xì)節(jié) 只有覆蓋了抽象類中所有的抽象方法后,其子類才可以實(shí)例化。如果存留未實(shí)現(xiàn)的抽象方法則該子類仍為一個(gè)抽象類,無(wú)法創(chuàng)建對(duì)象。 抽象類不一定包含抽象方法。 抽象類可以有非抽象方法。 /* * 犬科 * * 行為 * 吼叫 */ public abstract class Quan { public abstract void houJiao(); public abstract void sleep(); public void eat(){ System.out.println("吃"); } } /* * 抽象類的注意事項(xiàng): * 子類必須重寫父類的所有抽象方法,如果有抽象方法沒有重寫,就相當(dāng)于將抽象方法繼承過(guò)來(lái),子類里面有抽象方法, * 有抽象方法的類必須是抽象類,子類也得定義為抽象類 * * 抽象類不一定包含抽象方法。 * 抽象類可以有非抽象方法。 */ public class Dog extends Quan{ public void eat(){ System.out.println("狗吃肉"); } @Override public void houJiao() { System.out.println("狗汪汪叫!"); } @Override public void sleep() { System.out.println("趴著睡"); } } public class Test { public static void main(String[] args) { //抽象類不能創(chuàng)建對(duì)象 //Quan q = new Quan(); //可以創(chuàng)建子類對(duì)象 Dog d = new Dog(); d.houJiao(); } } 題目要求: 設(shè)計(jì)抽象父類與具體子類。 動(dòng)物類: 屬性:年齡、姓名 方法:吃飯、睡覺 貓科類: 動(dòng)物類基礎(chǔ)上添加產(chǎn)地 添加抓老鼠的方法 波斯貓、巴厘貓、卡通貓與貓科類類似 犬科: 與貓科類類似 對(duì)于動(dòng)物類與犬科貓科,均為抽象的概念,規(guī)定了該種類型體系中所應(yīng)該具備的通用基本功能與屬性。而實(shí)際生產(chǎn)中不會(huì)創(chuàng)建動(dòng)物、犬科、貓科的對(duì)象,而會(huì)使用更為具體的實(shí)現(xiàn)類對(duì)象。 定義抽象類動(dòng)物、犬科、貓科。 定義該三種類型的具體子類。 在測(cè)試類中,測(cè)試子類屬性與子類方法。 /* * 自定義數(shù)據(jù)類型 動(dòng)物類 * * 屬性 * 年齡 姓名 * 行為 * 吃飯 睡覺 */ public abstract class Animal { private String name; private int age; //吃 public abstract void eat(); //睡 public abstract void sleep(); public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public abstract class Cat extends Animal{ private String address; public void catchMouse(){ System.out.println("抓老鼠!"); } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } } public class KTCat extends Cat{ @Override public void eat() { System.out.println("卡通貓吃卡通魚!"); } @Override public void sleep() { System.out.println("卡通貓站著睡"); } } public class Test { public static void main(String[] args) { KTCat kt = new KTCat(); kt.setName("kitty"); kt.setAge(2); kt.eat(); kt.sleep(); kt.catchMouse(); System.out.println(kt.getName()); System.out.println(kt.getAge());; } } 繼承是面向?qū)ο笞铒@著的一個(gè)特性。繼承是從已有的類中派生出新的類,新的類能吸收已有類的數(shù)據(jù)屬性和行為,并能擴(kuò)展新的能力。Java繼承是使用已存在的類的定義作為基礎(chǔ)建立新類的技術(shù),新類的定義可以增加新的數(shù)據(jù)或新的功能,也可以用父類的功能,但不能選擇性地繼承父類。這種技術(shù)使得復(fù)用以前的代碼非常容易,能夠大大縮短開發(fā)周期,降低開發(fā)費(fèi)用。 好處: (1)繼承關(guān)系是傳遞的。若類C繼承類B,類B繼承類A(多層繼承),則類C既有從類B那里繼承下來(lái)的屬性與方法,也有從類A那里繼承下來(lái)的屬性與方法,還可以有自己新定義的屬性和方法。繼承來(lái)的屬性和方法盡管是隱式的,但仍是類C的屬性和方法。繼承是在一些比較一般的類的基礎(chǔ)上構(gòu)造、建立和擴(kuò)充新類的最有效的手段。 (2)繼承簡(jiǎn)化了人們對(duì)事物的認(rèn)識(shí)和描述,能清晰體現(xiàn)相關(guān)類間的層次結(jié)構(gòu)關(guān)系。 (3)繼承提供了軟件復(fù)用功能。若類B繼承類A,那么建立類B時(shí)只需要再描述與基類(類A)不同的少量特征(數(shù)據(jù)成員和成員方法)即可。這種做法能減小代碼和數(shù)據(jù)的冗余度,大大增加程序的重用性。 (4)繼承通過(guò)增強(qiáng)一致性來(lái)減少模塊間的接口和界面,大大增加了程序的易維護(hù)性。 (5)提供多重繼承機(jī)制。從理論上說(shuō),一個(gè)類可以是多個(gè)一般類的特殊類,它可以從多個(gè)一般類中繼承屬性與方法,這便是多重繼承。Java出于安全性和可靠性的考慮,僅支持單重繼承,而通過(guò)使用接口機(jī)制來(lái)實(shí)現(xiàn)多重繼承。 1.關(guān)于私有成員變量 無(wú)論父類中的成員變量是pirvate、public、還是其它類型的,子類都會(huì)擁有(繼承)父類中的這些成員變量。但是父類中的私有成員變量,無(wú)法在子類中直接訪問(wèn),可以通過(guò)從父類中繼承得到的protected、public方法(如getter、setter方法)來(lái)訪問(wèn)。 個(gè)人認(rèn)為這更好的提現(xiàn)了JAVA特性中的封裝,而且符合軟件工程的設(shè)計(jì)思想:低耦合 2. 關(guān)于靜態(tài)成員變量 無(wú)論父類中的成員變量是靜態(tài)的、還是非靜態(tài)的,子類都會(huì)擁有父類中的這些成員變量。 3. 關(guān)于被子類覆蓋的成員變量 無(wú)論父類中的成員變量是否被子類覆蓋,子類都會(huì)擁有父類中的這些成員變量。 抽象類中的非抽象方法不用重寫,其他必須重寫,接口的方法必須重寫; 接口和抽象類中只有方法名,沒有定義的,如果你不定義 也就是空方法,接口就是為了彌補(bǔ)java不能多重繼承,接口針對(duì)的是對(duì)象而不是實(shí)現(xiàn)。實(shí)現(xiàn)的部分可以交由對(duì)象去實(shí)現(xiàn)。這就是java中的多態(tài)啊。 方法重寫與方法重載不同,方法的重載是方法的參數(shù)個(gè)數(shù)或種類或順序不同,方法名相同。 方法重寫是要注意權(quán)限的問(wèn)題,子類中的權(quán)限不能小于父類的權(quán)限,當(dāng)父類的權(quán)限為private時(shí),子類無(wú)法繼承。也就無(wú)法產(chǎn)生所謂的重寫。(修飾符高低:private < 默認(rèn)修飾符 < public) java中的抽象方法就是以abstract修飾的方法,這種方法只聲明返回的數(shù)據(jù)類型、方法名稱和所需的參數(shù),沒有方法體,也就是說(shuō)抽象方法只需要聲明而不需要實(shí)現(xiàn)。 格式: abstract在訪問(wèn)權(quán)限后,返回值類型前修飾方法,方法沒有方法體: public abstract 返回值類型 方法名(參數(shù)); 作用: 抽象方法的作用是,你在此類里不必實(shí)現(xiàn)它,只是一個(gè)虛方法,所有的實(shí)現(xiàn)可以到繼承此類的子類里面去做.你也可以理解為,抽象方法就是用來(lái)被重載的方法.你可以在子類里對(duì)它進(jìn)行重載,也可以不進(jìn)行重載.舉個(gè)例就象定義了一個(gè)電器類,其中一個(gè)虛方法是顯示圖象.你用電視機(jī)繼承電器類的時(shí)候就把顯示圖象的方法實(shí)現(xiàn)為電視機(jī)的顯示方法,用mp4繼承電器類時(shí)就把這個(gè)虛方法實(shí)現(xiàn)為mp4自己的顯示方法.如果是用收音機(jī)類去繼承電器,你就可以不用實(shí)現(xiàn)這個(gè)方法. 抽象類的意義 抽象類往往用來(lái)表示對(duì)問(wèn)題領(lǐng)域進(jìn)行分析、設(shè)計(jì)中得出的抽象概念。其存在的意義在于其設(shè)計(jì)性、復(fù)用性與擴(kuò)展性。 抽象類方便了具體類的定義。 抽象類僅是對(duì)功能和屬性的聲明,表示這類事物應(yīng)該具備這些內(nèi)容。限制程序員不能直接創(chuàng)建該抽象類對(duì)象,必須定義其子類才可使用。如我們可以聽一只狼的叫聲,也可以聽一只狗的叫聲,但是如果我們聽一只犬科的叫聲就顯然不合適了。 經(jīng)理類: 姓名、年齡、薪水、獎(jiǎng)金 吃飯、工作內(nèi)容為管理員工,計(jì)算績(jī)效 人類: 姓名、年齡 吃飯 廚師類: 姓名、年齡、薪水、獎(jiǎng)金 吃飯、工作內(nèi)容炒菜 員工類 姓名、年齡、薪水 吃飯、工作 服務(wù)員類: 姓名、年齡、薪水、獎(jiǎng)金 吃飯、工作內(nèi)容端盤子 構(gòu)造器Constructor不能被繼承,因此不能重寫Override,但可以被重載Overload。 .//設(shè)有下面兩個(gè)類的定義。 class Person { long id; // 身份證號(hào) String name; // 姓名 } class Student extends Person{ int score; int getScore(){ return score; } } 則類Person和類Student的關(guān)系是? A.包含關(guān)系 B.繼承關(guān)系 C.關(guān)聯(lián)關(guān)系 D.上述類定義有語(yǔ)法錯(cuò)誤 答案:B A.子類繼承父類的所有屬性和方法 B.子類可以繼承父類的私有的屬性和方法 C子類可以繼承父類的公有的屬性和方法 D.創(chuàng)建子類對(duì)象時(shí),父類的構(gòu)造方法都要被執(zhí)行 答案:C A.一個(gè)子類可有多個(gè)父類 B.父類派生出子類 C.子類繼承父類 D.子類只能有一個(gè)父類 答案:A 要求: 編寫代碼,實(shí)現(xiàn)如下功能: (1)定義一個(gè)門類, 包含3個(gè)屬性:寬度width 和 高度height ,顏色color 包含2個(gè)方法:開門和關(guān)門 開門方法:輸出“門已經(jīng)打開,請(qǐng)進(jìn)!” 關(guān)門方法:輸出“門已經(jīng)關(guān)閉,禁止進(jìn)入!” (2)定義一個(gè)木頭門WOOD,繼承Door 重寫父類開門方法:輸出門的高度 寬度 顏色 +“門已經(jīng)打開,請(qǐng)進(jìn)!” 重寫父類關(guān)門方法:輸出門的高度 寬度 顏色 +“門已經(jīng)關(guān)閉,禁止進(jìn)入!” (3)定義一個(gè)測(cè)試類,測(cè)試類定義一個(gè)main方法 分別創(chuàng)建 門對(duì)象 和 木頭門對(duì)象, 為創(chuàng)建的木頭門對(duì)象屬性賦值, 調(diào)用開門和關(guān)門兩個(gè)方法。 答案: public class Demo { public static void main(String[] args) { //創(chuàng)建門對(duì)象 Door door = new Door(); // 調(diào)用方法 door.openDoor(); door.closeDoor(); // 創(chuàng)建木頭門對(duì)象 WoodDoor woodDoor = new WoodDoor(); //調(diào)用set方法對(duì)屬性賦值 woodDoor.setWidth(1.8); woodDoor.setHight(2.5); woodDoor.setColor("紅色"); // 調(diào)用方法 woodDoor.openDoor(); woodDoor.closeDoor(); } } class Door { // 定義屬性 private double width; private double hight; private String color; public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } public double getHight() { return hight; } public void setHight(double hight) { this.hight = hight; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } //開門方法 public void openDoor(){ System.out.println("門已經(jīng)打開,請(qǐng)進(jìn)!"); } //關(guān)門方法 public void closeDoor(){ System.out.println("門已經(jīng)關(guān)閉,禁止進(jìn)入!"); } } class WoodDoor extends Door{ //重寫開門方法 public void openDoor(){ System.out.println("門的寬度為:"+ getWidth() +",高度為:"+getHight()+",顏色:"+getColor()+",門已經(jīng)打開,請(qǐng)進(jìn)!"); } //關(guān)門方法 public void closeDoor(){ System.out.println("門的寬度為:"+ getWidth() +",高度為:"+getHight()+",顏色:"+getColor()+",門已經(jīng)關(guān)閉,禁止進(jìn)入!"); } } 要求: 1.定義動(dòng)物類,有名稱和年齡兩個(gè)屬性,且屬性私有化,提供相應(yīng)的getXxx與setXxx方法,提供無(wú)參數(shù)的無(wú)返回值的吃飯方法,內(nèi)容為:“吃飯...”; 2.定義貓類,繼承動(dòng)物類,重寫父類中的吃飯方法,內(nèi)容為:“貓吃魚...” 3.定義狗類,繼承動(dòng)物類,重寫父類中的吃飯方法,內(nèi)容為:“狗吃骨頭...” 4.定義測(cè)試類,分別創(chuàng)建貓對(duì)象和狗對(duì)象,并分別給父類對(duì)象中的名稱和年齡屬性賦值; 5.分別使用貓對(duì)象和狗對(duì)象獲取名稱和年齡的屬性值并打印在控制臺(tái)上; 6.分別使用貓對(duì)象和狗對(duì)象調(diào)用吃飯方法; 答案: /* * 動(dòng)物類: * 屬性: * 名稱 * 年齡 * 方法: * 吃飯方法 * getXxx與setXxx */ public class DongWu { //屬性 private String name; private int age; //getXxx與setXxx public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //吃飯方法 public void chiFan(){ System.out.println("吃飯..."); } } /* * 狗類繼承動(dòng)物類 */ public class Gou extends DongWu{ public void chiFan() { System.out.println("狗吃骨頭..."); } } /* * 貓類繼承動(dòng)物類: */ public class Mao extends DongWu{ //重寫吃飯的方法; public void chiFan() { System.out.println("貓吃魚..."); } } /* * 測(cè)試類 */ public class Test { public static void main(String[] args) { //1、分別創(chuàng)建貓對(duì)象和狗對(duì)象,并分別給父類對(duì)象中的名稱和年齡屬性賦值 Mao m = new Mao(); m.setName("波斯貓"); m.setAge(3); Gou g = new Gou(); g.setName("哈巴狗"); g.setAge(2); //2、分別使用貓對(duì)象和狗對(duì)象獲取名稱和年齡的屬性值并打印在控制臺(tái)上; String name = m.getName(); int age = m.getAge(); String name2 = g.getName(); int age2 = g.getAge(); System.out.println("貓的名字為:"+name+";年齡為:"+age); System.out.println("狗的名字為:"+name2+";年齡為:"+age2); //3、分別使用貓對(duì)象和狗對(duì)象調(diào)用吃飯方法 m.chiFan(); g.chiFan(); } } |
|
|