国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁 Java Java基礎 Java中繼承圖文詳解

Java中繼承圖文詳解

Nov 25, 2019 pm 04:45 PM
java

Java中繼承圖文詳解

java繼承與合成基本概念

繼承:可以基於已經(jīng)存在的類別來建構一個新類別。繼承已經(jīng)存在的類別就可以重複使用這些類別的方法和域。在此基礎上,可以新增新的方法和域,從而擴充了類別的功能。

合成:在新類別裡創(chuàng)造原有的物件稱為合成。這種方式可以重複利用現(xiàn)有的程式碼而不更改它的形式。

相關影片教學推薦:java影片教學

1.繼承的語法

關鍵字extends表示新類別衍生於一個已經(jīng)存在的類別。已存在的類別稱為父類別或基底類別,新類別稱為子類別或衍生類別。例如:

class Student extends Person {

}

類別Student繼承了Person,Person類別稱為父類別或基底類,Student類別稱為子類別或衍生類別。

2.合成的語法

合成比較簡單,就是在一個類別中創(chuàng)建一個已經(jīng)存在的類別。

class Student {
    Dog dog;
}

上溯造型

#1.基本概念

##繼承的作用在於程式碼的複用。由於繼承意味著所有父類別的方法亦可在子類別中使用,所以發(fā)給父類別的訊息亦可發(fā)給衍生類別。如果Person類別中有一個eat方法,那麼Student類別中也會有這個方法,這表示Student物件也是Person的一種型別。

class Person {
    public void eat() {
        System.out.println("eat");
    }

    static void show(Person p) {
        p.eat();
    }
}
public class Student extends Person{
    public static void main(String[] args) {
        Student s = new Student();
        Person.show(s);     // ①
    }
}

【運行結果】:

eat

在Person中定義的show方法是用來接收Person句柄的,但是在①處接收的卻是Student物件的參考。這是因為Student物件也是Person物件。在show方法中,傳入的句柄(物件的參考)可以是Person物件以及Person的衍生類別物件。這種將Student句柄轉換成Person句柄的行為成為上溯造型。

2.為什麼要上溯造型

為什麼在呼叫eat是要有意忽略呼叫它的物件型別呢?如果讓show方法簡單地取得Student句柄似乎更直觀易懂,但是那樣會使衍生自Person類別的每一個新類別都要實現(xiàn)專屬自己的show方法:

class Value {
    private int count = 1;

    private Value(int count) {
        this.count = count;
    }

    public static final Value
            v1 = new Value(1),
            v2 = new Value(2),
            v3 = new Value(3);
}

class Person {

    public void eat(Value v) {
        System.out.println("Person.eat()");
    }
}

class Teacher extends Person {
    public void eat(Value v) {
        System.out.println("Teacher.eat()");
    }
}

class Student extends Person {
    public void eat(Value v) {
        System.out.println("Student.eat()");
    }
}

public class UpcastingDemo {
    public static void show(Student s) {
        s.eat(Value.v1);
    }

    public static void show(Teacher t) {
        t.eat(Value.v1);
    }

    public static void show(Person p) {
        p.eat(Value.v1);
    }

    public static void main(String[] args) {
        Student s = new Student();
        Teacher t = new Teacher();
        Person p = new Person();
        show(s);
        show(t);
        show(p);
    }
}

這種做法一個很明顯的缺陷就是必須為每一個Person類別的衍生類別定義與之緊密相關的方法,產(chǎn)生了許多重複的程式碼。另一方面,對於如果忘記了方法的重載也不會報錯。上例中的三個show方法完全可以合併為一個:

public static void show(Person p) {
     p.eat(Value.v1);
}

動態(tài)綁定

當執(zhí)行show(s)時,輸出結果是Student.eat(),這確實是希望得到的結果,但是似乎沒有按照我們希望的形式來執(zhí)行,再來看一下show方法:

public static void show(Person p) {
     p.eat(Value.v1);
}

它接收的是Person句柄,當執(zhí)行show(s)時,它是如何知道Person句柄指向的是一個Student物件而不是Teacher物件呢?編譯器是無從得知的,這牽涉到接下來要說明的綁定問題。

1.方法呼叫的綁定

將一個方法同一個方法主體連接在一起就稱為綁定(Binding)。若在運行運行前執(zhí)行綁定,就稱為「早期綁定」。上面的例子中,在只有一個Person句柄的情況下,編譯器不知道要具體地呼叫哪個方法。 Java實作了一種方法呼叫機制,可在運行期間判斷物件的類型,然後呼叫對應的方法,這種方法在運行期間進行,以物件的類型為基礎的綁定稱為動態(tài)綁定。除非一個方法被宣告為final,Java中的所有方法都是動態(tài)綁定的。

