欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JAVA利用接口實(shí)現(xiàn)多繼承問題的代碼實(shí)操演示

 更新時(shí)間:2024年03月07日 10:02:44   作者:努力學(xué)編程'  
Java語言并不支持多繼承,這是由于多繼承會帶來許多復(fù)雜的問題,例如"菱形問題"等,下面這篇文章主要給大家介紹了關(guān)于JAVA利用接口實(shí)現(xiàn)多繼承問題的相關(guān)資料,需要的朋友可以參考下

hello,上文帶大家學(xué)習(xí)了java中類的繼承,我們可以創(chuàng)建一個父類,將類中的共性抽取出來,通過子類繼承的方式來實(shí)現(xiàn)代碼的復(fù)用。今天帶大家學(xué)習(xí)不同類之間的另外幾種關(guān)系,即多態(tài)抽象類和接口。

 多態(tài)的概念

多態(tài),從字面意思去形象的理解可以解釋為:針對不同的對象執(zhí)行某一行為時(shí),不同的對象會有不同的狀態(tài)。

比如貓和狗都是動物,他們都有進(jìn)食這個行為但是當(dāng)我們調(diào)用狗這個對象時(shí),吃的是狗糧,而調(diào)用貓時(shí),則會選擇吃貓食。 

代碼實(shí)操演示

class Animal{
    String name;
    int age;
    public  Animal(String name,int age){
        this.name=name;
        this.age=age;
    }
    public void eat(){
        System.out.println("正在吃飯");
    }

}
class Cat extends Animal{
    public Cat(String name, int age) {
        super(name, age);//調(diào)用父類的構(gòu)造方法
    }

    @Override
    public void eat() {
        System.out.println(this.name+"正在吃貓食");;
    }
}
class Dog extends Animal{
    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(this.name+"正在吃狗糧");
    }
}
public class Test {
    public static void eat(Animal a){
        a.eat();//這里放的是父類具體引用的是誰看傳的對象
    }

    public static void main(String[] args) {
        Cat cat=new Cat("寶寶",3);
        Dog dog=new Dog("旺財(cái)",3);
        eat(dog);//傳的狗
        eat(cat);//傳的貓,這里其實(shí)就是動態(tài)綁定

    }
}

 這里還是解釋一下,我們通過子類方法對父類的重寫,后面又在Test類里創(chuàng)建eat()這里傳的是Animal類,由于Animal是Dog和Cat的父類,所以后面我們在調(diào)用eat()時(shí)可以傳Dog和Cat形,即小范圍包含于大范圍。這就是多態(tài)的含義。

類中方法的重寫:

       重寫:又稱覆蓋,子類可以對父類中的非靜態(tài),非private,非final,非構(gòu)造方法的其他方法進(jìn)行重新定義,注意:重寫的方法返回值不能改變,方法的參數(shù)不能改變,方法名也不能改變。即方法的外殼,不變只對里面進(jìn)行重新編寫。我們可以根據(jù)子類的需要對父類中的方法進(jìn)行重新定義。通常重寫的方法會有一個標(biāo)簽 @override,上面的程序里有提及。

 這里可以對比記憶一下我們學(xué)過的重載:

注意:重寫是對于子類和父類中研究的,即不同類之間,而重載是在一個類中實(shí)現(xiàn)了多個參數(shù)不同的同名的方法。 

動態(tài)綁定:即不能立馬確定方法的行為,編譯時(shí)不能確定,等到運(yùn)行時(shí)才能世道方法到底調(diào)用的是哪個方法的類。

父類當(dāng)中的向下轉(zhuǎn)移和向上轉(zhuǎn)移

就是將子類引用給父類來使用,將小范圍賦值給大范圍,但本質(zhì)上仍然為子類對象。

所以運(yùn)行的結(jié)果為寶寶吃貓食。

當(dāng)然你也可以使用Dog類來進(jìn)行向下轉(zhuǎn)型,因?yàn)锳nimal也包含Dog。

直接賦值

方法的返回值

方法的參數(shù)

 直接賦值:

        Animal animal=new Cat("寶寶",10);

當(dāng)做返回值:

向上轉(zhuǎn)型的優(yōu)點(diǎn):代碼更加靈活。

向上轉(zhuǎn)型的缺點(diǎn):無法調(diào)用子類中的特有方法。

那如果我們就是要調(diào)用子類中的特有方法怎么辦呢?這就需要使用向下轉(zhuǎn)型了。

向下轉(zhuǎn)型:

我們可以使用關(guān)鍵字instanceof來對向下轉(zhuǎn)型的對象做一層檢驗(yàn),保障了代碼的安全性。

