国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承

這篇具有很好參考價(jià)值的文章主要介紹了【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

目錄

為什么需要繼承

繼承的概念

繼承的語(yǔ)法

注意事項(xiàng)

?父類成員訪問(wèn)

子類中訪問(wèn)父類的成員變量

子類和父類不存在同名成員變量

子類和父類成員變量同名

訪問(wèn)原則

子類中訪問(wèn)父類的成員方法

成員方法名字不同

總結(jié):

成員方法名字相同

總結(jié):

super關(guān)鍵字

注意事項(xiàng)

子類構(gòu)造方法

注意事項(xiàng)

super和this

相同點(diǎn)

不同點(diǎn)

再談初始化

繼承關(guān)系上的執(zhí)行順序

?編輯?結(jié)論:

?protected 關(guān)鍵字

同一個(gè)包中的子類

不同包中的子類

?不同包中的類

注意:

限定修飾符使用的時(shí)機(jī)

繼承方式

注意事項(xiàng)?

final 關(guān)鍵字

修飾變量或字段

修飾類

修飾方法

繼承與組合

總結(jié)


為什么需要繼承

Java中使用類對(duì)現(xiàn)實(shí)世界中實(shí)體來(lái)進(jìn)行描述,類經(jīng)過(guò)實(shí)例化之后的產(chǎn)物對(duì)象,則可以用來(lái)表示現(xiàn)實(shí)中的實(shí)體,但是現(xiàn)實(shí)世界錯(cuò)綜復(fù)雜,事物之間可能會(huì)存在一些關(guān)聯(lián),那在設(shè)計(jì)程序是就需要考慮。

比如:狗和貓,它們都是一個(gè)動(dòng)物

【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承,javaSE,java,開(kāi)發(fā)語(yǔ)言,繼承

如果我們需要用java語(yǔ)言來(lái)描述它們,我們會(huì)寫(xiě)出以下代碼

比如狗類

     public class Dog{
        string name;
        int age;
        float weight;
        public void eat(){
            System.out.println(name + "正在吃飯");
        }
        public void sleep(){
            System.out.println(name + "正在睡覺(jué)");
        }
        void Bark(){
            System.out.println(name + "汪汪汪~(yú)~~");
        }
    }

?貓類

    public class Cat{
        string name;
        int age;
        float weight;
        public void eat(){
            System.out.println(name + "正在吃飯");
        }
        public void sleep()
        {
            System.out.println(name + "正在睡覺(jué)");
        }
        void mew(){
            System.out.println(name + "喵喵喵~~~");
        }
    }

通過(guò)觀察上述代碼會(huì)發(fā)現(xiàn),貓和狗的類中存在大量重復(fù),如下所示

【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承,javaSE,java,開(kāi)發(fā)語(yǔ)言,繼承

那能否將這些共性抽取呢?面向?qū)ο笏枷胫刑岢隽死^承的概念,專門用來(lái)進(jìn)行共性抽取,實(shí)現(xiàn)代碼復(fù)用。

繼承的概念

繼承(inheritance)機(jī)制:是面向?qū)ο蟪绦蛟O(shè)計(jì)使代碼可以復(fù)用的最重要的手段,它允許程序員在保持原有類特 性的基礎(chǔ)上進(jìn)行擴(kuò)展,增加新功能,這樣產(chǎn)生新的類,稱派生類。繼承呈現(xiàn)了面向?qū)ο蟪绦蛟O(shè)計(jì)的層次結(jié)構(gòu), 體現(xiàn)了由簡(jiǎn)單到復(fù)雜的認(rèn)知過(guò)程。繼承主要解決的問(wèn)題是:共性的抽取,實(shí)現(xiàn)代碼復(fù)用。

例如:狗和貓都是動(dòng)物,那么我們就可以將共性的內(nèi)容進(jìn)行抽取,然后采用繼承的思想來(lái)達(dá)到共用
【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承,javaSE,java,開(kāi)發(fā)語(yǔ)言,繼承

上述圖示中,Dog和Cat都繼承了Animal類,其中:Animal類稱為父類/基類或超類,Dog和Cat可以稱為Animal的子類/派生類,繼承之后,子類可以復(fù)用父類中成員,子類在實(shí)現(xiàn)時(shí)只需關(guān)心自己新增加的成員即可。

從繼承概念中可以看出繼承最大的作用就是:實(shí)現(xiàn)代碼復(fù)用,還有就是來(lái)實(shí)現(xiàn)多態(tài)(后序講)

繼承的語(yǔ)法

在Java中如果要表示類之間的繼承關(guān)系,需要借助extends關(guān)鍵字,具體如下:

修飾符 class 子類 extends 父類 {
    // ...
}

然后我們對(duì)上述代碼進(jìn)行改造以下,帶大家感受一下繼承