用一張圖表示上溯造型的繼承關係:

Java中繼承圖文詳解

#用程式碼概括為:

Shape s = new Shape();

依照繼承關係,將創(chuàng)建的Circle物件句柄賦給一個Shape是合法的,因為Circle屬於Shape的一種。

當呼叫其中一個基礎類別方法時:

Shape s = new Shape();

此時,呼叫的是Circle.draw(),這是由於動態(tài)綁定的原因。

class Person {
    void eat() {}
    void speak() {}
}
class Boy extends Person {
    void eat() {
        System.out.println("Boy.eat()");
    }
    void speak() {
        System.out.println("Boy.speak()");
    }
}
class Girl extends Person {
    void eat() {
        System.out.println("Girl.eat()");
    }
    void speak() {
        System.out.println("Girl.speak()");
    }
}
public class Persons {
    public static Person randPerson() {
        switch ((int)(Math.random() * 2)) {
        default:
        case 0:
            return new Boy();
        case 1:
            return new Girl();
        }
    }
    public static void main(String[] args) {
        Person[] p = new Person[4];
        for (int i = 0; i < p.length; i++) {
            p[i] = randPerson();    // 隨機生成Boy或Girl
        }
        for (int i = 0; i < p.length; i++) {
            p[i].eat();
        }
    }
}

對所有從Person衍生出來的類,Person建立了一個通用接口,所有衍生的類都有eat和speak兩種行為。衍生類別涵蓋了這些定義,重新定義了這兩種行為。

在主類別中,randPerson隨機選擇Person物件的句柄。 **上訴造型是在return語句裡發(fā)生的。 **return語句取得一個Boy或Girl的句柄並將其作為Person類型傳回,此時並不知道具體是什麼類型,只知道是Person物件句柄。

在main方法中呼叫randPerson方法為數(shù)組填入Person對象,但不知具體情況。當呼叫數(shù)組每個元素的eat方法時,動態(tài)綁定的作用就是執(zhí)行物件的重新定義了的方法。

然而,動態(tài)綁定是有前提的,綁定的方法必須存在於基底類別中,否則無法編譯通過。

class Person {
    void eat() {
        System.out.println("Person.eat()");
    }
}
class Boy extends Person {
    void eat() {
        System.out.println("Boy.eat()");
    }
    void speak() {
        System.out.println("Boy.speak()");
    }
}
public class Persons {
    public static void main(String[] args) {
        Person p = new Boy();
        p.eat();
        p.speak();  // The method speak() is undefined for the type Person
    }
}

如果子類中沒有定義覆蓋方法,則會調(diào)用父類中的方法:

class Person {
    void eat() {
        System.out.println("Person.eat()");
    }
}
class Boy extends Person {
}
public class Persons {
    public static void main(String[] args) {
        Person p = new Boy();
        p.eat();
    }
}

【運行結果】:
Person.eat()

2.靜態(tài)方法的綁定

將上面的方法都加上static關鍵字,變成靜態(tài)方法:

class Person {
    static void eat() {
        System.out.println("Person.eat()");
    }
    static void speak() {
        System.out.println("Person.speak()");
    }
}
class Boy extends Person {
    static void eat() {
        System.out.println("Boy.eat()");
    }
    static void speak() {
        System.out.println("Boy.speak()");
    }
}
class Girl extends Person {
    static void eat() {
        System.out.println("Girl.eat()");
    }
    static void speak() {
        System.out.println("Girl.speak()");
    }
}
public class Persons {
    public static Person randPerson() {
        switch ((int)(Math.random() * 2)) {
        default:
        case 0:
            return new Boy();
        case 1:
            return new Girl();
        }
    }
    public static void main(String[] args) {
        Person[] p = new Person[4];
        for (int i = 0; i < p.length; i++) {
            p[i] = randPerson();    // 隨機生成Boy或Girl
        }
        for (int i = 0; i < p.length; i++) {
            p[i].eat();
        }
    }
}

【運行結果】:

Person.eat() 
Person.eat() 
Person.eat() 
Person.eat()

觀察結果,對于靜態(tài)方法而言,不管父類引用指向的什么子類對象,調(diào)用的都是父類的方法。

更多java相關文章請關注java基礎教程欄目。

以上是Java中繼承圖文詳解的詳細內(nèi)容。更多資訊請關注PHP中文網(wǎng)其他相關文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發(fā)現(xiàn)涉嫌抄襲或侵權的內(nèi)容,請聯(lián)絡admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1601
29
PHP教程
1502
276
如何使用JDBC處理Java的交易? 如何使用JDBC處理Java的交易? Aug 02, 2025 pm 12:29 PM