if(animal instanceof Cat){
   cat=(Cat)animal;
   cat.mew();

這里只有animal引用了Cat類的對象才執(zhí)行if語句。

多態(tài)的優(yōu)點(diǎn)

那么多態(tài)到底有什么優(yōu)點(diǎn)呢,這里給大家總結(jié)一下,多態(tài)可以降低代碼的圈復(fù)雜度,可以避免使用過多的if-else語句,其次,可拓展能力強(qiáng)需要新增一個類時(shí),直接繼承就好,需要注意構(gòu)造方法么有多態(tài)性。

class B {
public B() {
// do nothing
func();
}
public void func() {
System.out.println("B.func()");
}
}
class D extends B {
private int num = 1;
@Override
public void func() {
System.out.println("D.func() " + num);
}
}
public class Test {
public static void main(String[] args) {
D d = new D();
}
}
// 執(zhí)行結(jié)果
D.func() 0

 這里給大家一段有意思的代碼,運(yùn)行結(jié)果你猜對了嗎,原因是new() D之后,第一步應(yīng)該是調(diào)用父類的構(gòu)造方法,即func(),但是構(gòu)造方法在子類中被重寫,所以調(diào)用的是子類中的func(),此時(shí)子類中的成員變量還沒有賦值所以num仍然為0,所以運(yùn)行結(jié)果為D.func() 0

抽象類即抽象方法的重寫

其實(shí),我們在最上面的代碼中發(fā)現(xiàn)了一個問題,很多類由于不能將一個事物準(zhǔn)確描述出來,針對不同的事物的行為不同,執(zhí)行的方法也應(yīng)該不同,比如Animal中的eat()并不能準(zhǔn)確描述狗吃的狗糧,貓吃的貓糧,我們在狗類和貓類中還是要重寫這個eat()方法,類似與Animal的這些類可以理解為抽象類。 

       抽象類,修飾限定符為public abstract,抽象類中的抽象方法(修飾符也是public abstract)類似與eat(),是不能有具體的定義的,原因很好理解,即使你寫了,每個子類還得重寫這個方法,我們只聲明這個方法即可。注意:有抽象方法的類一定是抽象類,抽象類不一定含有抽象方法,抽象類也是類可以定義普通的成員變量,方法甚至是構(gòu)造方法。(非常重要!?。?!)

上代碼理解一下:

//抽象類
public Abstract Animal{
   
   public abstract void eat();//抽象方法
   public abstract void look();//抽象方法
}

抽象類也不能實(shí)例化對象,因?yàn)槌橄耦悷o法完整描述一個事物,他只能被子類繼承,然后子類必須將抽象類當(dāng)中的抽象方法進(jìn)行重寫,否則編譯報(bào)錯,

抽象方法不能是 private 的,因?yàn)樽宇愡€要重寫抽象方法的。

抽象方法不能被final和static修飾,因?yàn)槌橄蠓椒ㄒ蛔宇愔貙?/strong> 。

接口的概念:

       說到接口,我們第一想到的應(yīng)該是USB接口插座...,這些當(dāng)然都算接口,那么讓我來說接口的特性的話,我覺得接口首先是一個封裝好了的東西,并且它有著自己的功能,如果某個東西有了接口,那么他也應(yīng)該具有接口的特性。

在java中接口是多個類的公共規(guī)范,是一種引用數(shù)據(jù)類型,接口的定義格式與定義類的格式基本相同,將class關(guān)鍵字換成 interface 關(guān)鍵字,就定義了一個接口。

interface A{
   public abstract void method1(); // public abstract 是固定搭配,可以不寫
  public void method2();
  abstract void method3()
}

 接口不能直接使用,必須要有一個"實(shí)現(xiàn)類"來"實(shí)現(xiàn)"該接口,實(shí)現(xiàn)接口中的所有抽象方法。 這也比較好理解,畢竟接口只是實(shí)現(xiàn) 了某個特定的功能,并不能描述一個具體的對象。我們使用關(guān)鍵字implement將類和接口連接起來。

public class Animal implements IRunning{
// ...
}

 這里給大家舉一個電腦的例子:

// USB接口
public interface USB {
void openDevice();
void closeDevice();
}
// 鼠標(biāo)類,實(shí)現(xiàn)USB接口
public class Mouse implements USB {
@Override
public void openDevice() {
System.out.println("打開鼠標(biāo)");
}
@Override
public void closeDevice() {
System.out.println("關(guān)閉鼠標(biāo)");
}
public void click(){
System.out.println("鼠標(biāo)點(diǎn)擊");
}
}
// 鍵盤類,實(shí)現(xiàn)USB接口
public class KeyBoard implements USB {
@Override
public void openDevice() {
System.out.println("打開鍵盤");
}
@Override
public void closeDevice() {
System.out.println("關(guān)閉鍵盤");
}
public void inPut(){
System.out.println("鍵盤輸入");
}
}
// 筆記本類:使用USB設(shè)備
public class Computer {
public void powerOn(){
System.out.println("打開筆記本電腦");
}
public void powerOff(){
System.out.println("關(guān)閉筆記本電腦");
}
public void useDevice(USB usb){
usb.openDevice();
if(usb instanceof Mouse){
Mouse mouse = (Mouse)usb;
mouse.click();
}else if(usb instanceof KeyBoard){
KeyBoard keyBoard = (KeyBoard)usb;
keyBoard.inPut();
}
usb.closeDevice();
}
}
// 測試類:
public class TestUSB {
public static void main(String[] args) {
Computer computer = new Computer();
computer.powerOn();
// 使用鼠標(biāo)設(shè)備
computer.useDevice(new Mouse());
// 使用鍵盤設(shè)備
computer.useDevice(new KeyBoard());
computer.powerOff();
}
}