首先把狗類與貓類所擁有的共同元素書(shū)寫(xiě)成一個(gè)Animal類

public class Animal{
    String name;
    int age;
    public void eat() {
        System.out.println(name + "正在吃飯");
    }
    public void sleep() {
        System.out.println(name + "正在睡覺(jué)");
    }
}

接下來(lái)我們用繼承來(lái)實(shí)現(xiàn)一下我們的Dog類

public class Dog extends Animal{
    void bark(){
        System.out.println(name + "汪汪汪~(yú)~~");
    }
}

Cat類同理

public class Cat extends Animal{
    void mew(){
        System.out.println(name + "喵喵喵~~~");
    }
}

實(shí)例化對(duì)象如下

public class TestExtend {
    public static void main(String[] args) {
        Dog dog = new Dog();
        // dog類中并沒(méi)有定義任何成員變量,name和age屬性肯定是從父類Animal中繼承下來(lái)的
        System.out.println(dog.name);
        System.out.println(dog.age);
        // dog訪問(wèn)的eat()和sleep()方法也是從Animal中繼承下來(lái)的
        dog.eat();
        dog.sleep();
        dog.bark();
    }
}

注意事項(xiàng)

1. 子類會(huì)將父類中的成員變量或者成員方法繼承到子類中了
2. 子類繼承父類之后,必須要新添加自己特有的成員,體現(xiàn)出與基類的不同,否則就沒(méi)有必要繼承了

?父類成員訪問(wèn)

在繼承體系中,子類將父類中的方法和字段繼承下來(lái)了,那在子類中能否直接訪問(wèn)父類中繼承下來(lái)的成員呢?

子類中訪問(wèn)父類的成員變量

子類和父類不存在同名成員變量

public class Base {
    int a;
    int b;
}
public class Derived extends Base{
    int c;
    public void method(){
        a = 10; // 訪問(wèn)從父類中繼承下來(lái)的a
        b = 20; // 訪問(wèn)從父類中繼承下來(lái)的b
        c = 30; // 訪問(wèn)子類自己的c
    }
}

子類和父類成員變量同名

public class Base {
    int a;
    int b;
    int c;
} 

/
public class Derived extends Base{
    int a; // 與父類中成員a同名,且類型相同
    char b; // 與父類中成員b同名,但類型不同
    public void method(){
        a = 100; // 訪問(wèn)子類自己新增的a
        b = 101; // 訪問(wèn)子類自己新增的b
        c = 102; // 子類沒(méi)有c,訪問(wèn)的肯定是從父類繼承下來(lái)的c
        // d = 103; // 編譯失敗,因?yàn)楦割惡妥宇惗紱](méi)有定義成員變量b
}
}

訪問(wèn)原則

在子類方法中 或者 通過(guò)子類對(duì)象訪問(wèn)成員時(shí):

如果訪問(wèn)的成員變量子類中有,優(yōu)先訪問(wèn)自己的成員變量。
如果訪問(wèn)的成員變量子類中無(wú),則訪問(wèn)父類繼承下來(lái)的,如果父類也沒(méi)有定義,則編譯報(bào)錯(cuò)。
如果訪問(wèn)的成員變量與父類中成員變量同名,則優(yōu)先訪問(wèn)自己的。

成員變量訪問(wèn)遵循就近原則,自己有優(yōu)先自己的,如果沒(méi)有則向父類中找

子類中訪問(wèn)父類的成員方法

成員方法名字不同

public class Base {
    public void methodA(){
        System.out.println("Base中的methodA()");
    }
}
public class Derived extends Base{
    public void methodB(){
        System.out.println("Derived中的methodB()方法");
    }
    public void methodC(){
        methodB(); // 訪問(wèn)子類自己的methodB()
        methodA(); // 訪問(wèn)父類繼承的methodA()
// methodD(); // 編譯失敗,在整個(gè)繼承體系中沒(méi)有發(fā)現(xiàn)方法methodD()
    }
}
總結(jié):

成員方法沒(méi)有同名時(shí),在子類方法中或者通過(guò)子類對(duì)象訪問(wèn)方法時(shí),則優(yōu)先訪問(wèn)自己的,自己沒(méi)有時(shí),再到父類中找,如果父類中也沒(méi)有則報(bào)錯(cuò)。

成員方法名字相同

public class Base {
    public void methodA(){
        System.out.println("Base中的methodA()");
    }
    public void methodB(){
        System.out.println("Base中的methodB()");
    }
}
public class Derived extends Base{
    public void methodA(int a) {
        System.out.println("Derived中的method(int)方法");
    }
    public void methodB(){
        System.out.println("Derived中的methodB()方法");
    }
    public void methodC(){
        methodA(); // 沒(méi)有傳參,訪問(wèn)父類中的methodA()
        methodA(20); // 傳遞int參數(shù),訪問(wèn)子類中的methodA(int)
        methodB(); // 直接訪問(wèn),則永遠(yuǎn)訪問(wèn)到的都是子類中的methodB(),基類的無(wú)法訪問(wèn)到
    }
}
總結(jié):