要正確處理JDBC事務,必須先關閉自動提交模式,再執(zhí)行多個操作,最後根據(jù)結果提交或回滾;1.調(diào)用conn.setAutoCommit(false)以開始事務;2.執(zhí)行多個SQL操作,如INSERT和UPDATE;3.若所有操作成功則調(diào)用conn.commit(),若發(fā)生異常則調(diào)用conn.rollback()確保數(shù)據(jù)一致性;同時應使用try-with-resources管理資源,妥善處理異常並關閉連接,避免連接洩漏;此外建議使用連接池、設置保存點實現(xiàn)部分回滾,並保持事務盡可能短以提升性能。

如何使用Java的日曆? 如何使用Java的日曆? Aug 02, 2025 am 02:38 AM

使用java.time包中的類替代舊的Date和Calendar類;2.通過LocalDate、LocalDateTime和LocalTime獲取當前日期時間;3.使用of()方法創(chuàng)建特定日期時間;4.利用plus/minus方法不可變地增減時間;5.使用ZonedDateTime和ZoneId處理時區(qū);6.通過DateTimeFormatter格式化和解析日期字符串;7.必要時通過Instant與舊日期類型兼容;現(xiàn)代Java中日期處理應優(yōu)先使用java.timeAPI,它提供了清晰、不可變且線

比較Java框架:Spring Boot vs Quarkus vs Micronaut 比較Java框架:Spring Boot vs Quarkus vs Micronaut Aug 04, 2025 pm 12:48 PM

前形式攝取,quarkusandmicronautleaddueTocile timeProcessingandGraalvSupport,withquarkusoftenpernperforminglightbetterine nosserless notelless centarios.2。

了解網(wǎng)絡端口和防火牆 了解網(wǎng)絡端口和防火牆 Aug 01, 2025 am 06:40 AM

NetworkPortSandFireWallsworkTogetHertoEnableCommunication whereSeringSecurity.1.NetWorkPortSareVirtualendPointSnumbered0-655 35,with-Well-with-Newonportslike80(HTTP),443(https),22(SSH)和25(smtp)sindiessingspefificservices.2.portsoperateervertcp(可靠,c

垃圾收集如何在Java工作? 垃圾收集如何在Java工作? Aug 02, 2025 pm 01:55 PM

Java的垃圾回收(GC)是自動管理內(nèi)存的機制,通過回收不可達對象釋放堆內(nèi)存,減少內(nèi)存洩漏風險。 1.GC從根對象(如棧變量、活動線程、靜態(tài)字段等)出發(fā)判斷對象可達性,無法到達的對像被標記為垃圾。 2.基於標記-清除算法,標記所有可達對象,清除未標記對象。 3.採用分代收集策略:新生代(Eden、S0、S1)頻繁執(zhí)行MinorGC;老年代執(zhí)行較少但耗時較長的MajorGC;Metaspace存儲類元數(shù)據(jù)。 4.JVM提供多種GC器:SerialGC適用於小型應用;ParallelGC提升吞吐量;CMS降

比較Java構建工具:Maven vs. Gradle 比較Java構建工具:Maven vs. Gradle Aug 03, 2025 pm 01:36 PM

Gradleisthebetterchoiceformostnewprojectsduetoitssuperiorflexibility,performance,andmoderntoolingsupport.1.Gradle’sGroovy/KotlinDSLismoreconciseandexpressivethanMaven’sverboseXML.2.GradleoutperformsMaveninbuildspeedwithincrementalcompilation,buildcac

以身作則,解釋說明 以身作則,解釋說明 Aug 02, 2025 am 06:26 AM

defer用於在函數(shù)返回前執(zhí)行指定操作,如清理資源;參數(shù)在defer時立即求值,函數(shù)按後進先出(LIFO)順序執(zhí)行;1.多個defer按聲明逆序執(zhí)行;2.常用於文件關閉等安全清理;3.可修改命名返回值;4.即使發(fā)生panic也會執(zhí)行,適合用於recover;5.避免在循環(huán)中濫用defer,防止資源洩漏;正確使用可提升代碼安全性和可讀性。

使用HTML'輸入類型”作為用戶數(shù)據(jù) 使用HTML'輸入類型”作為用戶數(shù)據(jù) Aug 03, 2025 am 11:07 AM

選擇合適的HTMLinput類型能提升數(shù)據(jù)準確性、增強用戶體驗並提高可用性。 1.根據(jù)數(shù)據(jù)類型選用對應input類型,如text、email、tel、number和date,可實現(xiàn)自動校驗和適配鍵盤;2.利用HTML5新增類型如url、color、range和search,可提供更直觀的交互方式;3.配合使用placeholder和required屬性,可提升表單填寫效率和正確率,但需注意placeholder不能替代label。

See all articles