1. 程式人生 > >java8 介面之間繼承與覆蓋

java8 介面之間繼承與覆蓋

Java8的接口裡面允許定義靜態方法,與預設方法,那麼當一個子介面繼承父介面時,那麼介面中的預設方法與靜態方法的繼承與覆蓋是怎麼樣的呢?

我們知道兩個類有繼承關係時,子類會繼承父類的例項方法,靜態方法,例項變數與靜態變數,而且子類的例項方法、例項成員變數與父類的例項方法相同時(返回型別相同,引數列表相同,方法名也形同),例項成員變數相同時,子類會將父類的例項方法進行覆蓋,對父類例項成員變數隱藏,但子類繼承父類的靜態方法或靜態成員變數時,不會將父類的靜態方法進行覆蓋,只會對父類靜態方法或靜態成員變數進行隱藏!

public class Fu {
    static int  a = 5;  //父類靜態成員變數
    int  b = 4;         //父類例項成員變數
    
    static void show(){
        System.out.println("父類靜態方法");
    }

    void show1(){
        System.out.println("父類例項方法");
    }
}

class Zi extends Fu{

}

class DemoTest{
    public static void main(String [] args){
        Zi z = new Zi();
        System.out.println(z.a);
        System.out.println(z.b);
        z.show();
        z.show1();           

    }
}

輸出:

5
4
父類靜態方法
父類例項方法

可見子類會繼承父類的靜態成員,例項成員,靜態方法,例項方法!

另外若將DemoTest類中  Zi z = new Zi();改為Fu z = new Zi();輸出結果跟上面的結果一致!因為Zi類只是完全繼承父類,此時多型也就沒發揮出作用!

如將子類改寫成:

class Zi extends Fu{
    int b = 40;
    static int a = 50;
    static void show(){
        System.out.println("子類的靜態方法");
    }
    void show1(){
        System.out.println("子類覆蓋父類的例項方法");
    }
}
同樣DemoTest類中  Zi z = new Zi();改為Fu z = new Zi();輸出結果為:

5
4
父類靜態方法
子類覆蓋父類的例項方法

可見靜態方法,例項成員變數,靜態成員變數都不存在多型。編譯和執行都由等式左邊決定,左邊是什麼型別就呼叫該類的屬性和靜態方法!而例項方法的覆蓋,存在繼承,即編譯時看左邊,執行時看右邊!

介面的預設方法(介面的預設方法由default修飾,可以有方法體,不能與static關鍵字共存!)與抽象方法都可以像例項方法一樣的繼承,但是,當類或介面的超型別提供具有相同簽名的多個預設方法時,Java編譯器遵循以下繼承規則來解決名稱衝突:

1、例項方法優於介面預設方法。

public class Horse {
    public String identifyMyself() {
        return "I am a horse.";
    }
}
public interface Flyer {
    default public String identifyMyself() {
        return "I am able to fly.";
    }
}
public interface Mythical {
    default public String identifyMyself() {
        return "I am a mythical creature.";
    }
}
public class Pegasus extends Horse implements Flyer, Mythical {
    public static void main(String... args) {
        Pegasus myApp = new Pegasus();
        System.out.println(myApp.identifyMyself());
    }
}
執行得到如下結果:

I am a horse.(因為Pegasus類即繼承了Horse類,又實現了Flyer,Mythical介面,他們中都存在一個相同標籤的方法(返回型別相同,函式名形同,引數列表也相同),但由於例項方法優於介面預設方法,所以輸出I am a horse)
2、父接口裡面預設方法被別的介面覆蓋過了,當一個類實現該介面和父介面或者(和另外的繼承了父介面但沒有覆蓋父介面的預設方法的介面),會表現出覆蓋以後的方法,如:

public interface Animal {
    default public String identifyMyself() {
        return "I am an animal.";
    }
}

interface EggLayer extends Animal {
    default public String identifyMyself() {
        return "I am able to lay eggs.";
    }
}

interface FireBreather extends Animal {
}