1、通過(guò)子類對(duì)象訪問(wèn)父類與子類中不同名方法時(shí),優(yōu)先在子類中找,找到則訪問(wèn),否則在父類中找,找到則訪問(wèn),否則編譯報(bào)錯(cuò)。

2、通過(guò)派生類對(duì)象訪問(wèn)父類與子類同名方法時(shí),如果父類和子類同名方法的參數(shù)列表不同(重載),根據(jù)調(diào)用方法適傳遞的參數(shù)選擇合適的方法訪問(wèn),如果沒(méi)有則報(bào)錯(cuò);

那么問(wèn)題來(lái)了,如果子類中存在與父類中相同的成員時(shí),那如何在子類中訪問(wèn)父類相同名稱的成員呢?請(qǐng)看下文

super關(guān)鍵字

由于設(shè)計(jì)不好,或者因場(chǎng)景需要,子類和父類中可能會(huì)存在相同名稱的成員,如果要在子類方法中訪問(wèn)父類同名成員時(shí),該如何操作?

直接訪問(wèn)是無(wú)法做到的,Java提供了super關(guān)鍵字,該關(guān)鍵字主要作用:在子類方法中訪問(wèn)父
類的成員

例如我這兒有一個(gè)Base類

public class Base {
    int a;
    int b;
    public void methodA(){
        System.out.println("Base中的methodA()");
    }
    public void methodB(){
        System.out.println("Base中的methodB()");
    }
}

我們將它作為父類,我們現(xiàn)在有一個(gè)子類Derived類

public class Derived extends Base{
    int a; // 與父類中成員變量同名且類型相同
    char b; // 與父類中成員變量同名但類型不同
    // 與父類中methodA()構(gòu)成重載
    public void methodA(int a) {
        System.out.println("Derived中的method()方法");
    } 
    // 與基類中methodB()構(gòu)成重寫(xiě)(即原型一致,重寫(xiě)后序詳細(xì)介紹)
    public void methodB(){
        System.out.println("Derived中的methodB()方法");
    }
    public void methodC(){
// 對(duì)于同名的成員變量,直接訪問(wèn)時(shí),訪問(wèn)的都是子類的
        a = 100; // 等價(jià)于: this.a = 100;
        b = 101; // 等價(jià)于: this.b = 101;
// 注意:this是當(dāng)前對(duì)象的引用
// 訪問(wèn)父類的成員變量時(shí),需要借助super關(guān)鍵字
// super是獲取到子類對(duì)象中從基類繼承下來(lái)的部分
        super.a = 200;
        super.b = 201;
// 父類和子類中構(gòu)成重載的方法,直接可以通過(guò)參數(shù)列表區(qū)分清訪問(wèn)父類還是子類方法
        methodA(); // 沒(méi)有傳參,訪問(wèn)父類中的methodA()
        methodA(20); // 傳遞int參數(shù),訪問(wèn)子類中的methodA(int)
// 如果在子類中要訪問(wèn)重寫(xiě)的基類方法,則需要借助super關(guān)鍵字
        methodB(); // 直接訪問(wèn),則永遠(yuǎn)訪問(wèn)到的都是子類中的methodA(),基類的無(wú)法訪問(wèn)到
        super.methodB(); // 訪問(wèn)基類的methodB()
    }
}
public class Base {
    public Base() {
        System.out.println("Base()");
    }
}

在子類方法中,如果想要明確訪問(wèn)父類中成員時(shí),借助super關(guān)鍵字即可

注意事項(xiàng)

1. 只能在非靜態(tài)方法中使用
2. 在子類方法中,訪問(wèn)父類的成員變量和方法

子類構(gòu)造方法

父子父子,先有父再有子,即:子類對(duì)象構(gòu)造時(shí),需要先調(diào)用基類構(gòu)造方法,然后執(zhí)行子類的構(gòu)造方法

public class Base {
    public Base(){
        System.out.println("Base()");
    }
}
public class Derived extends Base{
    public Derived(){
// super(); // 注意子類構(gòu)造方法中默認(rèn)會(huì)調(diào)用基類的無(wú)參構(gòu)造方法:super(),
// 用戶沒(méi)有寫(xiě)時(shí),編譯器會(huì)自動(dòng)添加,而且super()必須是子類構(gòu)造方法中第一條語(yǔ)句,
// 并且只能出現(xiàn)一次
        System.out.println("Derived()");
    }
}
public class Test {
    public static void main(String[] args) {
        Derived d = new Derived();
    }
}