接口雖然是一種引用類型但是,他不能new(),必需通過引用類來重寫接口中的所有方法,并且每個方法都默認(rèn)為public abstract,也可以使用static和default修飾但是必須立即定義該方法,注意重寫方法時(shí)一定要用public修飾。

public interface USB {
void openDevice(); // 默認(rèn)是public的
void closeDevice(); // 默認(rèn)是public的
}
public class Mouse implements USB {
@Override
void openDevice() {
System.out.println("打開鼠標(biāo)");
}
// ...
}
// 編譯報(bào)錯,重寫USB中openDevice方法時(shí),不能使用默認(rèn)修飾符
// 正在嘗試分配更低的訪問權(quán)限; 以前為public

 而且一個類是可以實(shí)現(xiàn)多個接口的,這也間接解決了java的多繼承問題。

class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
}
interface IFlying {
void fly();
}
interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
class Cat extends Animal implements IRunning {
public Cat(String name) {
super(name);
}
@Override
public void run() {
System.out.println(this.name + "正在用四條腿跑");
}
}
class Fish extends Animal implements ISwimming {
public Fish(String name) {
super(name);
}
@Override
public void swim() {
System.out.println(this.name + "正在用尾巴游泳");
}
}

總結(jié)

到此這篇關(guān)于JAVA利用接口實(shí)現(xiàn)多繼承問題的文章就介紹到這了,更多相關(guān)JAVA用接口實(shí)現(xiàn)多繼承內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中Collection、List、Set、Map之間的關(guān)系總結(jié)

    Java中Collection、List、Set、Map之間的關(guān)系總結(jié)

    今天小編就為大家分享一篇關(guān)于Java中Collection、List、Set、Map之間的關(guān)系總結(jié),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • IDEA中osgi的開發(fā)應(yīng)用指南詳解

    IDEA中osgi的開發(fā)應(yīng)用指南詳解

    這篇文章主要介紹了IDEA中osgi的開發(fā)應(yīng)用指南詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-04-04
  • SpringBoot URL帶有特殊字符([]/{}等),報(bào)400錯誤的解決

    SpringBoot URL帶有特殊字符([]/{}等),報(bào)400錯誤的解決

    這篇文章主要介紹了SpringBoot URL帶有特殊字符([]/{}等),報(bào)400錯誤的解決,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • 詳解SpringBoot+Lucene案例介紹

    詳解SpringBoot+Lucene案例介紹

    這篇文章主要介紹了詳解SpringBoot+Lucene案例介紹,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Hadoop源碼分析一架構(gòu)關(guān)系簡介

    Hadoop源碼分析一架構(gòu)關(guān)系簡介

    本篇是Hadoop源碼分析系列文章第一篇,主要介紹一下Hadoop的基礎(chǔ)簡介以及框架關(guān)系,后續(xù)本系列文章會持續(xù)更新,有需要的朋友可以借鑒參考下
    2021-09-09
  • java壓縮文件和下載圖片示例

    java壓縮文件和下載圖片示例

    這篇文章主要為大家詳細(xì)介紹了java壓縮文件和下載圖片示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • SpringBoot自定義MessageConverter與內(nèi)容協(xié)商管理器contentNegotiationManager詳解

    SpringBoot自定義MessageConverter與內(nèi)容協(xié)商管理器contentNegotiationManag

    這篇文章主要介紹了SpringBoot自定義MessageConverter與內(nèi)容協(xié)商管理器contentNegotiationManager的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-10-10
  • 詳解如何實(shí)現(xiàn)SpringBoot的底層注解

    詳解如何實(shí)現(xiàn)SpringBoot的底層注解

    今天給大家?guī)淼奈恼率侨绾螌?shí)現(xiàn)SpringBoot的底層注解,文中有非常詳細(xì)的介紹及代碼示例,對正在學(xué)習(xí)java的小伙伴很有幫助,需要的朋友可以參考下
    2021-06-06
  • 關(guān)于Java虛擬機(jī)HotSpot

    關(guān)于Java虛擬機(jī)HotSpot

    這篇文章主要介紹了關(guān)于Java虛擬機(jī)HotSpot,在Java類中的一些方法會被由C/C++編寫的HotSpot虛擬機(jī)的C/C++函數(shù)調(diào)用,不過由于Java方法與C/C++函數(shù)的調(diào)用約定不同,所以并不能直接調(diào)用,需要JavaCalls::call()這個函數(shù)輔助調(diào)用,下面我們來看看文章對內(nèi)容的具體介紹
    2021-11-11
  • 詳解關(guān)于mybatis-plus中Service和Mapper的分析

    詳解關(guān)于mybatis-plus中Service和Mapper的分析

    這篇文章主要介紹了詳解關(guān)于mybatis-plus中Service和Mapper的分析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09

最新評論