Java基础:继承、多态、抽象、接口
生活随笔
收集整理的這篇文章主要介紹了
Java基础:继承、多态、抽象、接口
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
第一講 ? ?繼承
2、通過extends關鍵字可以實現類與類的繼承
? ? ? class 子類名 extends 父類名 {} ?
3、單獨的這個類稱為父類,基類或者超類;這多個類可以稱為子類或者派生類。
4、有了繼承以后,我們定義一個類的時候,可以在一個已經存在的類的基礎上,還可以定義自己的新成員。
首先我來寫兩個代碼://定義學生類class Student {String name;int age;public Student(){}//getXxx()/setXxx()public void eat() {System.out.println("吃飯");}}//定義老師類class Teacher {String name;int age;public Teacher(){}//getXxx()/setXxx()public void eat() {System.out.println("吃飯");}} 我們觀察上面兩個代碼:發(fā)現name,age成員變量,以及getXxx()/setXxx(),還有eat()等都是相同的。如果我們后來繼續(xù)定義類,舉例:工人類,軍人類。他們是不是也具備這些內容。那么,我們每一次定義這樣的類的時候,都要把這些重復的內容都重新定義一遍。麻煩不?麻煩。所以,我們要考慮改進? 如何改進呢?我這想的:我能不能把這些相同的內容給定義到一個獨立的類中。然后,讓這多個類和這個獨立的類產生一個關系,有了這個關系后,這多個類就可以具備這個獨立的類的功能。為了實現這個效果,java就提供了一個技術:繼承。父親:4個兒子 繼承怎么表示呢?繼承的格式是什么樣子的呢?class Fu {}class Zi extends Fu {} 我們就回頭修改我們的代碼:class Person {String name;int age;public Person(){}//getXxx()/setXxx()public void eat() {System.out.println("吃飯");}}class Student extends Person {public Student(){}}class Teacher extends Person {public Teacher(){}}
? ? ?我們在設計的時候原則是:自己能完成的就不麻煩別人,這樣將來別人產生了修改,就對我的影響較小。由此可見:在開發(fā)中使用繼承其實是在使用一把雙刃劍。今天我們還是以繼承的好處來使用,因為繼承還有很多其他的特性。
/*繼承概述:把多個類中相同的內容給提取出來定義到一個類中。如何實現繼承呢? Java提供了關鍵字:extends格式:class 子類名 extends 父類名 {}好處:A:提高了代碼的復用性B:提高了代碼的維護性C:讓類與類之間產生了關系,是多態(tài)的前提類與類產生了關系,其實也是繼承的一個弊端:類的耦合性增強了。開發(fā)的原則:低耦合,高內聚。耦合:類與類的關系內聚:就是自己完成某件事情的能力 *///使用繼承前 /* class Student {public void eat() {System.out.println("吃飯");}public void sleep() {System.out.println("睡覺");} }class Teacher {public void eat() {System.out.println("吃飯");}public void sleep() {System.out.println("睡覺");} } *///使用繼承后 class Person {public void eat() {System.out.println("吃飯");}public void sleep() {System.out.println("睡覺");} }class Student extends Person {}class Teacher extends Person {}class ExtendsDemo {public static void main(String[] args) {Student s = new Student();s.eat();s.sleep();System.out.println("-------------");Teacher t = new Teacher();t.eat();t.sleep();} }運行結果:
(2)class SubDemo extends Demo{} //ok
(3)class SubDemo extends Demo1,Demo2...//error
? ? ?class B extends A{}
? ? ?class C extends B{}
/*Java中繼承的特點:A:Java只支持單繼承,不支持多繼承。有些語言是支持多繼承,格式:extends 類1,類2,...B:Java支持多層繼承(繼承體系) *//* class Father {} class Mother {} class Son exnteds Father {} //正確的 class Son extends Father,Mother {} // 錯誤的 */class GrandFather {public void show() {System.out.println("我是爺爺");} }class Father extends GrandFather {public void method(){System.out.println("我是老子");} }class Son extends Father {}class ExtendsDemo2 {public static void main(String[] args) {Son s = new Son();s.method(); //使用父親的s.show(); //使用爺爺的} }運行結果:
? ? ? ? ?其實這也體現了繼承的另一個弊端:打破了封裝性
(2)子類不能繼承父類的構造方法,但是可以通過super(后面講)關鍵字去訪問父類構造方法。
(3)不要為了部分功能而去繼承
(4)我們到底在什么時候使用繼承呢?
? ? ? ? ?繼承中類之間體現的是:”is a”的關系。
/*繼承的注意事項:A:子類只能繼承父類所有非私有的成員(成員方法和成員變量)B:子類不能繼承父類的構造方法,但是可以通過super(馬上講)關鍵字去訪問父類構造方法。C:不要為了部分功能而去繼承class A {public void show1(){}public void show2(){}}class B {public void show2(){}public void show3(){}}//我們發(fā)現B類中出現了和A類一樣的show2()方法,所以,我們就用繼承來體現class B extends A {public void show3(){}}這樣其實不好,因為這樣你不但有了show2(),還多了show1()。有可能show1()不是你想要的。那么,我們什么時候考慮使用繼承呢?繼承其實體現的是一種關系:"is a"。PersonStudentTeacher水果蘋果香蕉橘子采用假設法。如果有兩個類A,B。只有他們符合A是B的一種,或者B是A的一種,就可以考慮使用繼承。 */ class Father {private int num = 10;public int num2 = 20;//私有方法,子類不能繼承private void method() {System.out.println(num);System.out.println(num2);}public void show() {System.out.println(num);System.out.println(num2);} }class Son extends Father {public void function() {//num可以在Father中訪問private//System.out.println(num); //子類不能繼承父類的私有成員變量System.out.println(num2);} }class ExtendsDemo3 {public static void main(String[] args) {// 創(chuàng)建對象Son s = new Son();//s.method(); //子類不能繼承父類的私有成員方法s.show();s.function();} }
(1)首先在子類局部范圍找
(2)然后在子類成員范圍找
(3)最后在父類成員范圍找(肯定不能訪問到父類局部范圍)
(4)如果還是沒有就報錯。(不考慮父親的父親…)
/*類的組成:成員變量:構造方法:成員方法:而現在我們又講解了繼承,所以,我們就應該來考慮一下,類的組成部分的各自關系。繼承中成員變量的關系:A:子類中的成員變量和父類中的成員變量名稱不一樣,這個太簡單。B:子類中的成員變量和父類中的成員變量名稱一樣,這個怎么玩呢?在子類方法中訪問一個變量的查找順序:a:在子類方法的局部范圍找,有就使用b:在子類的成員范圍找,有就使用c:在父類的成員范圍找,有就使用d:如果還找不到,就報錯。 */ class Father {public int num = 10;public void method() {int num = 50;} }class Son extends Father {public int num2 = 20;public int num = 30;public void show() {int num = 40;System.out.println(num);System.out.println(num2);// 找不到符號System.out.println(num3);} }class ExtendsDemo4 {public static void main(String[] args) {//創(chuàng)建對象Son s = new Son();s.show();} }
? ? ? ? this代表本類對應的引用。
? ? ? ? super代表父類存儲空間的標識(可以理解為父類引用)
(2)用法(this和super均可如下使用)
(2)原因:
? ? ? ? ?因為子類會繼承父類中的數據,可能還會使用父類的數據。所以,子類初始化之前,一定要先完成父類數據的初始化。 ? ? ? ? ?每一個構造方法的第一條語句默認都是:super()
(3)如果父類中沒有構造方法,該怎么辦呢? ? ? ? ? 子類通過super去顯示調用父類其他的帶參的構造方法
? ? ? ? 子類通過this去調用本類的其他構造方法
? ? ? ? 本類其他構造也必須首先訪問了父類構造
? ? ? ? ?一定要注意:super(…)或者this(….)必須出現在第一條語句山,否則,就會有父類數據的多次初始化
/*繼承中構造方法的關系A:子類中所有的構造方法默認都會訪問父類中空參數的構造方法B:為什么呢?因為子類會繼承父類中的數據,可能還會使用父類的數據。所以,子類初始化之前,一定要先完成父類數據的初始化。注意:子類每一個構造方法的第一條語句默認都是:super(); */ class Father {int age;public Father() {System.out.println("Father的無參構造方法");}public Father(String name) {System.out.println("Father的帶參構造方法");} }class Son extends Father {public Son() {//super();System.out.println("Son的無參構造方法");}public Son(String name) {//super();System.out.println("Son的帶參構造方法");} } class ExtendsDemo6 {public static void main(String[] args) {//創(chuàng)建對象Son s = new Son();System.out.println("------------");Son s2 = new Son("林青霞");} }
? ? ? ? ?使用特點:如果方法名不同,就調用對應的方法;如果方法名相同,最終使用的是子類自己的
(2)方法重寫的應用:
? ? ? ? ?當子類需要父類的功能,而功能主體子類有自己特有內容時,可以重寫父類中的方法,這樣,即沿襲了父類的功能,又定義了子類特有的內容。 (3)方法重寫的注意事項
? ? ? ? 父類中私有方法不能被重寫
? ? ? ? 子類重寫父類方法時,訪問權限不能更低
? ? ? ? 父類靜態(tài)方法,子類也必須通過靜態(tài)方法進行重寫。 /*方法重寫:子類中出現了和父類中方法聲明一模一樣的方法。方法重載:本類中出現的方法名一樣,參數列表不同的方法。與返回值無關。子類對象調用方法的時候:先找子類本身,再找父類。方法重寫的應用:當子類需要父類的功能,而功能主體子類有自己特有內容時,可以重寫父類中的方法。這樣,即沿襲了父類的功能,又定義了子類特有的內容。案例:A:定義一個手機類。B:通過研究,我發(fā)明了一個新手機,這個手機的作用是在打完電話后,可以聽天氣預報。按照我們基本的設計,我們把代碼給寫出來了。但是呢?我們又發(fā)現新手機應該是手機,所以,它應該繼承自手機。其實這個時候的設計,并不是最好的。因為手機打電話功能,是手機本身就具備的最基本的功能。所以,我的新手機是不用在提供這個功能的。但是,這個時候,打電話功能就沒有了。這個不好。最終,還是加上這個功能。由于它繼承了手機類,所以,我們就直接使用父類的功能即可。那么,如何使用父類的功能呢?通過super關鍵字調用 */ class Phone {public void call(String name) {System.out.println("給"+name+"打電話");} }class NewPhone extends Phone {public void call(String name) {//System.out.println("給"+name+"打電話");super.call(name);System.out.println("可以聽天氣預報了");} }class ExtendsDemo9 {public static void main(String[] args) {NewPhone np = new NewPhone();np.call("林青霞");} }運行結果:
? ? ?修飾類,類不能被繼承
? ? ?修飾變量,變量就變成了常量,只能被賦值一次
? ? ?修飾方法,方法不能被重寫
(2)貓狗案例講解 /*貓狗案例講解先找到具體的事物,然后發(fā)現具體的事物有共性,才提取出一個父類。貓:成員變量:姓名,年齡,顏色構造方法:無參,帶參成員方法:getXxx()/setXxx()eat()palyGame()狗:成員變量:姓名,年齡,顏色構造方法:無參,帶參成員方法:getXxx()/setXxx()eat()lookDoor()共性:成員變量:姓名,年齡,顏色構造方法:無參,帶參成員方法:getXxx()/setXxx()eat()把共性定義到一個類中,這個類的名字叫:動物。動物類:成員變量:姓名,年齡,顏色構造方法:無參,帶參成員方法:getXxx()/setXxx()eat()貓: 構造方法:無參,帶參成員方法:palyGame()狗:構造方法:無參,帶參成員方法:lookDoor() */ //定義動物類 class Animal {//姓名private String name;//年齡private int age;//顏色private String color;public Animal() {}public Animal(String name,int age,String color) {this.name = name;this.age = age;this.color = color;}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 String getColor() {return color;}public void setColor(String color) {this.color = color;}public void eat() {System.out.println("不要睡了,該吃飯了");} }//定義貓類 class Cat extends Animal {public Cat() {}public Cat(String name,int age,String color) {super(name,age,color);}public void playGame() {System.out.println("貓玩英雄聯盟");} }//定義狗類 class Dog extends Animal {public Dog() {}public Dog(String name,int age,String color) {super(name,age,color);}public void lookDoor() {System.out.println("狗看家");} }//測試類 class ExtendsTest5 {public static void main(String[] args) {//測試貓//方式1Cat c1 = new Cat();c1.setName("Tom");c1.setAge(3);c1.setColor("白色");System.out.println("貓的名字是:"+c1.getName()+";年齡是:"+c1.getAge()+";顏色是:"+c1.getColor());c1.eat();c1.playGame();System.out.println("---------------");//方式2Cat c2 = new Cat("杰瑞",5,"土豪金");System.out.println("貓的名字是:"+c2.getName()+";年齡是:"+c2.getAge()+";顏色是:"+c2.getColor());c2.eat();c2.playGame();//作業(yè):測試狗} }運行結果:
舉例:貓可以是貓的類型。貓 m = new 貓();同時貓也是動物的一種,也可以把貓稱為動物。動物 d = new 貓();
2、多態(tài)前提和體現
? ? ?有繼承關系
? ? ?有方法重寫
? ? ?有父類引用指向子類對象 3、多態(tài)中的成員訪問特點:
? ? ?(1)成員變量:編譯看左邊,運行看左邊。
? ? ?(2)構造方法:創(chuàng)建子類對象的時候,訪問父類的構造方法,對父類的數據進行初始化。
? ? ?(3)成員方法:編譯看左邊,運行看右邊。動態(tài)綁定
? ? ?(4)靜態(tài)方法:編譯看左邊,運行看左邊。(靜態(tài)和類相關,算不上重寫,所以,訪問還是左邊的)
當方法被 static private final三個關鍵字其中一個修飾,執(zhí)行的靜態(tài)綁定 由于成員方法存在方法重寫,所以它運行看右邊。 /*多態(tài):同一個對象(事物),在不同時刻體現出來的不同狀態(tài)。舉例:貓是貓,貓是動物。水(液體,固體,氣態(tài))。多態(tài)的前提:A:要有繼承關系。B:要有方法重寫。其實沒有也是可以的,但是如果沒有這個就沒有意義。動物 d = new 貓();d.show();動物 d = new 狗();d.show();C:要有父類引用指向子類對象。父 f = new 子();用代碼體現一下多態(tài)。 */ class Fu {public int num = 100;public void show() {System.out.println("show Fu");}public static void function() {System.out.println("function Fu");} }class Zi extends Fu {public int num = 1000;public int num2 = 200;public void show() {System.out.println("show Zi");}public void method() {System.out.println("method zi");}public static void function() {System.out.println("function Zi");} }class DuoTaiDemo {public static void main(String[] args) {//要有父類引用指向子類對象。//父 f = new 子();Fu f = new Zi();System.out.println(f.num);//找不到符號//System.out.println(f.num2);f.show();//找不到符號//f.method();f.function();} }
提高了程序的擴展性(由多態(tài)保證)
那么我們如何才能訪問子類的特有功能呢?
A:創(chuàng)建子類對象調用方法即可。(可以,但是很多時候不合理。而且,太占內存了)
B:把父類的引用強制轉換為子類的引用。(向下轉型)
向下轉型:從父到子,父類引用轉為子類對象。
/*多態(tài)的弊端:不能使用子類的特有功能。我就想使用子類的特有功能?行不行?行。怎么用呢?A:創(chuàng)建子類對象調用方法即可。(可以,但是很多時候不合理。而且,太占內存了)B:把父類的引用強制轉換為子類的引用。(向下轉型)對象間的轉型問題:向上轉型:Fu f = new Zi();向下轉型:Zi z = (Zi)f; //要求該f必須是能夠轉換為Zi的。 */ class Fu {public void show() {System.out.println("show fu");} }class Zi extends Fu {public void show() {System.out.println("show zi");}public void method() {System.out.println("method zi");}}class DuoTaiDemo4 {public static void main(String[] args) {//測試Fu f = new Zi();f.show();//f.method();//創(chuàng)建子類對象//Zi z = new Zi();//z.show();//z.method();//你能夠把子的對象賦值給父親,那么我能不能把父的引用賦值給子的引用呢?//如果可以,但是如下Zi z = (Zi)f;z.show();z.method();} }運行結果:
4、多態(tài)繼承中的內存圖解
5、多態(tài)中的對象變化內存圖解
2、格式:
? ? ? ? ? ? abstract class 類名 {}
? ? ? ? ? ? public abstract void eat();
3、抽象類不一定有抽象方法,有抽象方法的類一定是抽象類
4、抽象類不能實例化
? ? ?那么,抽象類如何實例化呢?按照多態(tài)的方式,由具體的子類實例化。其實這也是多態(tài)的一種,抽象類多態(tài)。
5、抽象類的子類
? ? ?要么是抽象類
? ? ?要么重寫抽象類中的所有抽象方法 /*抽象類的概述:動物不應該定義為具體的東西,而且動物中的吃,睡等也不應該是具體的。我們把一個不是具體的功能稱為抽象的功能,而一個類中如果有抽象的功能,該類必須是抽象類。抽象類的特點:A:抽象類和抽象方法必須用abstract關鍵字修飾B:抽象類中不一定有抽象方法,但是有抽象方法的類必須定義為抽象類C:抽象類不能實例化因為它不是具體的。抽象類有構造方法,但是不能實例化?構造方法的作用是什么呢?用于子類訪問父類數據的初始化D:抽象的子類a:如果不想重寫抽象方法,該子類是一個抽象類。b:重寫所有的抽象方法,這個時候子類是一個具體的類。抽象類的實例化其實是靠具體的子類實現的。是多態(tài)的方式。Animal a = new Cat(); *///abstract class Animal //抽象類的聲明格式 abstract class Animal {//抽象方法//public abstract void eat(){} //空方法體,這個會報錯。抽象方法不能有主體public abstract void eat();public Animal(){} }//子類是抽象類 abstract class Dog extends Animal {}//子類是具體類,重寫抽象方法 class Cat extends Animal {public void eat() {System.out.println("貓吃魚");} }class AbstractDemo {public static void main(String[] args) {//創(chuàng)建對象//Animal是抽象的; 無法實例化//Animal a = new Animal();//通過多態(tài)的方式Animal a = new Cat();a.eat();} }運行結果:
可以是變量,也可以是常量
(2)構造方法
有構造方法,但是不能實例化,那么,構造方法的作用是什么呢?用于子類訪問父類數據的初始化
(3)成員方法
可以有抽象方法 限定子類必須完成某些動作,也可以有非抽象方法 提高代碼服用性 /*抽象類的成員特點:成員變量:既可以是變量,也可以是常量。構造方法:有。用于子類訪問父類數據的初始化。成員方法:既可以是抽象的,也可以是非抽象的。抽象類的成員方法特性:A:抽象方法 強制要求子類做的事情。B:非抽象方法 子類繼承的事情,提高代碼復用性。 */ abstract class Animal {public int num = 10;public final int num2 = 20;public Animal() {}public Animal(String name,int age){}public abstract void show();public void method() {System.out.println("method");} }class Dog extends Animal {public void show() {System.out.println("show Dog");} }class AbstractDemo2 {public static void main(String[] args) {//創(chuàng)建對象Animal a = new Dog();a.num = 100;System.out.println(a.num);//a.num2 = 200;System.out.println(a.num2);System.out.println("--------------");a.show();a.method();} }運行結果:
? ? ?格式:interface 接口名 {}
2、類實現接口用implements表示
? ? ?格式:class 類名 implements 接口名 {}
3、接口不能實例化
? ? ?那么,接口如何實例化呢?按照多態(tài)的方式,由具體的子類實例化。其實這也是多態(tài)的一種,接口多態(tài)。
4、接口的子類
? ? ?要么是抽象類
? ? ?要么重寫接口中的所有抽象方法
? ? ?只能是常量,默認修飾符 public static final
2、構造方法
? ? ?沒有,因為接口主要是擴展功能的,而沒有具體存在
3、成員方法
? ? ?只能是抽象方法,默認修飾符 public abstract
? ? ?繼承關系,只能單繼承,但是可以多層繼承
2、類與接口
? ? ?實現關系,可以單實現,也可以多實現。還可以在繼承一個類的同時實現多個接口
3、接口與接口
? ? ?繼承關系,可以單繼承,也可以多繼承
一、繼承概述
1、多個類中存在相同屬性和行為時,將這些內容抽取到單獨一個類中,那么多個類無需再定義這些屬性和行為,只要繼承那個類即可。2、通過extends關鍵字可以實現類與類的繼承
? ? ? class 子類名 extends 父類名 {} ?
3、單獨的這個類稱為父類,基類或者超類;這多個類可以稱為子類或者派生類。
4、有了繼承以后,我們定義一個類的時候,可以在一個已經存在的類的基礎上,還可以定義自己的新成員。
首先我來寫兩個代碼://定義學生類class Student {String name;int age;public Student(){}//getXxx()/setXxx()public void eat() {System.out.println("吃飯");}}//定義老師類class Teacher {String name;int age;public Teacher(){}//getXxx()/setXxx()public void eat() {System.out.println("吃飯");}} 我們觀察上面兩個代碼:發(fā)現name,age成員變量,以及getXxx()/setXxx(),還有eat()等都是相同的。如果我們后來繼續(xù)定義類,舉例:工人類,軍人類。他們是不是也具備這些內容。那么,我們每一次定義這樣的類的時候,都要把這些重復的內容都重新定義一遍。麻煩不?麻煩。所以,我們要考慮改進? 如何改進呢?我這想的:我能不能把這些相同的內容給定義到一個獨立的類中。然后,讓這多個類和這個獨立的類產生一個關系,有了這個關系后,這多個類就可以具備這個獨立的類的功能。為了實現這個效果,java就提供了一個技術:繼承。父親:4個兒子 繼承怎么表示呢?繼承的格式是什么樣子的呢?class Fu {}class Zi extends Fu {} 我們就回頭修改我們的代碼:class Person {String name;int age;public Person(){}//getXxx()/setXxx()public void eat() {System.out.println("吃飯");}}class Student extends Person {public Student(){}}class Teacher extends Person {public Teacher(){}}
二、繼承的好處
1、提高了代碼的復用性
? ? ?多個類相同的成員可以放到同一個類中2、提高了代碼的維護性
? ? ?如果功能的代碼需要修改,修改一處即可3、讓類與類之間產生了關系,是多態(tài)的前提
? ? ?其實這也是繼承的一個弊端:類的耦合性很強4、設計原則:高內聚低耦合。
? ? ?簡單的理解:內聚就是自己完成某件事情的能力。耦合就是類與類之間的關系。? ? ?我們在設計的時候原則是:自己能完成的就不麻煩別人,這樣將來別人產生了修改,就對我的影響較小。由此可見:在開發(fā)中使用繼承其實是在使用一把雙刃劍。今天我們還是以繼承的好處來使用,因為繼承還有很多其他的特性。
/*繼承概述:把多個類中相同的內容給提取出來定義到一個類中。如何實現繼承呢? Java提供了關鍵字:extends格式:class 子類名 extends 父類名 {}好處:A:提高了代碼的復用性B:提高了代碼的維護性C:讓類與類之間產生了關系,是多態(tài)的前提類與類產生了關系,其實也是繼承的一個弊端:類的耦合性增強了。開發(fā)的原則:低耦合,高內聚。耦合:類與類的關系內聚:就是自己完成某件事情的能力 *///使用繼承前 /* class Student {public void eat() {System.out.println("吃飯");}public void sleep() {System.out.println("睡覺");} }class Teacher {public void eat() {System.out.println("吃飯");}public void sleep() {System.out.println("睡覺");} } *///使用繼承后 class Person {public void eat() {System.out.println("吃飯");}public void sleep() {System.out.println("睡覺");} }class Student extends Person {}class Teacher extends Person {}class ExtendsDemo {public static void main(String[] args) {Student s = new Student();s.eat();s.sleep();System.out.println("-------------");Teacher t = new Teacher();t.eat();t.sleep();} }運行結果:
三、Java中繼承的特點
1、Java只支持單繼承,不支持多繼承。
(1)一個類只能有一個父類,不可以有多個父類。(2)class SubDemo extends Demo{} //ok
(3)class SubDemo extends Demo1,Demo2...//error
2、Java支持多層繼承(繼承體系)
? ? ?class A{}? ? ?class B extends A{}
? ? ?class C extends B{}
/*Java中繼承的特點:A:Java只支持單繼承,不支持多繼承。有些語言是支持多繼承,格式:extends 類1,類2,...B:Java支持多層繼承(繼承體系) *//* class Father {} class Mother {} class Son exnteds Father {} //正確的 class Son extends Father,Mother {} // 錯誤的 */class GrandFather {public void show() {System.out.println("我是爺爺");} }class Father extends GrandFather {public void method(){System.out.println("我是老子");} }class Son extends Father {}class ExtendsDemo2 {public static void main(String[] args) {Son s = new Son();s.method(); //使用父親的s.show(); //使用爺爺的} }運行結果:
3、Java中繼承的注意事項
(1)子類只能繼承父類所有非私有的成員(成員方法和成員變量)? ? ? ? ?其實這也體現了繼承的另一個弊端:打破了封裝性
(2)子類不能繼承父類的構造方法,但是可以通過super(后面講)關鍵字去訪問父類構造方法。
(3)不要為了部分功能而去繼承
(4)我們到底在什么時候使用繼承呢?
? ? ? ? ?繼承中類之間體現的是:”is a”的關系。
/*繼承的注意事項:A:子類只能繼承父類所有非私有的成員(成員方法和成員變量)B:子類不能繼承父類的構造方法,但是可以通過super(馬上講)關鍵字去訪問父類構造方法。C:不要為了部分功能而去繼承class A {public void show1(){}public void show2(){}}class B {public void show2(){}public void show3(){}}//我們發(fā)現B類中出現了和A類一樣的show2()方法,所以,我們就用繼承來體現class B extends A {public void show3(){}}這樣其實不好,因為這樣你不但有了show2(),還多了show1()。有可能show1()不是你想要的。那么,我們什么時候考慮使用繼承呢?繼承其實體現的是一種關系:"is a"。PersonStudentTeacher水果蘋果香蕉橘子采用假設法。如果有兩個類A,B。只有他們符合A是B的一種,或者B是A的一種,就可以考慮使用繼承。 */ class Father {private int num = 10;public int num2 = 20;//私有方法,子類不能繼承private void method() {System.out.println(num);System.out.println(num2);}public void show() {System.out.println(num);System.out.println(num2);} }class Son extends Father {public void function() {//num可以在Father中訪問private//System.out.println(num); //子類不能繼承父類的私有成員變量System.out.println(num2);} }class ExtendsDemo3 {public static void main(String[] args) {// 創(chuàng)建對象Son s = new Son();//s.method(); //子類不能繼承父類的私有成員方法s.show();s.function();} }
4、繼承中成員變量的關系
在子類方法中訪問一個變量(1)首先在子類局部范圍找
(2)然后在子類成員范圍找
(3)最后在父類成員范圍找(肯定不能訪問到父類局部范圍)
(4)如果還是沒有就報錯。(不考慮父親的父親…)
/*類的組成:成員變量:構造方法:成員方法:而現在我們又講解了繼承,所以,我們就應該來考慮一下,類的組成部分的各自關系。繼承中成員變量的關系:A:子類中的成員變量和父類中的成員變量名稱不一樣,這個太簡單。B:子類中的成員變量和父類中的成員變量名稱一樣,這個怎么玩呢?在子類方法中訪問一個變量的查找順序:a:在子類方法的局部范圍找,有就使用b:在子類的成員范圍找,有就使用c:在父類的成員范圍找,有就使用d:如果還找不到,就報錯。 */ class Father {public int num = 10;public void method() {int num = 50;} }class Son extends Father {public int num2 = 20;public int num = 30;public void show() {int num = 40;System.out.println(num);System.out.println(num2);// 找不到符號System.out.println(num3);} }class ExtendsDemo4 {public static void main(String[] args) {//創(chuàng)建對象Son s = new Son();s.show();} }
5、super關鍵字
(1)super的用法和this很像? ? ? ? this代表本類對應的引用。
? ? ? ? super代表父類存儲空間的標識(可以理解為父類引用)
(2)用法(this和super均可如下使用)
/*問題是:我不僅僅要輸出局部范圍的num,還要輸出本類成員范圍的num。怎么辦呢?我還想要輸出父類成員范圍的num。怎么辦呢?如果有一個東西和this相似,但是可以直接訪問父類的數據就好了。恭喜你,這個關鍵字是存在的:super。this和super的區(qū)別?分別是什么呢?this代表本類對應的引用。super代表父類存儲空間的標識(可以理解為父類引用,可以操作父類的成員)怎么用呢?A:調用成員變量this.成員變量 調用本類的成員變量super.成員變量 調用父類的成員變量B:調用構造方法this(...) 調用本類的構造方法super(...) 調用父類的構造方法C:調用成員方法this.成員方法 調用本類的成員方法super.成員方法 調用父類的成員方法 */ class Father {public int num = 10; }class Son extends Father {public int num = 20;public void show() {int num = 30;System.out.println(num);System.out.println(this.num);System.out.println(super.num);} }class ExtendsDemo5 {public static void main(String[] args) {Son s = new Son();s.show();} }
6、繼承中構造方法的關系
(1)子類中所有的構造方法默認都會訪問父類中空參數的構造方法(2)原因:
? ? ? ? ?因為子類會繼承父類中的數據,可能還會使用父類的數據。所以,子類初始化之前,一定要先完成父類數據的初始化。 ? ? ? ? ?每一個構造方法的第一條語句默認都是:super()
(3)如果父類中沒有構造方法,該怎么辦呢? ? ? ? ? 子類通過super去顯示調用父類其他的帶參的構造方法
? ? ? ? 子類通過this去調用本類的其他構造方法
? ? ? ? 本類其他構造也必須首先訪問了父類構造
? ? ? ? ?一定要注意:super(…)或者this(….)必須出現在第一條語句山,否則,就會有父類數據的多次初始化
/*繼承中構造方法的關系A:子類中所有的構造方法默認都會訪問父類中空參數的構造方法B:為什么呢?因為子類會繼承父類中的數據,可能還會使用父類的數據。所以,子類初始化之前,一定要先完成父類數據的初始化。注意:子類每一個構造方法的第一條語句默認都是:super(); */ class Father {int age;public Father() {System.out.println("Father的無參構造方法");}public Father(String name) {System.out.println("Father的帶參構造方法");} }class Son extends Father {public Son() {//super();System.out.println("Son的無參構造方法");}public Son(String name) {//super();System.out.println("Son的帶參構造方法");} } class ExtendsDemo6 {public static void main(String[] args) {//創(chuàng)建對象Son s = new Son();System.out.println("------------");Son s2 = new Son("林青霞");} }
運行結果:
7、方法重寫
(1)子類中出現了和父類中一模一樣的方法聲明,也被稱為方法覆蓋,方法復寫。? ? ? ? ?使用特點:如果方法名不同,就調用對應的方法;如果方法名相同,最終使用的是子類自己的
(2)方法重寫的應用:
? ? ? ? ?當子類需要父類的功能,而功能主體子類有自己特有內容時,可以重寫父類中的方法,這樣,即沿襲了父類的功能,又定義了子類特有的內容。 (3)方法重寫的注意事項
? ? ? ? 父類中私有方法不能被重寫
? ? ? ? 子類重寫父類方法時,訪問權限不能更低
? ? ? ? 父類靜態(tài)方法,子類也必須通過靜態(tài)方法進行重寫。 /*方法重寫:子類中出現了和父類中方法聲明一模一樣的方法。方法重載:本類中出現的方法名一樣,參數列表不同的方法。與返回值無關。子類對象調用方法的時候:先找子類本身,再找父類。方法重寫的應用:當子類需要父類的功能,而功能主體子類有自己特有內容時,可以重寫父類中的方法。這樣,即沿襲了父類的功能,又定義了子類特有的內容。案例:A:定義一個手機類。B:通過研究,我發(fā)明了一個新手機,這個手機的作用是在打完電話后,可以聽天氣預報。按照我們基本的設計,我們把代碼給寫出來了。但是呢?我們又發(fā)現新手機應該是手機,所以,它應該繼承自手機。其實這個時候的設計,并不是最好的。因為手機打電話功能,是手機本身就具備的最基本的功能。所以,我的新手機是不用在提供這個功能的。但是,這個時候,打電話功能就沒有了。這個不好。最終,還是加上這個功能。由于它繼承了手機類,所以,我們就直接使用父類的功能即可。那么,如何使用父類的功能呢?通過super關鍵字調用 */ class Phone {public void call(String name) {System.out.println("給"+name+"打電話");} }class NewPhone extends Phone {public void call(String name) {//System.out.println("給"+name+"打電話");super.call(name);System.out.println("可以聽天氣預報了");} }class ExtendsDemo9 {public static void main(String[] args) {NewPhone np = new NewPhone();np.call("林青霞");} }運行結果:
8、final關鍵字
? ? ?通過子類重寫父類方法,來說明父類不能被人動的方法,也別動了。為了強制不能動,Java就提高了final關鍵字 final關鍵字是最終的意思,可以修飾類,成員變量,成員方法。? ? ?修飾類,類不能被繼承
? ? ?修飾變量,變量就變成了常量,只能被賦值一次
? ? ?修飾方法,方法不能被重寫
9、繼承練習
(1)學生案例和老師案例講解 /*學生案例和老師案例講解學生:成員變量;姓名,年齡構造方法:無參,帶參成員方法:getXxx()/setXxx()老師:成員變量;姓名,年齡構造方法:無參,帶參成員方法:getXxx()/setXxx()看上面兩個類的成員,發(fā)現了很多相同的東西,所以我們就考慮抽取一個共性的類:人:成員變量;姓名,年齡構造方法:無參,帶參成員方法:getXxx()/setXxx()學生 繼承 人老師 繼承 人 */ //定義人類 class Person {//姓名private String name;//年齡private int age;public Person() {}public Person(String name,int age) { //"林青霞",27this.name = name;this.age = age;}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;} }//定義學生類 class Student extends Person {public Student() {}public Student(String name,int age) { //"林青霞",27//this.name = name;//this.age = age;super(name,age);} }//定義老師類 class Teacher extends Person {}class ExtendsTest4 {public static void main(String[] args) {//創(chuàng)建學生對象并測試//方式1Student s1 = new Student();s1.setName("林青霞");s1.setAge(27);System.out.println(s1.getName()+"---"+s1.getAge());//方式2Student s2 = new Student("林青霞",27);System.out.println(s2.getName()+"---"+s2.getAge());//補齊老師類中的代碼并進行測試。} }運行結果:(2)貓狗案例講解 /*貓狗案例講解先找到具體的事物,然后發(fā)現具體的事物有共性,才提取出一個父類。貓:成員變量:姓名,年齡,顏色構造方法:無參,帶參成員方法:getXxx()/setXxx()eat()palyGame()狗:成員變量:姓名,年齡,顏色構造方法:無參,帶參成員方法:getXxx()/setXxx()eat()lookDoor()共性:成員變量:姓名,年齡,顏色構造方法:無參,帶參成員方法:getXxx()/setXxx()eat()把共性定義到一個類中,這個類的名字叫:動物。動物類:成員變量:姓名,年齡,顏色構造方法:無參,帶參成員方法:getXxx()/setXxx()eat()貓: 構造方法:無參,帶參成員方法:palyGame()狗:構造方法:無參,帶參成員方法:lookDoor() */ //定義動物類 class Animal {//姓名private String name;//年齡private int age;//顏色private String color;public Animal() {}public Animal(String name,int age,String color) {this.name = name;this.age = age;this.color = color;}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 String getColor() {return color;}public void setColor(String color) {this.color = color;}public void eat() {System.out.println("不要睡了,該吃飯了");} }//定義貓類 class Cat extends Animal {public Cat() {}public Cat(String name,int age,String color) {super(name,age,color);}public void playGame() {System.out.println("貓玩英雄聯盟");} }//定義狗類 class Dog extends Animal {public Dog() {}public Dog(String name,int age,String color) {super(name,age,color);}public void lookDoor() {System.out.println("狗看家");} }//測試類 class ExtendsTest5 {public static void main(String[] args) {//測試貓//方式1Cat c1 = new Cat();c1.setName("Tom");c1.setAge(3);c1.setColor("白色");System.out.println("貓的名字是:"+c1.getName()+";年齡是:"+c1.getAge()+";顏色是:"+c1.getColor());c1.eat();c1.playGame();System.out.println("---------------");//方式2Cat c2 = new Cat("杰瑞",5,"土豪金");System.out.println("貓的名字是:"+c2.getName()+";年齡是:"+c2.getAge()+";顏色是:"+c2.getColor());c2.eat();c2.playGame();//作業(yè):測試狗} }運行結果:
第二講 ? ?多態(tài)
一、多態(tài)概述
1、某一個事物,在不同時刻表現出來的不同狀態(tài)。舉例:貓可以是貓的類型。貓 m = new 貓();同時貓也是動物的一種,也可以把貓稱為動物。動物 d = new 貓();
2、多態(tài)前提和體現
? ? ?有繼承關系
? ? ?有方法重寫
? ? ?有父類引用指向子類對象 3、多態(tài)中的成員訪問特點:
? ? ?(1)成員變量:編譯看左邊,運行看左邊。
? ? ?(2)構造方法:創(chuàng)建子類對象的時候,訪問父類的構造方法,對父類的數據進行初始化。
? ? ?(3)成員方法:編譯看左邊,運行看右邊。動態(tài)綁定
? ? ?(4)靜態(tài)方法:編譯看左邊,運行看左邊。(靜態(tài)和類相關,算不上重寫,所以,訪問還是左邊的)
當方法被 static private final三個關鍵字其中一個修飾,執(zhí)行的靜態(tài)綁定 由于成員方法存在方法重寫,所以它運行看右邊。 /*多態(tài):同一個對象(事物),在不同時刻體現出來的不同狀態(tài)。舉例:貓是貓,貓是動物。水(液體,固體,氣態(tài))。多態(tài)的前提:A:要有繼承關系。B:要有方法重寫。其實沒有也是可以的,但是如果沒有這個就沒有意義。動物 d = new 貓();d.show();動物 d = new 狗();d.show();C:要有父類引用指向子類對象。父 f = new 子();用代碼體現一下多態(tài)。 */ class Fu {public int num = 100;public void show() {System.out.println("show Fu");}public static void function() {System.out.println("function Fu");} }class Zi extends Fu {public int num = 1000;public int num2 = 200;public void show() {System.out.println("show Zi");}public void method() {System.out.println("method zi");}public static void function() {System.out.println("function Zi");} }class DuoTaiDemo {public static void main(String[] args) {//要有父類引用指向子類對象。//父 f = new 子();Fu f = new Zi();System.out.println(f.num);//找不到符號//System.out.println(f.num2);f.show();//找不到符號//f.method();f.function();} }
二、多態(tài)的好處和弊端
1、多態(tài)的好處
提高了程序的維護性(由繼承保證)提高了程序的擴展性(由多態(tài)保證)
2、多態(tài)的弊端
不能訪問子類特有功能那么我們如何才能訪問子類的特有功能呢?
A:創(chuàng)建子類對象調用方法即可。(可以,但是很多時候不合理。而且,太占內存了)
B:把父類的引用強制轉換為子類的引用。(向下轉型)
3、多態(tài)中的轉型問題
向上轉型:從子到父,父類引用指向子類對象。向下轉型:從父到子,父類引用轉為子類對象。
/*多態(tài)的弊端:不能使用子類的特有功能。我就想使用子類的特有功能?行不行?行。怎么用呢?A:創(chuàng)建子類對象調用方法即可。(可以,但是很多時候不合理。而且,太占內存了)B:把父類的引用強制轉換為子類的引用。(向下轉型)對象間的轉型問題:向上轉型:Fu f = new Zi();向下轉型:Zi z = (Zi)f; //要求該f必須是能夠轉換為Zi的。 */ class Fu {public void show() {System.out.println("show fu");} }class Zi extends Fu {public void show() {System.out.println("show zi");}public void method() {System.out.println("method zi");}}class DuoTaiDemo4 {public static void main(String[] args) {//測試Fu f = new Zi();f.show();//f.method();//創(chuàng)建子類對象//Zi z = new Zi();//z.show();//z.method();//你能夠把子的對象賦值給父親,那么我能不能把父的引用賦值給子的引用呢?//如果可以,但是如下Zi z = (Zi)f;z.show();z.method();} }運行結果:
4、多態(tài)繼承中的內存圖解
5、多態(tài)中的對象變化內存圖解
第三講 ? ?抽象類
一、抽象類概述
? ? ?回想前面我們的貓狗案例,提取出了一個動物類。并且我們在前面也創(chuàng)建過了動物對象,其實這是不對的。為什么呢?因為,我說動物,你知道我說的是什么動物嗎?只有看到了具體的動物,你才知道,這是什么動物。 所以說,動物本身并不是一個具體的事物,而是一個抽象的事物。只有真正的貓,狗才是具體的動物。同理,我們也可以推想,不同的動物吃的東西應該是不一樣的,所以,我們不應該在動物類中給出具體體現,而是應該給出一個聲明即可。在Java中,一個沒有方法體的方法應該定義為抽象方法,而類中如果有抽象方法,該類必須定義為抽象類。二、抽象類特點
1、抽象類和抽象方法必須用abstract關鍵字修飾2、格式:
? ? ? ? ? ? abstract class 類名 {}
? ? ? ? ? ? public abstract void eat();
3、抽象類不一定有抽象方法,有抽象方法的類一定是抽象類
4、抽象類不能實例化
? ? ?那么,抽象類如何實例化呢?按照多態(tài)的方式,由具體的子類實例化。其實這也是多態(tài)的一種,抽象類多態(tài)。
5、抽象類的子類
? ? ?要么是抽象類
? ? ?要么重寫抽象類中的所有抽象方法 /*抽象類的概述:動物不應該定義為具體的東西,而且動物中的吃,睡等也不應該是具體的。我們把一個不是具體的功能稱為抽象的功能,而一個類中如果有抽象的功能,該類必須是抽象類。抽象類的特點:A:抽象類和抽象方法必須用abstract關鍵字修飾B:抽象類中不一定有抽象方法,但是有抽象方法的類必須定義為抽象類C:抽象類不能實例化因為它不是具體的。抽象類有構造方法,但是不能實例化?構造方法的作用是什么呢?用于子類訪問父類數據的初始化D:抽象的子類a:如果不想重寫抽象方法,該子類是一個抽象類。b:重寫所有的抽象方法,這個時候子類是一個具體的類。抽象類的實例化其實是靠具體的子類實現的。是多態(tài)的方式。Animal a = new Cat(); *///abstract class Animal //抽象類的聲明格式 abstract class Animal {//抽象方法//public abstract void eat(){} //空方法體,這個會報錯。抽象方法不能有主體public abstract void eat();public Animal(){} }//子類是抽象類 abstract class Dog extends Animal {}//子類是具體類,重寫抽象方法 class Cat extends Animal {public void eat() {System.out.println("貓吃魚");} }class AbstractDemo {public static void main(String[] args) {//創(chuàng)建對象//Animal是抽象的; 無法實例化//Animal a = new Animal();//通過多態(tài)的方式Animal a = new Cat();a.eat();} }運行結果:
2、抽象類的成員特點
(1)成員變量可以是變量,也可以是常量
(2)構造方法
有構造方法,但是不能實例化,那么,構造方法的作用是什么呢?用于子類訪問父類數據的初始化
(3)成員方法
可以有抽象方法 限定子類必須完成某些動作,也可以有非抽象方法 提高代碼服用性 /*抽象類的成員特點:成員變量:既可以是變量,也可以是常量。構造方法:有。用于子類訪問父類數據的初始化。成員方法:既可以是抽象的,也可以是非抽象的。抽象類的成員方法特性:A:抽象方法 強制要求子類做的事情。B:非抽象方法 子類繼承的事情,提高代碼復用性。 */ abstract class Animal {public int num = 10;public final int num2 = 20;public Animal() {}public Animal(String name,int age){}public abstract void show();public void method() {System.out.println("method");} }class Dog extends Animal {public void show() {System.out.println("show Dog");} }class AbstractDemo2 {public static void main(String[] args) {//創(chuàng)建對象Animal a = new Dog();a.num = 100;System.out.println(a.num);//a.num2 = 200;System.out.println(a.num2);System.out.println("--------------");a.show();a.method();} }運行結果:
第四講 ? ?接口
一、接口概述
? ? ? ?繼續(xù)回到我們的貓狗案例,我們想想狗一般就是看門,貓一般就是作為寵物了,對不。但是,現在有很多的馴養(yǎng)員或者是馴獸師,可以訓練出:貓鉆火圈,狗跳高,狗做計算等。而這些額外的動作,并不是所有貓或者狗一開始就具備的,這應該屬于經過特殊的培訓訓練出來的,對不。所以,這些額外的動作定義到動物類中就不合適,也不適合直接定義到貓或者狗中,因為只有部分貓狗具備這些功能。所以,為了體現事物功能的擴展性,Java中就提供了接口來定義這些額外功能,并不給出具體實現,將來哪些貓狗需要被培訓,只需要這部分貓狗把這些額外功能實現即可。二、接口特點
1、接口用關鍵字interface表示? ? ?格式:interface 接口名 {}
2、類實現接口用implements表示
? ? ?格式:class 類名 implements 接口名 {}
3、接口不能實例化
? ? ?那么,接口如何實例化呢?按照多態(tài)的方式,由具體的子類實例化。其實這也是多態(tài)的一種,接口多態(tài)。
4、接口的子類
? ? ?要么是抽象類
? ? ?要么重寫接口中的所有抽象方法
三、接口成員特點
1、成員變量? ? ?只能是常量,默認修飾符 public static final
2、構造方法
? ? ?沒有,因為接口主要是擴展功能的,而沒有具體存在
3、成員方法
? ? ?只能是抽象方法,默認修飾符 public abstract
四、類、接口之間的關系
1、類與類? ? ?繼承關系,只能單繼承,但是可以多層繼承
2、類與接口
? ? ?實現關系,可以單實現,也可以多實現。還可以在繼承一個類的同時實現多個接口
3、接口與接口
? ? ?繼承關系,可以單繼承,也可以多繼承
五、抽象類和接口的區(qū)別
六、接口練習
1、貓狗案例,加入跳高的額外功能
/*貓狗案例,加入跳高的額外功能分析:從具體到抽象貓:姓名,年齡吃飯,睡覺狗:姓名,年齡吃飯,睡覺由于有共性功能,所以,我們抽取出一個父類:動物:姓名,年齡吃飯();睡覺(){}貓:繼承自動物狗:繼承自動物跳高的額外功能是一個新的擴展功能,所以我們要定義一個接口接口:跳高部分貓:實現跳高部分狗:實現跳高實現;從抽象到具體使用:使用具體類 */ //定義跳高接口 interface Jumpping {//跳高功能public abstract void jump(); }//定義抽象類 abstract class Animal {//姓名private String name;//年齡private int age;public Animal() {}public Animal(String name,int age) {this.name = name;this.age = age;}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 void eat();//睡覺(){}public void sleep() {System.out.println("睡覺覺了");} }//具體貓類 class Cat extends Animal {public Cat(){}public Cat(String name,int age) {super(name,age);}public void eat() {System.out.println("貓吃魚");} }//具體狗類 class Dog extends Animal {public Dog(){}public Dog(String name,int age) {super(name,age);}public void eat() {System.out.println("狗吃肉");} }//有跳高功能的貓 class JumpCat extends Cat implements Jumpping {public JumpCat() {}public JumpCat(String name,int age) {super(name,age);}public void jump() {System.out.println("跳高貓");} }//有跳高功能的狗 class JumpDog extends Dog implements Jumpping {public JumpDog() {}public JumpDog(String name,int age) {super(name,age);}public void jump() {System.out.println("跳高狗");} }class InterfaceTest {public static void main(String[] args) {//定義跳高貓并測試JumpCat jc = new JumpCat();jc.setName("哆啦A夢");jc.setAge(3);System.out.println(jc.getName()+"---"+jc.getAge());jc.eat();jc.sleep();jc.jump();System.out.println("-----------------");JumpCat jc2 = new JumpCat("加菲貓",2);System.out.println(jc2.getName()+"---"+jc2.getAge());jc2.eat();jc2.sleep();jc2.jump();//定義跳高狗并進行測試的事情自己完成。} }運行結果:2、老師和學生案例,加入抽煙的額外功能
/*老師和學生案例,加入抽煙的額外功能分析:從具體到抽象老師:姓名,年齡,吃飯,睡覺學生:姓名,年齡,吃飯,睡覺由于有共性功能,我們提取出一個父類,人類。人類:姓名,年齡吃飯();睡覺(){}抽煙的額外功能不是人或者老師,或者學生一開始就應該具備的,所以,我們把它定義為接口抽煙接口。部分老師抽煙:實現抽煙接口部分學生抽煙:實現抽煙接口實現:從抽象到具體使用:具體 */ //定義抽煙接口 interface Smoking {//抽煙的抽象方法public abstract void smoke(); }//定義抽象人類 abstract class Person {//姓名private String name;//年齡private int age;public Person() {}public Person(String name,int age) {this.name = name;this.age = age;}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 void eat();//睡覺(){}public void sleep() {System.out.println("睡覺覺了");} }//具體老師類 class Teacher extends Person {public Teacher() {}public Teacher(String name,int age) {super(name,age);}public void eat() {System.out.println("吃大白菜");} }//具體學生類 class Student extends Person {public Student() {}public Student(String name,int age) {super(name,age);}public void eat() {System.out.println("吃紅燒肉");} }//抽煙的老師 class SmokingTeacher extends Teacher implements Smoking {public SmokingTeacher() {}public SmokingTeacher(String name,int age) {super(name,age);}public void smoke() {System.out.println("抽煙的老師");} }//抽煙的學生 class SmokingStudent extends Student implements Smoking {public SmokingStudent() {}public SmokingStudent(String name,int age) {super(name,age);}public void smoke() {System.out.println("抽煙的學生");} }class InterfaceTest2 {public static void main(String[] args) {//測試學生SmokingStudent ss = new SmokingStudent();ss.setName("林青霞");ss.setAge(27);System.out.println(ss.getName()+"---"+ss.getAge());ss.eat();ss.sleep();ss.smoke();System.out.println("-------------------");SmokingStudent ss2 = new SmokingStudent("劉意",30);System.out.println(ss2.getName()+"---"+ss2.getAge());ss2.eat();ss2.sleep();ss2.smoke();//測試老師留給自己練習} }運行結果:第五講 ? ?權限修飾符
總結
以上是生活随笔為你收集整理的Java基础:继承、多态、抽象、接口的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java基础:常见对象
- 下一篇: 数据存储和界面展示