結(jié)果為

【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承,javaSE,java,開(kāi)發(fā)語(yǔ)言,繼承

?在子類構(gòu)造方法中,并沒(méi)有寫(xiě)任何關(guān)于基類構(gòu)造的代碼,但是在構(gòu)造子類對(duì)象時(shí),先執(zhí)行基類的構(gòu)造方法,然后執(zhí)行子類的構(gòu)造方法

因?yàn)椋鹤宇悓?duì)象中成員是有兩部分組成的,基類繼承下來(lái)的以及子類新增加的部分 。父子父子肯定是先有父再有子,所以在構(gòu)造子類對(duì)象時(shí)候 ,先要調(diào)用基類的構(gòu)造方法,將從基類繼承下來(lái)的成員構(gòu)造完整,然后再調(diào)用子類自己的構(gòu)造方法,將子類自己新增加的成員初始化完整 。

注意事項(xiàng)

1. 若父類顯式定義無(wú)參或者默認(rèn)的構(gòu)造方法,在子類構(gòu)造方法第一行默認(rèn)有隱含的super()調(diào)用,即調(diào)用基類構(gòu)造方法
2. 如果父類構(gòu)造方法是帶有參數(shù)的,此時(shí)需要用戶為子類顯式定義構(gòu)造方法,并在子類構(gòu)造方法中選擇合適的父類構(gòu)造方法調(diào)用,否則編譯失敗。

【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承,javaSE,java,開(kāi)發(fā)語(yǔ)言,繼承
3. 在子類構(gòu)造方法中,super(...)調(diào)用父類構(gòu)造時(shí),必須是子類構(gòu)造函數(shù)中第一條語(yǔ)句。

【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承,javaSE,java,開(kāi)發(fā)語(yǔ)言,繼承
4. super(...)只能在子類構(gòu)造方法中出現(xiàn)一次,并且不能和this同時(shí)出現(xiàn)

【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承,javaSE,java,開(kāi)發(fā)語(yǔ)言,繼承

【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承,javaSE,java,開(kāi)發(fā)語(yǔ)言,繼承

super和this

super和this都可以在成員方法中用來(lái)訪問(wèn):成員變量和調(diào)用其他的成員函數(shù),都可以作為構(gòu)造方法的第一條語(yǔ)句,

那他們之間有什么區(qū)別呢?

相同點(diǎn)

1. 都是Java中的關(guān)鍵字

2. 只能在類的非靜態(tài)方法中使用,用來(lái)訪問(wèn)非靜態(tài)成員方法和字段

3. 在構(gòu)造方法中調(diào)用時(shí),必須是構(gòu)造方法中的第一條語(yǔ)句,并且不能同時(shí)存在

不同點(diǎn)

1. this是當(dāng)前對(duì)象的引用,當(dāng)前對(duì)象即調(diào)用實(shí)例方法的對(duì)象,super相當(dāng)于是子類對(duì)象中從父類繼承下來(lái)部分成員的引用

【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承,javaSE,java,開(kāi)發(fā)語(yǔ)言,繼承

2. 在非靜態(tài)成員方法中,this用來(lái)訪問(wèn)本類的方法和屬性,super用來(lái)訪問(wèn)父類繼承下來(lái)的方法和屬性

3. 在構(gòu)造方法中:this(...)用于調(diào)用本類構(gòu)造方法,super(...)用于調(diào)用父類構(gòu)造方法,兩種調(diào)用不能同時(shí)在構(gòu)造方法中出現(xiàn)

4. 構(gòu)造方法中一定會(huì)存在super(...)的調(diào)用,用戶沒(méi)有寫(xiě)編譯器也會(huì)增加,但是this(...)用戶不寫(xiě)則沒(méi)有

再談初始化

我們還記得之前講過(guò)的代碼塊嗎?我們簡(jiǎn)單回顧一下幾個(gè)重要的代碼塊:實(shí)例代碼塊和靜態(tài)代碼塊。在沒(méi)有繼承關(guān)系時(shí)的執(zhí)行順序。

class Person {
    public String name;
    public int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("構(gòu)造方法執(zhí)行");
    }
    {
        System.out.println("實(shí)例代碼塊執(zhí)行");
    } 
    static {
        System.out.println("靜態(tài)代碼塊執(zhí)行");
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Person person1 = new Person("bit",10);
        System.out.println("============================");
        Person person2 = new Person("gaobo",20);
    }
}

運(yùn)行結(jié)果如下

【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承,javaSE,java,開(kāi)發(fā)語(yǔ)言,繼承

我們發(fā)現(xiàn)執(zhí)行順序