class Dragon implements EggLayer, Animal,FireBreather {
    public static void main (String... args) {
        Dragon myApp = new Dragon();
        System.out.println(myApp.identifyMyself());
    }
}
輸出:
I am able to lay eggs.

注意千萬不能實現兩個或以上都覆蓋了相同父介面預設方法的介面,否則會出現編譯錯誤!

如下:

public interface Animal {
    default public String identifyMyself() {
        return "I am an animal.";
    }
}

interface EggLayer extends Animal {
    default public String identifyMyself() {
        return "I am able to lay eggs.";
    }
}

interface FireBreather extends Animal {
    default public String identifyMyself(){
        return "I am able to lay Fire.";
    }
}

class Dragon implements EggLayer,FireBreather {
    public static void main (String... args) {
        Dragon myApp = new Dragon();
        System.out.println(myApp.identifyMyself());
    }
}
上面程式碼出現編譯錯誤!
如果不想出現編譯錯誤,可藉助super關鍵字,在實現類裡指定繼承的是哪個介面的預設函式,如下
class Dragon implements EggLayer, FireBreather {
    public String identifyMyself(){
        return FireBreather.super.identifyMyself();  //注意使用方法
    }
    public static void main (String... args) {
        Dragon myApp = new Dragon();
        System.out.println(myApp.identifyMyself());
    }
}
編譯通過,輸出:
        I am able to fire
另外:接口裡面的靜態方法不能被繼承!

相關推薦

java8 介面之間繼承覆蓋

Java8的接口裡面允許定義靜態方法,與預設方法,那麼當一個子介面繼承父介面時,那麼介面中的預設方法與靜態方法的繼承與覆蓋是怎麼樣的呢? 我們知道兩個類有繼承關係時,子類會繼承父類的例項方法,靜態方法,例項變數與靜態變數,而且子類的例項方法、例項成員變數與父類的例項方法相同

C#中的繼承覆蓋

sta 文章 class static color read con public ner 原文發布時間為:2009-03-03 —— 來源於本人的百度文章 [由搬家工具導入]//using System;//using System.Collections.Generic

第10章 介面繼承多型

10.1 package tex; public abstract class one { abstract void test(); public static void main(String args[]) { new one(); } } //無法例項化 10.2 p

IOS中如何在多層介面之間顯示隱藏標籤欄(UITabBar)

在做專案的時候,遇到了一個難題,使用hidesBottomWhenPushed=YES屬性設定,可以讓本級介面及其以後介面都隱藏,但是根據專案 需求,在第4層是需要顯示標籤欄的。 於是想了很多的辦法,每個要顯示的push的介面前都加了hidesBottomWhenPushe

Java的介面繼承多型

介面 java只支援單繼承,即一個類只能有一個父類,因此需要介面來實現多重繼承。 介面的定義 類和介面的區別:一個類通過繼承介面的方式,從而來繼承介面的抽象方法。類描述物件的屬性和方法,介面則包含類要實現的方法。 介面的宣告語法方式: <span style="

聊聊TypeScript中類、介面之間相互繼承實現的那些事兒

