4.繼承
繼承:就是子類繼承父類的屬性和行為,使得子類對(duì)象具有與父類相同的屬性、相同的行為。子類可以直接 訪問父類中的非私有的屬性和行為
好處:
- 提高代碼的復(fù)用性。
- 類與類之間產(chǎn)生了關(guān)系,是多態(tài)的前提
格式:
通過 extends 關(guān)鍵字,可以聲明一個(gè)子類繼承另外一個(gè)父類,定義格式如下:
class 父類 {
...
}
class 子類 extends 父類 {
...
}
繼承后的特點(diǎn)——成員變量
①如果子類父類中出現(xiàn)不重名的成員變量,這時(shí)的訪問是沒有影響的
②如果子類父類中出現(xiàn)重名的成員變量,這時(shí)的訪問是有影響的
子父類中出現(xiàn)了同名的成員變量時(shí),在子類中需要訪問父類中非私有成員變量時(shí),需要使用 super 關(guān)鍵字,修飾 父類成員變量,類似于之前學(xué)過的 this 。
public class Fu {
public String name="父親";
private int age;
public void learn(){
System.out.println("我正在賺錢....");
}
}
public class Zi extends Fu {
private String name="孩子";
public void play(){
System.out.println("我正在打籃球....");
System.out.println(this.name);
System.out.println(super.name);
}
}
public static void main(String[] args) {
Zi zi = new Zi();
zi.play();
zi.learn();
}
結(jié)果為:
我正在打籃球....
孩子
父親
我正在賺錢....
注意:Fu 類中的成員變量是非私有的,子類中可以直接訪問。若Fu 類中的成員變量私有了,子類是不能 直接訪問的。通常編碼時(shí),我們遵循封裝的原則,使用private修飾成員變量,那么如何訪問父類的私有成員 變量呢?對(duì)!可以在父類中提供公共的getXxx方法和setXxx方法
繼承后的特點(diǎn)——成員方法
①成員方法不重名
如果子類父類中出現(xiàn)不重名的成員方法,這時(shí)的調(diào)用是沒有影響的。對(duì)象調(diào)用方法時(shí),會(huì)先在子類中查找有沒有對(duì) 應(yīng)的方法,若子類中存在就會(huì)執(zhí)行子類中的方法,若子類中不存在就會(huì)執(zhí)行父類中相應(yīng)的方法
②成員方法重名——重寫(Override)
如果子類父類中出現(xiàn)重名的成員方法,這時(shí)的訪問是一種特殊情況,叫做方法重寫 (Override)。
方法重寫 :子類中出現(xiàn)與父類一模一樣的方法時(shí)(返回值類型,方法名和參數(shù)列表都相同),會(huì)出現(xiàn)覆蓋效 果,也稱為重寫或者復(fù)寫。聲明不變,重新實(shí)現(xiàn)
public class Zi extends Fu {
private String name="孩子";
public void play(){
System.out.println("我正在打籃球....");
System.out.println(this.name);
System.out.println(super.name);
}
@Override
public void learn() {
System.out.println("我重寫了父親的方法...");
}
}
public class test01 {
public static void main(String[] args) {
Zi zi = new Zi();
zi.play();
zi.learn();
}
}
結(jié)果:
我正在打籃球....
孩子
父親
我重寫了父親的方法...
注意:
- 子類方法覆蓋父類方法,必須要保證權(quán)限大于等于父類權(quán)限。
- 子類方法覆蓋父類方法,返回值類型、函數(shù)名和參數(shù)列表都要一模一樣
繼承后的特點(diǎn)——構(gòu)造方法
1.構(gòu)造方法的名字是與類名一致的。所以子類是無法繼承父類構(gòu)造方法的。
- 構(gòu)造方法的作用是初始化成員變量的。所以子類的初始化過程中,必須先執(zhí)行父類的初始化動(dòng)作。子類的構(gòu) 造方法中默認(rèn)有一個(gè) super() ,表示調(diào)用父類的構(gòu)造方法,父類成員變量初始化后,才可以給子類使用
public class Fu {
public String name="父親";
private int age;
public void learn(){
System.out.println("我正在賺錢....");
}
public Fu() {
System.out.println("fu()");
}
}
public class Zi extends Fu {
private String name="孩子";
public void play(){
System.out.println("我正在打籃球....");
System.out.println(this.name);
System.out.println(super.name);
}
public Zi() {
//super();
System.out.println("zi()");
}
}
public static void main(String[] args) {
Zi zi = new Zi();
}
注意:在每次創(chuàng)建子類對(duì)象時(shí),先初始化父類空間,再創(chuàng)建其子類對(duì)象本身。目的在于子類對(duì)象中包含了其對(duì)應(yīng)的父類空 間,便可以包含其父類的成員,如果父類成員非private修飾,則子類可以隨意使用父類成員。代碼體現(xiàn)在子類的構(gòu) 造方法調(diào)用時(shí),一定先調(diào)用父類的構(gòu)造方法。
繼承的特點(diǎn)
① Java只支持單繼承,不支持多繼承。
②Java支持多層繼承(繼承體系)
③子類和父類是一種相對(duì)的概念
重載
概念:
- 重載(overloading) 是在一個(gè)類里面,方法名字相同,而參數(shù)不同。返回類型可以相同也可以不同。
- 每個(gè)重載的方法(或者構(gòu)造函數(shù))都必須有一個(gè)獨(dú)一無二的參數(shù)類型列表。
重載規(guī)則: - 被重載的方法必須改變參數(shù)列表(參數(shù)個(gè)數(shù)或類型不一樣);
- 被重載的方法可以改變返回類型;
- 被重載的方法可以改變?cè)L問修飾符;
- 被重載的方法可以聲明新的或更廣的檢查異常;
- 方法能夠在同一個(gè)類中或者在一個(gè)子類中被重載。
- 無法以返回值類型作為重載函數(shù)的區(qū)分標(biāo)準(zhǔn)。
public class OverLoadTest{
public int test(){
System.out.println("test1");
return 1;
}
public void test(int a){
System.out.println("test2");
}
//以下兩個(gè)參數(shù)類型順序不同
public String test(int a,String s){
System.out.println("test3");
return "returntest3";
}
public String test(String s,int a){
System.out.println("test4");
return "returntest4";
}
public static void main(String[] args){
Overloading o = new Overloading();
System.out.println(o.test());
o.test(1);
System.out.println(o.test(1,"test3"));
System.out.println(o.test("test4",1));
}
}
重寫與重載之間的區(qū)別:
方法的重寫(Overriding)和重載(Overloading)是java多態(tài)性的不同表現(xiàn),重寫是父類與子類之間多態(tài)性的一種表現(xiàn),重載可以理解成多態(tài)的具體表現(xiàn)形式。
(1)方法重載是一個(gè)類中定義了多個(gè)方法名相同,而他們的參數(shù)的數(shù)量不同或數(shù)量相同而類型和次序不同,則稱為方法的重載(Overloading)。
(2)方法重寫是在子類存在方法與父類的方法的名字相同,而且參數(shù)的個(gè)數(shù)與類型一樣,返回值也一樣的方法,就稱為重寫(Overriding)。
(3)方法重載是一個(gè)類的多態(tài)性表現(xiàn),而方法重寫是子類與父類的一種多態(tài)性表現(xiàn)。
5.抽象類
由來:
父類中的方法,被它的子類們重寫,子類各自的實(shí)現(xiàn)都不盡相同。那么父類的方法聲明和方法主體,只有聲明還有 意義,而方法主體則沒有存在的意義了。我們把沒有方法主體的方法稱為抽象方法。Java語法規(guī)定,包含抽象方法 的類就是抽象類
定義:
- 抽象方法 : 沒有方法體的方法。
- 抽象類:包含抽象方法的類
抽象方法
定義格式:
修飾符 abstract 返回值類型 方法名 (參數(shù)列表);
示例:
public abstract void run();
抽象類
定義格式:
abstract class 類名字 { }
示例:
public abstract class Animal {
public abstract void run();
}
抽象的使用:
繼承抽象類的子類必須重寫父類所有的抽象方法。否則,該子類也必須聲明為抽象類。最終,必須有子類實(shí)現(xiàn)該父 類的抽象方法,否則,從最初的父類到最終的子類都不能創(chuàng)建對(duì)象,失去意義。
public class Cat extends Animal {
public void run (){
System.out.println("小貓?jiān)趬︻^走~~~");
}
}
public class CatTest {
public static void main(String[] args) {
// 創(chuàng)建子類對(duì)象
Cat c = new Cat();
// 調(diào)用run方法 c.run();
}
}
輸出結(jié)果:
小貓?jiān)趬︻^走~~~
此時(shí)的方法重寫,是子類對(duì)父類抽象方法的完成實(shí)現(xiàn),我們將這種方法重寫的操作,也叫做實(shí)現(xiàn)方法。
注意:
1.抽象類不能創(chuàng)建對(duì)象,如果創(chuàng)建,編譯無法通過而報(bào)錯(cuò)。只能創(chuàng)建其非抽象子類的對(duì)象。
- 理解:假設(shè)創(chuàng)建了抽象類的對(duì)象,調(diào)用抽象的方法,而抽象方法沒有具體的方法體,沒有意義。
2.抽象類中,可以有構(gòu)造方法,是供子類創(chuàng)建對(duì)象時(shí),初始化父類成員使用的。
- 理解:子類的構(gòu)造方法中,有默認(rèn)的super(),需要訪問父類構(gòu)造方法。
3.抽象類中,不一定包含抽象方法,但是有抽象方法的類必定是抽象類。
- 理解:未包含抽象方法的抽象類,目的就是不想讓調(diào)用者創(chuàng)建該類對(duì)象,通常用于某些特殊的類結(jié)構(gòu)設(shè)計(jì)。
4.抽象類的子類,必須重寫抽象父類中所有的抽象方法,否則,編譯無法通過而報(bào)錯(cuò)。除非該子類也是抽象 類。
- 理解:假設(shè)不重寫所有抽象方法,則類中可能包含抽象方法。那么創(chuàng)建對(duì)象后,調(diào)用抽象的方法,沒有 意義。
6.接口
- 接口,是Java語言中一種引用類型,是方法的集合,如果說類的內(nèi)部封裝了成員變量、構(gòu)造方法和成員方法,那么接口的內(nèi)部主要就是封裝了方法
- 接口的定義,它與定義類方式相似,但是使用 interface 關(guān)鍵字。它也會(huì)被編譯成.class文件,但一定要明確它并 不是類,而是另外一種引用數(shù)據(jù)類型
- 接口的使用,它不能創(chuàng)建對(duì)象,但是可以被實(shí)現(xiàn)( implements ,類似于被繼承)。一個(gè)實(shí)現(xiàn)接口的類(可以看做 是接口的子類),需要實(shí)現(xiàn)接口中所有的抽象方法,創(chuàng)建該類對(duì)象,就可以調(diào)用方法了,否則它必須是一個(gè)抽象 類
定義格式 :
public interface 接口名稱 {
// 抽象方法
// 默認(rèn)方法
// 靜態(tài)方法
// 私有方法
}
含有抽象方法:
抽象方法:使用 abstract 關(guān)鍵字修飾,可以省略,沒有方法體。該方法供子類實(shí)現(xiàn)使用
public interface InterFaceName {
public abstract void method();
}
含有默認(rèn)方法和靜態(tài)方法
- 默認(rèn)方法:使用 default 修飾,不可省略,供子類調(diào)用或者子類- - 重寫。
- 靜態(tài)方法:使用 static 修飾,供接口直接調(diào)用
public interface InterFaceName {
public default void method() {
// 執(zhí)行語句
}
public static void method2() {
// 執(zhí)行語句
}
}
含有私有方法和私有靜態(tài)方法 :
- 私有方法:使用 private 修飾,供接口中的默認(rèn)方法或者靜態(tài)方法調(diào)用
public interface InterFaceName {
private void method() {
// 執(zhí)行語句
}
}
基本實(shí)現(xiàn):
實(shí)現(xiàn)的動(dòng)作類 似繼承,格式相仿,只是關(guān)鍵字不同,實(shí)現(xiàn)使用 implements 關(guān)鍵字。
非抽象子類實(shí)現(xiàn)接口:
- 必須重寫接口中所有抽象方法。
- 繼承了接口的默認(rèn)方法,即可以直接調(diào)用,也可以重寫。
實(shí)現(xiàn)格式:
class 類名 implements 接口名 {
// 重寫接口中抽象方法【必須】
// 重寫接口中默認(rèn)方法【可選】
}
抽象方法的使用
必須全部實(shí)現(xiàn),代碼如下:
定義接口:
public interface LiveAble {
// 定義抽象方法
public abstract void eat();
public abstract void sleep();
}
定義實(shí)現(xiàn)類:
public class Animal implements LiveAble {
@Override
public void eat() {
System.out.println("吃東西");
}
@Override
public void sleep() {
System.out.println("晚上睡");
}
}
定義測(cè)試類:
public class InterfaceDemo {
public static void main(String[] args) {
// 創(chuàng)建子類對(duì)象
Animal a = new Animal();
// 調(diào)用實(shí)現(xiàn)后的方法
a.eat();
a.sleep();
}
}
輸出結(jié)果:
吃東西
晚上睡
默認(rèn)方法的使用:
可以繼承,可以重寫,二選一,但是只能通過實(shí)現(xiàn)類的對(duì)象來調(diào)用。
- 繼承默認(rèn)方法,代碼如下:
定義接口:
public interface LiveAble {
public default void fly(){
System.out.println("天上飛");
}
}
定義實(shí)現(xiàn)類:
public class Animal implements LiveAble {
// 繼承,什么都不用寫,直接調(diào)用
}
定義測(cè)試類:
public class InterfaceDemo {
public static void main(String[] args) {
// 創(chuàng)建子類對(duì)象
Animal a = new Animal();
// 調(diào)用默認(rèn)方法
a.fly();
}
}
輸出結(jié)果:
天上飛
2.重寫默認(rèn)方法,代碼如下:
定義接口:
public interface LiveAble {
public default void fly(){
System.out.println("天上飛");
}
}
定義實(shí)現(xiàn)類:
public class Animal implements LiveAble {
@Override
public void fly() {
System.out.println("自由自在的飛");
}
}
定義測(cè)試類:
public class InterfaceDemo {
public static void main(String[] args) {
// 創(chuàng)建子類對(duì)象
Animal a = new Animal();
// 調(diào)用重寫方法
a.fly();
}
}
輸出結(jié)果:
自由自在的飛
靜態(tài)方法的使用:
靜態(tài)與.class 文件相關(guān),只能使用接口名調(diào)用,不可以通過實(shí)現(xiàn)類的類名或者實(shí)現(xiàn)類的對(duì)象調(diào)用,代碼如下:
定義接口:
public interface LiveAble {
public static void run(){
System.out.println("跑起來~~~");
}
}
定義實(shí)現(xiàn)類:
public class Animal implements LiveAble {
// 無法重寫靜態(tài)方法
}
定義測(cè)試類:
public class InterfaceDemo {
public static void main(String[] args) {
// Animal.run();
// 【錯(cuò)誤】無法繼承方法,也無法調(diào)用
LiveAble.run();
}
}
私有方法的使用:
- 私有方法:只有默認(rèn)方法可以調(diào)用。
- 私有靜態(tài)方法:默認(rèn)方法和靜態(tài)方法可以調(diào)用。
如果一個(gè)接口中有多個(gè)默認(rèn)方法,并且方法中有重復(fù)的內(nèi)容,那么可以抽取出來,封裝到私有方法中,供默認(rèn)方法 去調(diào)用。從設(shè)計(jì)的角度講,私有的方法是對(duì)默認(rèn)方法和靜態(tài)方法的輔助。同學(xué)們?cè)谝褜W(xué)技術(shù)的基礎(chǔ)上,可以自行測(cè)試。
定義接口:
public interface LiveAble {
default void func(){
func1();
func2();
}
private void func1(){
System.out.println("跑起來~~~");
}
private void func2(){
System.out.println("跑起來~~~");
}
}
7.多態(tài)
生活中,比如跑的動(dòng)作,小貓、小狗和大象,跑起來是不一樣的。再比如飛的動(dòng)作,昆蟲、鳥類和飛機(jī),飛起來也 是不一樣的??梢?,同一行為,通過不同的事物,可以體現(xiàn)出來的不同的形態(tài)。多態(tài),描述的就是這樣的狀態(tài)。
定義:
多態(tài): 是指同一行為,具有多個(gè)不同表現(xiàn)形式。
前提:
- 繼承或者實(shí)現(xiàn)【二選一】
- 方法的重寫【意義體現(xiàn):不重寫,無意義】
- 父類引用指向子類對(duì)象【格式體現(xiàn)】
體現(xiàn):
父類類型 變量名 = new 子類對(duì)象;
變量名.方法名();
父類類型:指子類對(duì)象繼承的父類類型,或者實(shí)現(xiàn)的父接口類型。
Fu f = new Zi();
f.method();
當(dāng)使用多態(tài)方式調(diào)用方法時(shí),首先檢查父類中是否有該方法,如果沒有,則編譯錯(cuò)誤;如果有,執(zhí)行的是子類重寫 后方法。
定義父類:
public abstract class Animal {
public abstract void eat();
}
定義子類:
class Cat extends Animal {
public void eat() {
System.out.println("吃魚");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨頭");
}
}
定義測(cè)試類:
public class Test {
public static void main(String[] args) {
// 多態(tài)形式,創(chuàng)建對(duì)象
Animal a1 = new Cat();
// 調(diào)用的是 Cat 的 eat
a1.eat();
// 多態(tài)形式,創(chuàng)建對(duì)象
Animal a2 = new Dog();
// 調(diào)用的是 Dog 的 eat
a2.eat();
}
}
多態(tài)的好處
實(shí)際開發(fā)的過程中,父類類型作為方法形式參數(shù),傳遞子類對(duì)象給方法,進(jìn)行方法的調(diào)用,更能體現(xiàn)出多態(tài)的擴(kuò)展 性與便利。代碼如下:
定義父類:
public abstract class Animal {
public abstract void eat();
}
定義子類:
class Cat extends Animal {
public void eat() {
System.out.println("吃魚");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨頭");
}
}
定義測(cè)試類:
public class Test {
public static void main(String[] args) {
// 多態(tài)形式,創(chuàng)建對(duì)象
Cat c = new Cat();
Dog d = new Dog();
// 調(diào)用showCatEat
showCatEat(c);
// 調(diào)用showDogEat
showDogEat(d);
/* 以上兩個(gè)方法, 均可以被showAnimalEat(Animal a)方法所替代 而執(zhí)行效果一致*/
showAnimalEat(c);
showAnimalEat(d);
}
public static void showCatEat (Cat c){
c.eat();
}
public static void showDogEat (Dog d){
d.eat();
}
public static void showAnimalEat (Animal a){
a.eat();
}
}
由于多態(tài)特性的支持,showAnimalEat方法的Animal類型,是Cat和Dog的父類類型,父類類型接收子類對(duì)象,當(dāng) 然可以把Cat對(duì)象和Dog對(duì)象,傳遞給方法。
當(dāng)eat方法執(zhí)行時(shí),多態(tài)規(guī)定,執(zhí)行的是子類重寫的方法,那么效果自然與showCatEat、showDogEat方法一致, 所以showAnimalEat完全可以替代以上兩方法。 不僅僅是替代,在擴(kuò)展性方面,無論之后再多的子類出現(xiàn),我們都不需要編寫showXxxEat方法了,直接使用 showAnimalEat都可以完成。
所以,多態(tài)的好處,體現(xiàn)在,可以使程序編寫的更簡單,并有良好的擴(kuò)展。
向上轉(zhuǎn)型
多態(tài)本身是子類類型向父類類型向上轉(zhuǎn)換的過程,這個(gè)過程是默認(rèn)的。
當(dāng)父類引用指向一個(gè)子類對(duì)象時(shí),便是向上轉(zhuǎn)型。
使用格式:
父類類型 變量名 = new 子類類型();
如:Animal a = new Cat();
向下轉(zhuǎn)型
父類類型向子類類型向下轉(zhuǎn)換的過程,這個(gè)過程是強(qiáng)制的。
一個(gè)已經(jīng)向上轉(zhuǎn)型的子類對(duì)象,將父類引用轉(zhuǎn)為子類引用,可以使用強(qiáng)制類型轉(zhuǎn)換的格式,便是向下轉(zhuǎn)型。
使用格式:
子類類型 變量名 = (子類類型) 父類變量名;
如:Cat c =(Cat) a;
為什么要轉(zhuǎn)型?
當(dāng)使用多態(tài)方式調(diào)用方法時(shí),首先檢查父類中是否有該方法,如果沒有,則編譯錯(cuò)誤。也就是說,不能調(diào)用子類擁 有,而父類沒有的方法。編譯都錯(cuò)誤,更別說運(yùn)行了。這也是多態(tài)給我們帶來的一點(diǎn)"小麻煩"。所以,想要調(diào)用子 類特有的方法,必須做向下轉(zhuǎn)型。為了避免ClassCastException的發(fā)生,Java提供了 instanceof 關(guān)鍵字,給引用變量做類型的校驗(yàn),格式如下:
變量名 instanceof 數(shù)據(jù)類型 如果變量屬于該數(shù)據(jù)類型,返回true。
如果變量不屬于該數(shù)據(jù)類型,返回false。
示例:
Animal類:
public abstract class Animal {
//抽象方法
public abstract void run();
public Animal(){
// System.out.println("我是Animal");
}
}
Cat類:
public class Cat extends Animal {
@Override
public void run() {
System.out.println("我是小貓咪,我在跑步....");
}
public Cat() {
super();
}
public void eat(){
System.out.println("chichichichichi");
}
}
Dog類
public class Dog extends Animal {
@Override
public void run() {
}
public Dog() {
System.out.println("我是dog");
}
public void watchHouse() {
System.out.println("看家");
}
}
測(cè)試類:
public static void main(String[] args) {
public static void main(String[] args) {
Animal a = new Cat();
a.run();
Cat cat = (Cat)a;
cat.eat();
//假設(shè)忘記我定義了貓咪的方法 ,我向下轉(zhuǎn)型轉(zhuǎn)成dog類可以么?
// Dog dog = (Dog)a;
//dog.watchHouse();//報(bào)錯(cuò) ClassCastException 類型轉(zhuǎn)換異常
if(a instanceof Dog){
Dog dog = (Dog)a;
dog.watchHouse();
}else if(a instanceof Cat){
Cat cat2 = (Cat)a;
cat2.eat();
}
}
}
結(jié)果:
我是小貓咪,我在跑步....
類型不對(duì)....
接口多態(tài)的綜合案例
筆記本電腦
筆記本電腦(laptop)通常具備使用USB設(shè)備的功能。在生產(chǎn)時(shí),筆記本都預(yù)留了可以插入U(xiǎn)SB設(shè)備的USB接口, 但具體是什么USB設(shè)備,筆記本廠商并不關(guān)心,只要符合USB規(guī)格的設(shè)備都可以。 定義USB接口,具備基本的開啟功能和關(guān)閉功能。鼠標(biāo)和鍵盤要想能在電腦上使用,那么鼠標(biāo)和鍵盤也必須遵守 USB規(guī)范,實(shí)現(xiàn)USB接口,否則鼠標(biāo)和鍵盤的生產(chǎn)出來也無法使用。
案例分析:
進(jìn)行描述筆記本類,實(shí)現(xiàn)筆記本使用USB鼠標(biāo)、USB鍵盤
- USB接口,包含開啟功能、關(guān)閉功能
- 筆記本類,包含運(yùn)行功能、關(guān)機(jī)功能、使用USB設(shè)備功能
- 鼠標(biāo)類,要實(shí)現(xiàn)USB接口,并具備點(diǎn)擊的方法
- 鍵盤類,要實(shí)現(xiàn)USB接口,具備敲擊的方法
定義usb接口
public interface USB {
void open();
void close();
}
定義鼠標(biāo)類:
public class Mouse implements USB {
@Override
public void open() {
System.out.println("我是鼠標(biāo),我現(xiàn)在是開啟狀態(tài).....");
}
@Override
public void close() {
}
public void click(){
System.out.println("我是鼠標(biāo)...我是可以被點(diǎn)擊的呀....");
}
}
定義鍵盤類:
public class KeyBoard implements USB{
@Override
public void open() {
System.out.println("我是鍵盤類....我現(xiàn)在正在開啟...");
}
@Override
public void close() {
System.out.println("我是鍵盤類....我現(xiàn)在正在關(guān)閉...");
}
public void play(){
System.out.println("我是鍵盤類....我是可以被敲打的.......");
}
}
定義筆記本類:
public class Laptop {
public void run(){
System.out.println("我是筆記本,我正在開啟");
}
public void UseUSB(USB usb){
if (usb!=null){
usb.open();
if(usb instanceof Mouse){
Mouse mouse = (Mouse)usb;
mouse.click();
}else if(usb instanceof KeyBoard){
KeyBoard keyBoard = (KeyBoard)usb;
keyBoard.play();
}
usb.close();
}
}
public void unrun(){
System.out.println("我是筆記本,我已經(jīng)被關(guān)閉...");
}
}
測(cè)試類,代碼如下:
public class TestLaptop {
public static void main(String[] args) {
Laptop laptop = new Laptop();
laptop.run();
laptop.UseUSB(new Mouse());
laptop.UseUSB(new KeyBoard());
laptop.unrun();
}
}
結(jié)果:
我是筆記本,我正在開啟
我是鼠標(biāo),我現(xiàn)在是開啟狀態(tài).....
我是鼠標(biāo)...我是可以被點(diǎn)擊的呀....
我是鍵盤類....我現(xiàn)在正在開啟...
我是鍵盤類....我是可以被敲打的.......
我是鍵盤類....我現(xiàn)在正在關(guān)閉...
我是筆記本,我已經(jīng)被關(guān)閉...