1. 靜態(tài)代碼塊先執(zhí)行,并且只執(zhí)行一次,在類加載階段執(zhí)行

2. 當(dāng)有對(duì)象創(chuàng)建時(shí),才會(huì)執(zhí)行實(shí)例代碼塊,實(shí)例代碼塊執(zhí)行完成后,最后構(gòu)造方法執(zhí)行

繼承關(guān)系上的執(zhí)行順序

為了看清楚著中間的執(zhí)行順序,我們有以下代碼

class Person {
    public String name;
    public int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("Person:構(gòu)造方法執(zhí)行");
    }

    {
        System.out.println("Person:實(shí)例代碼塊執(zhí)行");
    }

    static {
        System.out.println("Person:靜態(tài)代碼塊執(zhí)行");
    }
}

class Student extends Person{
    public Student(String name,int age) {
        super(name,age);
        System.out.println("Student:構(gòu)造方法執(zhí)行");
    }

    {
        System.out.println("Student:實(shí)例代碼塊執(zhí)行");
    }

    static {
        System.out.println("Student:靜態(tài)代碼塊執(zhí)行");
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Student student1 = new Student("張三",19);
        System.out.println("===========================");
        Student student2 = new Student("gaobo",20);
    }
    public static void main1(String[] args) {
        Person person1 = new Person("bit",10);
        System.out.println("============================");
        Person person2 = new Person("gaobo",20);
    }
}

運(yùn)行結(jié)果

?結(jié)論:

1、父類靜態(tài)代碼塊優(yōu)先于子類靜態(tài)代碼塊執(zhí)行,且是最早執(zhí)行

2、父類實(shí)例代碼塊和父類構(gòu)造方法緊接著執(zhí)行

3、子類的實(shí)例代碼塊和子類構(gòu)造方法緊接著再執(zhí)行

4、第二次實(shí)例化子類對(duì)象時(shí),父類和子類的靜態(tài)代碼塊都將不會(huì)再執(zhí)行
?

?protected 關(guān)鍵字

在類和對(duì)象章節(jié)中,為了實(shí)現(xiàn)封裝特性,Java中引入了訪問(wèn)限定符,主要限定:類或者類中成員能否在類外或者其他包中被訪問(wèn)。

【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承,javaSE,java,開(kāi)發(fā)語(yǔ)言,繼承

那父類中不同訪問(wèn)權(quán)限的成員,在子類中的可見(jiàn)性又是什么樣子的呢?

比如我們現(xiàn)在有一個(gè)父類叫B類,我將它放在extend01包中


public class B {
    private int a;
    protected int b;
    public int c;
    int d;
}

同一個(gè)包中的子類

D類我也放在extend01包中

public class D extends B{
    public void method(){
        // super.a = 10; // 編譯報(bào)錯(cuò),父類private成員在相同包子類中不可見(jiàn)
        super.b = 20; // 父類中protected成員在相同包子類中可以直接訪問(wèn)
        super.c = 30; // 父類中public成員在相同包子類中可以直接訪問(wèn)
        super.d = 40; // 父類中默認(rèn)訪問(wèn)權(quán)限修飾的成員在相同包子類中可以直接訪問(wèn)
    }
}

不同包中的子類

我將C類放在extend02包中

public class C extends B {
    public void method(){
        // super.a = 10; // 編譯報(bào)錯(cuò),父類中private成員在不同包子類中不可見(jiàn)
        super.b = 20; // 父類中protected修飾的成員在不同包子類中可以直接訪問(wèn)
        super.c = 30; // 父類中public修飾的成員在不同包子類中可以直接訪問(wèn)
        //super.d = 40; // 父類中默認(rèn)訪問(wèn)權(quán)限修飾的成員在不同包子類中不能直接訪問(wèn)
    }
}

?不同包中的類

在剛剛那個(gè)包創(chuàng)建C類的基礎(chǔ)上,在再該包創(chuàng)建一個(gè)TestC類,并加入我們的主函數(shù)

public class TestC {
    public static void main(String[] args) {
        C c = new C();
        c.method();
        // System.out.println(c.a); // 編譯報(bào)錯(cuò),父類中private成員在不同包其他類中不可見(jiàn)
        // System.out.println(c.b); // 父類中protected成員在不同包其他類中不能直接訪問(wèn)
        System.out.println(c.c); // 父類中public成員在不同包其他類中可以直接訪問(wèn)
        // System.out.println(c.d); // 父類中默認(rèn)訪問(wèn)權(quán)限修飾的成員在不同包其他類中不能直接訪問(wèn)
    }
}

注意:

父類中private成員變量雖然在子類中不能直接訪問(wèn),但是也繼承到子類中了

限定修飾符使用的時(shí)機(jī)

