10_java之继承和抽象类
?01繼承的概述
*A:繼承的概念*a:繼承描述的是事物之間的所屬關系,通過繼承可以使多種事物之間形成一種關系體系*b:在Java中,類的繼承是指在一個現有類的基礎上去構建一個新的類,構建出來的新類被稱作子類,現有類被稱作父類*B:繼承關系的子類特點 *a:子類會自動擁有父類所有非private修飾的屬性和方法02繼承的定義格式和使用
*A:繼承的格式class 子類 extends 父類 {}*B:雇員(Employee)與研發部員工(Developer)案例:*cn.itcast.demo01包下:*Employee.java:/** 定義員工類Employee*/class Employee {String name; // 定義name屬性public void work() {// 定義員工的工作方法System.out.println("盡心盡力地工作");}}*Developer.java:/** 定義研發部員工類Developer 繼承 員工類Employee* 繼承了父類中所有非private修飾的成員變量*/class Developer extends Employee {// 定義一個打印name的方法public void printName() {System.out.println("name=" + name);}} *測試員工類與研發部員工類: /* 定義測試類*/
public class Example01 {
public static void main(String[] args) {Developer d = new Developer();// 創建一個研發部員工類對象 d.name = "小明"; // 為該員工類的name屬性進行賦值 d.printName();// 調用該員工的printName()方法 d.work();// 調用Developer類繼承來的work()方法 } }*通過子類對象既可以調用自身的非private修飾的成員,也可以調用父類的非private修飾的成員
03繼承的好處
*A:繼承的好處:*1、繼承的出現提高了代碼的復用性,提高軟件開發效率。*2、繼承的出現讓類與類之間產生了關系,提供了多態的前提。04繼承的注意事項
*A:繼承的注意事項 *a:在Java中,類只支持單繼承,不允許多繼承,也就是說一個類只能有一個直接父類,例如下面這種情況是不合法的。class A{} class B{}class C extends A,B{} // C類不可以同時繼承A類和B類 假如支持多繼承例如:class A{int a=3;public void method(){ ?}} class B{int a=5;public void method(){ ?}}class C extends A,B{} class Demo{public static void main(String[] args){C c=new C();System.out.println(c.a);//到底是調用A的還是B的成員變量??無法確定c.method();//到底是調用A的還是B的成員方法??無法確定 } } *b:多個類可以繼承一個父類,例如下面這種情況是允許的(就像你爹可以多個兒子,但是這些兒子都只有一個爹)class A{}class B extends A{}class C extends A{} // 類B和類C都可以繼承類A*c:在Java中,多層繼承是可以的,即一個類的父類可以再去繼承另外的父類,例如C類繼承自B類,而B類又可以去繼承A類,這時,C類也可稱作A類的子類。下面這種情況是允許的。class A{}class B extends A{} // 類B繼承類A,類B是類A的子類class C extends B{} // 類C繼承類B,類C是類B的子類,同時也是類A的子類*d:在Java中,子類和父類是一種相對概念, 也就是說一個類是某個類父類的同時,也可以是另一個類的子類。 例如上面的這種情況中,B類是A類的子類,同時又是C類的父類。05繼承的體系
*A:繼承的體系:動物(吃)|-------------------------| |貓科動物(吃,胎生) 爬行動物(吃,卵生)| |------------------------------- ----------------- | | | |貓(吃,抓老鼠,胎生) 虎(吃,領地,胎生) 蛇(吃,冬眠,卵生) 鱷魚(吃,潛水,卵生)*a:動物體系是對每個具體事物共性的抽取,子類的共性抽取形成父類*b:父類:具有所有子類的共性內容子類:不但有共性還有自身特有的內容*c:整個繼承體系,越向上越抽象,越向下越具體
06繼承后子類父類成員變量的特點
A:繼承后子類父類成員變量的特點a:子類的對象調用成員變量的時候,子類自己有,使用子類,子類自己沒有調用的父類class Fu{//Fu中的成員變量。int num = 5;}class Zi extends Fu{//Zi中的成員變量int num2 = 6;//Zi中的成員方法public void show(){//訪問父類中的numSystem.out.println("Fu num="+num);//訪問子類中的num2System.out.println("Zi num2="+num2);}}class Demo{public static void main(String[] args) {Zi z = new Zi(); //創建子類對象z.show(); //調用子類中的show方法 }}b:當子父類中出現了同名成員變量 class Fu{ //Fu中的成員變量。 int num = 5; }class Zi extends Fu{//Zi中的成員變量int num = 6;void show(){ //子類的局部變量int num=7//直接訪問,遵循就近查找原則System.out.println(num);//7//子父類中出現了同名的成員變量時//在子類中需要訪問父類中非私有成員變量時,需要使用super關鍵字//訪問父類中的numSystem.out.println("Fu num="+super.num);//5//訪問子類中的num2System.out.println("Zi num2="+this.num);//6 }}class Demo5 {public static void main(String[] args) {Zi z = new Zi(); //創建子類對象z.show(); //調用子類中的show方法 }}07繼承后子類父類成員方法的特性_子類重寫父類方法
A:繼承后子類父類成員方法的特性a:子類的對象調用方法的時候,子類自己有,使用子類,子類自己沒有調用的父類class Fu{public void show(){System.out.println("Fu類中的show方法執行");}}class Zi extends Fu{public void show2(){System.out.println("Zi類中的show2方法執行");}}public class Test{public static void main(String[] args) {Zi z = new Zi();z.show(); //子類中沒有show方法,但是可以找到父類方法去執行 z.show2();}} b:為什么要有重寫?class Fu{public void method(){//上千行代碼//Fu類中的方法最先存在,那么如果項目需求變了,該方法//功能不能夠滿足我們的需求,此時我們也不會去改這個方法//因為項目中可能有大量的功能已經使用到該方法,如果隨意修改可能使調用該方法的功能出現問題//所以使用重寫方式基于原有功能提供更強的功能 } }class Zi extends Fu{}c:子類中出現與父類一模一樣的方法時,會出現覆蓋操作,也稱為override重寫、復寫或者覆蓋class Fu{public void show(){System.out.println("Fu show");}}class Zi extends Fu{//子類復寫了父類的show方法public void show(){System.out.println("Zi show");}}public class Test{public static void main(String[] args) {Zi z = new Zi();z.show(); //Zi show 子類有直接使用子類 }}?
08方法覆蓋的需求
A:方法覆蓋的需求 a:案例:比如手機,當描述一個手機時,它具有發短信,打電話,顯示來電號碼功能,后期由于手機需要在來電顯示功能中增加顯示姓名和頭像,這時可以重新定義一個類描述智能手機,并繼承原有描述手機的類。并在新定義的類中覆蓋來電顯示功能,在其中增加顯示姓名和頭像功能 ?b:分析:我們不改裝(破壞)原來的手機,而是再買一個新的智能手機,不但有原有的功能,而且還有特有功能例:廠商發布新手機都是基于原有手機的升級,不會拿著原有的手機在賣,新產一款 1:分析類的構建:手機類屬性(成員變量):無行為(成員方法):發短信打電話來電顯示:顯示來電號碼智能手機類:屬性(成員變量):無行為(成員方法):發短信打電話來電顯示:顯示來電號碼,顯示姓名和頭像手機類和智能手機類有共性內容:發短信打電話顯示來電號碼2:繼承關系分析:對于發短信和打電話功能,讓智能手機直接沿用(繼承)手機的就可以但是在智能手機中的來電顯示不但實現號碼,還顯示姓名和頭像,同樣的都是來電顯示功能,智能手機的來電顯示比手機的功能更加強大,我們考慮使用重寫09方法覆蓋的手機案例實現
//手機類class Phone{public void sendMessage(){System.out.println("發短信");}public void call(){System.out.println("打電話");}public void showNum(){System.out.println("來電顯示號碼");}} ?//智能手機類class NewPhone extends Phone{//覆蓋父類的來電顯示號碼功能,并增加自己的顯示姓名和圖片功能//從現實生活角度考慮沿用原有的showNum方法名便于用戶更快熟悉和接受,而不是再起個新的名字//用戶還需要花費大量時間慢慢接受public void showNum(){//調用父類已經存在的功能使用super//如果不加super這是調用子類自身的showNum(),自己調用自己,遞歸//方法不斷入棧導致內存溢出super.showNum();//增加自己特有顯示姓名和圖片功能System.out.println("顯示來電姓名");System.out.println("顯示頭像");}} ?public class Test {public static void main(String[] args) {new NewPhone().showNum();//來電顯示 顯示來電姓名 顯示頭像 }}10方法覆蓋的注意事項
A:方法覆蓋的注意事項a:權限:子類方法覆蓋父類方法,必須要保證權限大于等于父類權限。 四大權限:public>默認=protected>privateclass Fu{ void show(){ ?}public void method(){ ?}}class Zi() extends Fu{public void show(){//編譯運行沒問題 ?} void method(){//編譯錯誤 ?} }b:方法定義:子類方法和要重寫的父類的方法:方法的方法名和參數列表都要一樣。關于方法的返回值:如果是基本數據類型,子類的方法和重寫的父類的方法返回值類型必須相同如果是引用數據類型,子類的方法和重寫的父類的方法返回值類型可以相同或者子類方法的返回值類型是父類方法返回值類型的子類class Fu{ int show(){ ?}public Fu method(){ ?}public Fu method2(){ ?}}class Zi() extends Fu{public int show(){//返回值為基本類型的重寫 ?} public Fu method(){//子類的方法和重寫的父類的方法返回值類型可以相同 ?} public Zi method2(){//子類方法的返回值類型是父類方法返回值類型的子類 ?} }c:重載與重寫對比:重載:權限修飾符(public private 默認):無關方法名:重載的兩個方法的方法名必須相同形參列表:形參類型的順序不同形參的個數不同形參的類型不同三者至少滿足一個返回值類型:重載與返回值類型無關重寫:權限修飾符(public private 默認): 子類方法的權限>=父類的方法的權限方法名: 子類方法和父類方法必須相同形參列表: 子類方法和父類方法的形參列表必須相同返回值類型:基本類數據類型:必須相同引用數據類型:子類方法的返回值類型和父類方法的返回值類型相同或者子類方法的返回值類型是父類方法的返回值類型的 子類
11抽象類的產生
A:抽象類的產生a:分析事物時,發現了共性內容,就出現向上抽取。會有這樣一種特殊情況,就是方法功能聲明相同,但方法功能主體不同。那么這時也可以抽取,但只抽取方法聲明,不抽取方法主體。那么此方法就是一個抽象方法。
12抽象類的定義格式
A:抽象方法定義的格式:a:public abstract 返回值類型 方法名(參數);抽象類定義的格式:abstract class 類名 {}b:抽象類示例代碼:/** 定義類開發工程師類* EE開發工程師 : 工作* Android開發工程師 : 工作* * 根據共性進行抽取,然后形成一個父類Develop* 定義方法,工作: 怎么工作,具體干什么呀* * 抽象類,不能實例化對象, 不能new的* 不能創建對象的原因: 如果真的讓你new了, 對象.調用抽象方法,抽象方法沒有主體,根本就不能運行* 抽象類使用: 定義類繼承抽象類,將抽象方法進行重寫,創建子類的對象*/public abstract class Develop {//定義方法工作方法,但是怎么工作,說不清楚了,講不明白//就不說, 方法沒有主體的方法,必須使用關鍵字abstract修飾//抽象的方法,必須存在于抽象的類中,類也必須用abstract修飾public abstract void work();}13抽象類的使用方式
A:抽象類的使用方式/** 定義類,JavaEE的開發人員* 繼承抽象類Develop,重寫抽象的方法*/ public class JavaEE extends Develop{//重寫父類的抽象方法//去掉abstract修飾符,加上方法主體public void work(){System.out.println("JavaEE工程師在開發B/S 軟件");} } /** 定義Android類,繼承開發人員類* 重寫抽象方法*/ public class Android extends Develop{public void work(){System.out.println("Android工程師開發手機軟件");} } ? /** 測試抽象類* 創建他的子類的對象,使用子類的對象調用方法*/ public class Test {public static void main(String[] args) {JavaEE ee = new JavaEE();ee.work();//"JavaEE工程師在開發B/S 軟件" Android and = new Android();and.work();//"Android工程師開發手機軟件" } }14抽象類特點
A:抽象類的特點?a:抽象類和抽象方法都需要被abstract修飾。抽象方法一定要定義在抽象類中。
b:抽象類不可以直接創建對象,原因:調用抽象方法沒有意義。
c:只有覆蓋了抽象類中所有的抽象方法后,其子類才可以創建對象。否則該子類還是一個抽象類。
之所以繼承抽象類,更多的是在思想,是面對共性類型操作會更簡單。
abstract class A{
public abstract void func();
public abstract void func2();
}
class A2 extends A{
//A2把A中的兩個抽象方法都重寫掉了
//A2類不再是抽象類 public void func(){} public void func2(){} }abstract class A3 extends A{
//含有抽象方法的類一定是抽象類public void func(){} //public abstract void func2();//func2相當于被繼承下來}
15抽象類的設計思想 4:40
A:抽象類的設計思想a:抽象類的作用:繼承的體系抽象類,強制子類重寫抽象的方法抽象員工:規定一個方法,work工作EE員工,Android員工 Develop類 抽象類abstract work();|-------------| |EE Android //是我開發的一員必須工作work(){} work(){}16抽象類的細節
A:抽象類的細節
a:抽象類一定是個父類? 是的,因為不斷抽取而來的。b:抽象類中是否可以不定義抽象方法? 是可以的,那這個抽象類的存在到底有什么意義呢?不讓該類創建對象,方法可以直接讓子類去使用 (適配器設計模式)
/*
* 抽象類,可以沒有抽象方法,可以定義帶有方法體的方法
* 讓子類繼承后,可以直接使用
*/
public abstract class Animal {
public void sleep(){ System.out.println("動物睡覺");
}}public class Cat extends Animal{ ?} public class Test {public static void main(String[] args) {//Cat c = new Cat();new Cat().sleep();//不讓該類創建對象,方法可以直接讓子類去使用 }}c:抽象關鍵字abstract不可以和哪些關鍵字共存? 1:private:私有的方法子類是無法繼承到的,也不存在覆蓋, 而abstract和private一起使用修飾方法,abstract既要子類去實現這個方法, 而private修飾子類根本無法得到父類這個方法。互相矛盾。/** 抽象類,可以沒有抽象方法,可以定義帶有方法體的方法* 讓子類繼承后,可以直接使用*/public abstract class Animal {// private abstract void show();//抽象方法,需要子類重寫, 如果父類方法是私有的,子類繼承不了,也就沒有了重寫 } 2:final,暫時不關注,后面學? 3:static,暫時不關注,后面學
17員工案例分析
A:員工案例分析:?a:需求描述: 某IT公司有多名員工,按照員工負責的工作不同,進行了部門的劃分(研發部員工、維護部員工)。
研發部根據所需研發的內容不同,又分為JavaEE工程師、Android工程師; 維護部根據所需維護的內容不同,又分為網絡維護工程師、硬件維護工程師。公司的每名員工都有他們自己的員工編號、姓名,并要做它們所負責的工作。 工作內容:
JavaEE工程師:員工號為xxx的 xxx員工,正在研發淘寶網站
Android工程師:員工號為xxx的 xxx員工,正在研發淘寶手機客戶端軟件
? ? ? ?網絡維護工程師:員工號為xxx的 xxx員工,正在檢查網絡是否暢通 硬件維護工程師:員工號為xxx的 xxx員工,正在修復打印機
b:繼承體系: 員工 | -------------------------------------------- | | 研發部員工 維護部員工 | | | | | |JavaEE工程師 Android工程師 網絡維護工程師 硬件維護工程師
? ?c:詳細描述:
? 根據員工信息的描述,確定每個員工都有員工編號、姓名、要進行工作。 則,把這些共同的屬性與功能抽取到父類中(員工類), 關于工作的內容由具體的工程師來進行指定。
? 工作內容 ? JavaEE工程師:員工號為xxx的 xxx員工,正在研發淘寶網站
? Android工程師:員工號為xxx的 xxx員工,正在研發淘寶手機客戶端軟件
? 網絡維護工程師:員工號為xxx的 xxx員工,正在檢查網絡是否暢通
? 硬件維護工程師:員工號為xxx的 xxx員工,正在修復打印機
? 創建JavaEE工程師對象,完成工作方法的調用
18員工案例Employee類的編寫
A:員工案例Employee類的編寫:按照分析的繼承體系來逐個實現
/* * 定義員工類 * 內容,都是所有子類的共性抽取* 屬性: 姓名,工號 * 方法: 工作
*/
public abstract class Employee {
private String id;
// 員工編號 private String name; // 員工姓名public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}//工作方法(抽象方法)public abstract void work(); }
19員工案例的子類的編寫
B:員工案例的子類的編寫:/* * 定義研發員工類 * 屬于員工中的一種, 繼承員工類 * 抽象類Develop 給自己的員工定義自己有的屬性 */public abstract class Develop extends Employee{} ?/** 描述JavaEE開發工程師類* 工號,姓名 工作方法* 其他的員工,也具備這些共性,抽取到父類中,自己就不需要定義了* 是研發部員工的一種,繼承研發部類*/
public class JavaEE extends Develop{//重寫他父類的父類的抽象方法public void work(){//調用父類的get方法,獲取name,id值System.out.println("JavaEE的工程師開發淘寶"+ super.getName()+".."+super.getId());} }
/* *定義Android工程師 繼承 研發部員工類,重寫工作方法 */ public class Android extends Developer {@Overridepublic void work() {System.out.println("員工號為 " + getId() + " 的 " + getName() + " 員工,正在研發淘寶手機客戶端軟件");} }/** 定義維護員工類,屬于員工中的一種* 繼承員工類* 抽象類Maintainer 給自己的員工定義自己有的屬性*/ public abstract class Maintainer extends Employee{ ? } ? /** 描述的是網絡維護工程師* 屬于維護部的員工,繼承維護部類*/ public class Network extends Maintainer{public void work(){System.out.println("網絡工程師在檢查網絡是否暢通"+super.getName()+"..."+super.getId());} }
/*
*定義Hardware硬件維護工程師 繼承 維護部員工類,重寫工作方法
*/
public class Hardware extends Maintainer {
@Override public void work() {
System.out.println("員工號為 " + getId() + " 的 " + getName() + " 員工,正在修復打印機");
} }
?
轉載于:https://www.cnblogs.com/alexzhang92/p/9969744.html
總結
以上是生活随笔為你收集整理的10_java之继承和抽象类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于linux中的 秘钥认证 ,最清晰解
- 下一篇: char* 和 char * 思考