本文講述了類的繼承、介面的實現中需要注意的一些小細節,同時也對類、介面的多繼承做了一些講解。 先看一下繼承 類的繼承 子類繼承了父類之後,就會將父類中定義的非 private 屬性以及方法都繼承下來 class Animal { public name: string = "

8.繼承覆蓋、重載多態

auto 區別 再次 cor c++ java接口 睡覺 它的 其中 1. 繼承 1.1 繼承的概念 1.1.1 概念 繼承是java面向對象編程技術的一塊基石,因為它允許創建分等級層次的類。 繼承就是子類繼承父類的特征和行為,使得子類對象(實例)具有父類的實例域和方法,或

Java的繼承介面

Java語言中的很重要的功能,繼承與介面。整合可以讓你在不同的類中共享程式碼,藉口可以用統一的方法處理幾個不同的類的物件。Android中用了大量的繼承,需要掌握。 面向物件的程式設計引入了繼承機制,

介面返回資料資料資料的對比、資料表之間的拆分重組對比

import pymysql import datetime import json import decimal import requests import warnings """ 超市供應鏈資料測試:1、product表和supplier表拆分重組與supply_introduce表對比

JAVA 單繼承 介面 多重繼承

又是一個牛角尖,只是語言不夠嚴謹而已,Java中只支援類的單繼承,介面之間的繼承同樣也是使用extends關鍵字,但是介面之間是支援多繼承的,如下面的例子: interface IP1 {  }  interface IP2 {  }  publicinterface 

介面之間關係、介面介面之間關係、面向物件三大特徵之多型

一、類與介面之間關係: 實現關係。 1、類與介面要注意的事項: 1)重點內容非抽象類實現一個介面時,必須要把介面中所有方法全部實現。 2)抽象類實現一個介面時,可以實現也可以不實現介面中的 方法。 3)一個類可以實現多個介面 。 2、疑問: java為

抽象類介面之間的關係

/*老師和學生案例,加入抽菸的額外功能分析:從具體到抽象老師:姓名,年齡,吃飯,睡覺學生:姓名,年齡,吃飯,睡覺由於有共性功能,我們提取出一個父類,人類。人類:姓名,年齡吃飯();睡覺(){}抽菸的額外功能不是人或者老師,或者學生一開始就應該具備的,所以,我們把它定義為介面

ubuntu開機進入命令列介面圖形介面之間的切換

本人比較喜歡的選擇開機進入介面方法: (1)sudo gedit /etc/default/grub (2)找到這一行 文字:GRUB_CMDLINE_LINUX_DEFAULT="quie

java抽象類和介面繼承之間關係

有時候,我們可能想要構造一個很抽象的父類物件,它可能僅僅代表一個分類或抽象概念,它的例項沒有任何意義,因此不希望它能被例項化。例如:有一個父類“ 水果(Fruit)”,它有幾個子類“蘋果(Apple)”、“橘子(Orange)”、“香蕉(Banana)”等。水果在這裡僅僅只是作為一個分類,顯然水果的例項沒有

android去除掉介面頭標籤狀態列(包含繼承AppCompatActivity)的V7包下

方式一:編碼方式 v7包下去掉標題欄 ActionBar public class SplashAcitivity extends AppCompatActivity { @Override protected void onCreate(Bundle save

在Android中實現Service動態更新UI介面(Service主程式Activity之間的資料互動或控制)

案例:通過service向遠端伺服器傳送請求,根據伺服器返回的結果動態更新主程式UI介面,主程式可實時關閉或重啟服務。 方案一:使用廣播+Service註冊BroadcastReceiver 1、在主程式activity中註冊一個BroadcastReceiver

PHP介面繼承介面繼承原理實現方法詳解

在PHP的介面中,介面可以繼承介面。雖然PHP類只能繼承一個父類(單繼承),但是介面和類不同,介面可以實現多繼承,可以繼承一個或者多個介面。當然介面的繼承也是使用extends關鍵字,要多個繼承的話只要用逗號把繼承的介面隔開即可。 需要注意的是當你介面繼承其它介面時候,

CesiumPrimeNG結合導致介面元素被Cesium覆蓋的問題

問題描述:接觸的專案開始的時候是用的PrimeNG的樣式,後來改為使用Cesium庫,出現了一個神奇的現象,在使用dialog時,dialog出現後會把整個的介面完全覆蓋,包括dialog;(因為公司的專案不方便截圖,大體的如下,就是dialog的對話方塊也在隱

Java中的面向物件、繼承介面(封裝)

Java面向物件程式設計有四(三)大特性:繼承、封裝、多型、(抽象)。今天就從這三個方面進行學習。最簡單的思路,首先,繼承,封裝,多型是什麼意思,然後要了解到,他們到底有什麼用。每一項設計都是有意義,有作用的,知道為什麼用,有什麼用,才能更好的理解。(這點有人總結的很好,wh

java繼承介面

在java中繼承是使用extends關鍵字來實現,不同於C++中的多繼承設計,java中的繼承只能是單繼承,父類可以使一般的類也可以是抽象類,抽象類就是被abstract關鍵字修飾過的類,在其中可以定