這么多限定修飾符,那我們應(yīng)該在什么時(shí)候用什么修飾符呢?

相信很多人都有這樣的疑問(wèn)

我們希望類要盡量做到 "封裝", 即隱藏內(nèi)部實(shí)現(xiàn)細(xì)節(jié), 只暴露出 必要 的信息給類的調(diào)用者.
因此我們?cè)谑褂玫臅r(shí)候應(yīng)該盡可能的使用 比較嚴(yán)格 的訪問(wèn)權(quán)限. 例如如果一個(gè)方法能用 private, 就盡量不要用 public.


另外, 還有一種 簡(jiǎn)單粗暴 的做法: 將所有的字段設(shè)為 private, 將所有的方法設(shè)為 public. 不過(guò)這種方式屬于是對(duì)訪問(wèn)權(quán)限的濫用, 還是更希望同學(xué)們能寫(xiě)代碼的時(shí)候認(rèn)真思考, 該類提供的字段方法到底給 "誰(shuí)" 使用(是類內(nèi)部自己用, 還是類的調(diào)用者使用, 還是子類使用)
?

繼承方式

在現(xiàn)實(shí)生活中,事物之間的關(guān)系是非常復(fù)雜,靈活多樣,比如:

【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承,javaSE,java,開(kāi)發(fā)語(yǔ)言,繼承

但在Java中只支持以下幾種繼承方式:

【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承,javaSE,java,開(kāi)發(fā)語(yǔ)言,繼承

注意事項(xiàng)?

Java中不支持多繼承。

時(shí)刻牢記, 我們寫(xiě)的類是現(xiàn)實(shí)事物的抽象. 而我們真正在公司中所遇到的項(xiàng)目往往業(yè)務(wù)比較復(fù)雜, 可能會(huì)涉及到一系列復(fù)雜的概念, 都需要我們使用代碼來(lái)表示, 所以我們真實(shí)項(xiàng)目中所寫(xiě)的類也會(huì)有很多. 類之間的關(guān)系也會(huì)更加復(fù)雜.


但是即使如此, 我們并不希望類之間的繼承層次太復(fù)雜. 一般我們不希望出現(xiàn)超過(guò)三層的繼承關(guān)系. 如果繼承層次太多, 就需要考慮對(duì)代碼進(jìn)行重構(gòu)了.

有些同學(xué)就想我能不能不讓別人繼承我的呢??

當(dāng)然是可以的,如果想從語(yǔ)法上進(jìn)行限制繼承, 就可以使用 final 關(guān)鍵字

final 關(guān)鍵字

final關(guān)鍵可以用來(lái)修飾變量、成員方法以及類。

修飾變量或字段

表示常量(即不能修改)

final int a = 10;
a = 20; // 編譯出錯(cuò)

修飾類

表示此類不能被繼承

final public class Animal {
...
}

public class Bird extends Animal {
...
} 

// 編譯出錯(cuò)
Error:(3, 27) java: 無(wú)法從最終com.bit.Animal進(jìn)行繼

【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承,javaSE,java,開(kāi)發(fā)語(yǔ)言,繼承

我們平時(shí)是用的 String 字符串類, 就是用 final 修飾的, 不能被繼承

修飾方法

表示該方法不能被重寫(xiě),博主會(huì)在后續(xù)進(jìn)行介紹

繼承與組合

和繼承類似, 組合也是一種表達(dá)類之間關(guān)系的方式, 也是能夠達(dá)到代碼重用的效果。組合并沒(méi)有涉及到特殊的語(yǔ)法(諸如 extends 這樣的關(guān)鍵字), 僅僅是將一個(gè)類的實(shí)例作為另外一個(gè)類的字段。

繼承表示對(duì)象之間是is-a的關(guān)系,比如:狗是動(dòng)物,貓是動(dòng)物

組合表示對(duì)象之間是has-a的關(guān)系,比如:汽車

【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承,javaSE,java,開(kāi)發(fā)語(yǔ)言,繼承

汽車和其輪胎、發(fā)動(dòng)機(jī)、方向盤、車載系統(tǒng)等的關(guān)系就應(yīng)該是組合,因?yàn)槠囀怯羞@些部件組成的?

// 輪胎類
class Tire{
// ...
} 

// 發(fā)動(dòng)機(jī)類
class Engine{
// ...
} 

// 車載系統(tǒng)類
class VehicleSystem{
// ...
}
class Car{
    private Tire tire; // 可以復(fù)用輪胎中的屬性和方法
    private Engine engine; // 可以復(fù)用發(fā)動(dòng)機(jī)中的屬性和方法
    private VehicleSystem vs; // 可以復(fù)用車載系統(tǒng)中的屬性和方法
// ...
} 
// 奔馳是汽車
class Benz extend Car{
// 將汽車中包含的:輪胎、發(fā)送機(jī)、車載系統(tǒng)全部繼承下來(lái)
}

組合和繼承都可以實(shí)現(xiàn)代碼復(fù)用,應(yīng)該使用繼承還是組合,需要根據(jù)應(yīng)用場(chǎng)景來(lái)選擇,一般建議:能用組合盡量用組合

如果有同學(xué)想詳細(xì)了解繼承與組合可以點(diǎn)下方鏈接,進(jìn)行了解,我這里就不做過(guò)多贅述了

深入理解Java中的組合和繼承-HollisChuang's Bloghttps://www.hollischuang.com/archives/1319

總結(jié)

關(guān)于《面向?qū)ο蟪绦蛉筇匦灾^承》就講解到這兒,歡迎各位留言交流以及批評(píng)指正,如果文章對(duì)您有幫助或者覺(jué)得作者寫(xiě)的還不錯(cuò)可以點(diǎn)一下關(guān)注,點(diǎn)贊,收藏支持一下。


?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-621171.html

到了這里,關(guān)于【javaSE】 面向?qū)ο蟪绦蛉筇匦灾^承的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • C++ 面向?qū)ο笕筇匦浴^承

    C++ 面向?qū)ο笕筇匦浴^承

    ?1主頁(yè):我的代碼愛(ài)吃辣 ??2知識(shí)講解:C++ 繼承 ??3開(kāi)發(fā)環(huán)境:Visual Studio 2022 ??4前言:面向?qū)ο笕筇匦缘模庋b,繼承,多態(tài),今天我們研究研究 C++的繼承 。 目錄 一.繼承的概念及定義 1.繼承的概念 ?2.繼承的定義 二. 繼承關(guān)系和訪問(wèn)限定符 ?三.基類和派生類對(duì)象賦

    2024年02月12日
    瀏覽(23)
  • 【JAVASE】帶你了解面向?qū)ο笕筇匦灾唬ǘ鄳B(tài))

    【JAVASE】帶你了解面向?qū)ο笕筇匦灾唬ǘ鄳B(tài))

    ?作者簡(jiǎn)介:大家好,我是橘橙黃又青,一個(gè)想要與大家共同進(jìn)步的男人???? ??個(gè)人主頁(yè):再無(wú)B~U~G-CSDN博客 多態(tài)的概念:通俗來(lái)說(shuō),就是多種形態(tài), 具體點(diǎn)就是去完成某個(gè)行為,當(dāng)不同的對(duì)象去完成時(shí)會(huì)產(chǎn)生出不同 的狀 態(tài)。 總的來(lái)說(shuō):同一件事情,發(fā)生在不同對(duì)象

    2024年04月14日
    瀏覽(91)
  • 面向?qū)ο蟮娜筇匦灾^承(C++)

    面向?qū)ο蟮娜筇匦灾^承(C++)

    概念 ??繼承機(jī)制是面向?qū)ο缶幘幊淌勾a可以復(fù)用的最重要的手段,它允許程序員在保持原有類特性的基礎(chǔ)上進(jìn)行擴(kuò)展,增加功能,這樣產(chǎn)生新的類,稱為派生類。繼承呈現(xiàn)了面向?qū)ο蟪绦蛟O(shè)計(jì)的層次結(jié)構(gòu),體現(xiàn)了由簡(jiǎn)單到復(fù)雜的認(rèn)知過(guò)程。繼承是類設(shè)計(jì)層次的復(fù)用。 定

    2024年02月06日
    瀏覽(46)
  • 【C++庖丁解牛】面向?qū)ο蟮娜筇匦灾欢鄳B(tài) | 抽象類 | 多態(tài)的原理 | 單繼承和多繼承關(guān)系中的虛函數(shù)表

    【C++庖丁解牛】面向?qū)ο蟮娜筇匦灾欢鄳B(tài) | 抽象類 | 多態(tài)的原理 | 單繼承和多繼承關(guān)系中的虛函數(shù)表

    ??你好,我是 RO-BERRY ?? 致力于C、C++、數(shù)據(jù)結(jié)構(gòu)、TCP/IP、數(shù)據(jù)庫(kù)等等一系列知識(shí) ??感謝你的陪伴與支持 ,故事既有了開(kāi)頭,就要畫(huà)上一個(gè)完美的句號(hào),讓我們一起加油 需要聲明的,本節(jié)課件中的代碼及解釋都是在vs2013下的x86程序中,涉及的指針都是4bytes。如果要其他平臺(tái)

    2024年04月10日
    瀏覽(28)
  • 【java】面向?qū)ο笕筇匦灾鄳B(tài)

    【java】面向?qū)ο笕筇匦灾鄳B(tài)

    ? ? ? ? 俗話說(shuō)的好,“一龍生九子,九子各不同”,這句話就蘊(yùn)含了面向?qū)ο笕筇匦灾坏亩鄳B(tài)的思想。那么多態(tài)具體有什么特點(diǎn)呢,就由博主來(lái)帶大家梳理一下吧?? 目錄 一、什么是多態(tài) 二、重寫(xiě) 三、向上轉(zhuǎn)型和向下轉(zhuǎn)型 1、向上轉(zhuǎn)型 2、向下轉(zhuǎn)型 四、多態(tài)的優(yōu)缺點(diǎn)

    2024年03月15日
    瀏覽(24)
  • 【Java SE語(yǔ)法篇】8.面向?qū)ο笕筇卣鳌庋b、繼承和多態(tài)

    【Java SE語(yǔ)法篇】8.面向?qū)ο笕筇卣鳌庋b、繼承和多態(tài)

    ??博客主頁(yè):愛(ài)敲代碼的小楊. ?專欄:《Java SE語(yǔ)法》 ??感謝大家點(diǎn)贊????收藏?評(píng)論???,您的三連就是我持續(xù)更新的動(dòng)力?? 面向?qū)ο笕筇匦裕悍庋b、繼承和多態(tài)。 在面向?qū)ο蟪淌皆O(shè)計(jì)方法中,封裝(英語(yǔ):Encapsulation)是指一種將抽象性函式接口的實(shí)現(xiàn)細(xì)節(jié)部

    2024年02月01日
    瀏覽(36)
  • 面向?qū)ο笤斀?,面向?qū)ο蟮娜筇卣鳎悍庋b、繼承、多態(tài)

    面向?qū)ο笤斀?,面向?qū)ο蟮娜筇卣鳎悍庋b、繼承、多態(tài)

    一、面向?qū)ο笈c面向過(guò)程 面向?qū)ο缶幊?(Object-Oriented Programming,簡(jiǎn)稱OOP)和 面向過(guò)程編程 (Procedural Programming,簡(jiǎn)稱PP)是兩種不同的 編程范式 。 面向?qū)ο缶幊虖?qiáng)調(diào)把問(wèn)題分解成對(duì)象,通過(guò)封裝、繼承和多態(tài)等機(jī)制,來(lái)處理對(duì)象之間的關(guān)系 。每個(gè)對(duì)象都可以獨(dú)立地處理自

    2024年02月21日
    瀏覽(23)
  • 【JavaSE】面向?qū)ο缶幊趟枷胫^承

    【JavaSE】面向?qū)ο缶幊趟枷胫^承

    ?【本節(jié)目標(biāo)】 1. 繼承 2. 組合 目錄 1.?為什么需要繼承 2.?繼承概念 3.?繼承的語(yǔ)法 4.?父類成員訪問(wèn) 4.1 子類中訪問(wèn)父類的成員變量 4.2 子類中訪問(wèn)父類的成員方法 5. super 6.?子類構(gòu)造方法 7. super和this 8. 再談初始化 9. protected 10. 繼承方式 11. final 12 繼承與

    2024年02月12日
    瀏覽(25)
  • 【面向?qū)ο笳Z(yǔ)言三大特性之 “多態(tài)”】

    【面向?qū)ο笳Z(yǔ)言三大特性之 “多態(tài)”】

    目錄 ?1. 多態(tài)的概念 1.1 概念 2. 多態(tài)的定義及實(shí)現(xiàn) 2.1多態(tài)的構(gòu)成條件 2.2 虛函數(shù) ?2.3虛函數(shù)的重寫(xiě) 2.4 C++11 override 和 final ?2.5 重載、覆蓋(重寫(xiě))、隱藏(重定義)的對(duì)比 ?3. 抽象類 3.1 概念 3.2 接口繼承和實(shí)現(xiàn)繼承 ?4.多態(tài)的原理 4.1虛函數(shù)表 ?4.2多態(tài)的原理 4.3 動(dòng)態(tài)綁定與靜態(tài)綁定

    2023年04月17日
    瀏覽(56)
  • 面向?qū)ο笕筇匦灾弧@承(上篇)

    面向?qū)ο笕筇匦灾弧@承(上篇)

    目錄 前文 一.什么是継承? 1.1 継承的定義 1.2 継承的格式 1.2.1 継承的使用格式 1.2.2 継承關(guān)系和訪問(wèn)限定符 二,基類和派生類對(duì)象復(fù)制轉(zhuǎn)換 三,継承中的作用域 四,派生類/子類中的默認(rèn)成員函數(shù) 六,継承與友元 ?六,継承與靜態(tài)成員 總結(jié) 本篇文章主要是詳解面向?qū)ο笕?/p>

    2024年02月03日
    瀏覽(19)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包