最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java面向程序的三大特性之封裝、繼承、多態(tài)詳解(最新整理)

 更新時(shí)間:2025年06月10日 16:56:08   作者:Code哈哈笑  
面向?qū)ο蟪绦蛉筇匦裕悍庋b、繼承、多態(tài),而類(lèi)和對(duì)象階段,主要研究的就是封裝特性,何為封裝呢?簡(jiǎn)單來(lái)說(shuō)就是套殼屏蔽細(xì)節(jié),本文給大家介紹Java面向程序的三大特性之封裝、繼承、多態(tài),感興趣的朋友一起看看吧

1. 封裝

1.1 什么是封裝呢?

我們生活中使用的很多電子產(chǎn)品都是封裝好的,有的部分讓我們看到,有的部分不讓我們看到。比如機(jī)械手表,它的指針指向的時(shí)間讓我們看到,而它的工作原理用表盤(pán)遮擋起來(lái)不讓我們看,這也是一種合理的設(shè)計(jì),我們只需要看時(shí)機(jī)就行了。

其Java的實(shí)封裝也是這樣設(shè)計(jì)的,把類(lèi)封裝起來(lái),有些成員變量和成員方法讓我們看到和使用,有的成員變量和成員方法不讓我們使用。

面向?qū)ο蟪绦蛉筇匦?/strong>:封裝、繼承、多態(tài)。而類(lèi)和對(duì)象階段,主要研究的就是封裝特性。何為封裝呢?簡(jiǎn)單來(lái)說(shuō)就是套殼屏蔽細(xì)節(jié)。

封裝:將成員變量和成員方法進(jìn)行有機(jī)結(jié)合,隱藏對(duì)象的屬性和實(shí)現(xiàn)細(xì)節(jié),僅對(duì)外公開(kāi)接口來(lái)和對(duì)象進(jìn)行、交互。

實(shí)現(xiàn)這些功能就需要訪問(wèn)限定符

1.2 訪問(wèn)限定符

范圍privatedefaultprotectedpublic
1同一包中的同一類(lèi)????
2同一包中的不同類(lèi)???
3不同包中的子類(lèi)??
4不同包中的非子類(lèi)?

說(shuō)明:
public:只看單詞的意思就可以明白,是公共的,誰(shuí)都可以看到和使用。
protected:主要是用在繼承中,子類(lèi)可以使用。
default: 對(duì)于自己家族中(同一個(gè)包中)不是什么秘密,對(duì)于其他人來(lái)說(shuō)就是隱私了。什么都不寫(xiě)時(shí)的默認(rèn)權(quán)限
private:?jiǎn)卧~的意思是私密的,只有自己使用,其他人不能使用

訪問(wèn)權(quán)限除了可以限定類(lèi)中成員的可見(jiàn)性,也可以控制類(lèi)的可見(jiàn)性

1.3 使用封裝

cn.nyist.watch包中創(chuàng)建一個(gè)手表類(lèi)Watch

package cn.nyist.watch;
public class Watch {
    private String machine; // 機(jī)械手表的動(dòng)力來(lái)源
    public String time; // 時(shí)間
    String brand; // 品牌,default
    // 構(gòu)造器
    public Watch(String machine,String time, String brand){
        this.machine = machine;
        this.time = time;
        this.brand = brand;
    }
    // 手表的功能 看時(shí)間
    public void See_time(){
        System.out.println("時(shí)間");
    }
    //調(diào)試零件
    private void debugging(){
        System.out.println("調(diào)試零件");
    }
}

Watch類(lèi)中使用main函數(shù),相當(dāng)于是創(chuàng)造表的人:
可以任意查看和使用

// 程序的入口,在Watch類(lèi)中
    public static void main(String[] args){
        // 在類(lèi)中創(chuàng)建一個(gè)手表
        // 此場(chǎng)景相當(dāng)于創(chuàng)造表的人
        Watch w = new Watch("機(jī)械","12:00","勞力士");
        //開(kāi)始使用手表
        //查看表的機(jī)械部件
        System.out.println(w.machine);
        // 查看時(shí)間
        System.out.println(w.time);
        //查看品牌
        System.out.println(w.brand);
        w.See_time();
        w.debugging();
    }

cn.nyist.watch包中創(chuàng)建一個(gè)Main類(lèi),作為相當(dāng)于買(mǎi)手表的人:
不可以訪問(wèn)Watch類(lèi)定義的私有成員和私有方法

package cn.nyist.watch;
public class Buy {
    // 程序的入口,在類(lèi)中
    public static void main(String[] args){
        // 此場(chǎng)景相當(dāng)于手表的買(mǎi)者即擁有者
        Watch w = new Watch("機(jī)械","12:00","勞力士");
        //開(kāi)始使用手表
        //查看表的機(jī)械部件
        //System.out.println(w.machine); 不可以查看private屬性
        // 查看時(shí)間
        System.out.println(w.time); // time是public屬性
        //查看品牌
        System.out.println(w.brand); // brand 是default屬性
        w.See_time(); // See_time是public屬性
        //w.debugging(); // 不能調(diào)用private方法
    }
}

在其他包中的非子類(lèi),相當(dāng)于一個(gè)陌生人去看你的表:
只能訪問(wèn)public屬性的成員變量和成員方法

public class People {
    // 程序的入口
    public static void main(String[] args){
        // 此場(chǎng)景相當(dāng)于一個(gè)陌生人去看你的表
        Watch w = new Watch("機(jī)械","12:00","勞力士");
        //查看表的機(jī)械部件
        //System.out.println(w.machine); 不可以查看private屬性
        // 查看時(shí)間
        System.out.println(w.time); // time是public屬性
        //查看品牌
        //System.out.println(w.brand); // 不可以看default屬性
        w.See_time(); // See_time是public屬性
        //w.debugging(); // 不能調(diào)用private方法
    }
}

2. 繼承

2.1 為什么要有繼承?

Java中的程序都是類(lèi)與類(lèi)進(jìn)行交互,如果多個(gè)類(lèi)中有很多一樣的成員方法或成員變量就會(huì)出現(xiàn)代碼冗余的現(xiàn)象,比如:
cn.nyist.animal包中創(chuàng)建一個(gè)Dog類(lèi):

package cn.nyist.animal;
public class Dog{
    public String name;
    public String color;
    protected int age;
    // 構(gòu)造器
    public Dog(String name,String color, int age){
        this.name = name;
        this.color = color;
        this.age = age;
    }
    public void eat(){
        System.out.println("吃飯~");
    }
    public void sleep(){
        System.out.println("睡覺(jué)~");
    }
    // 叫
    public void bark(){
        System.out.println("汪汪~(yú)");
    }
}

cn.nyist.animal包中創(chuàng)建一個(gè)Cat類(lèi):

package cn.nyist.animal;
public class Cat{
    public String name;
    public String color;
    protected int age;
    //構(gòu)造器
    public Cat(String name,String color, int age){
        this.name = name;
        this.color = color;
        this.age = age;
    }
    public void eat(){
        System.out.println("吃飯~");
    }
    public void sleep(){
        System.out.println("睡覺(jué)~");
    }
    //叫
    public void mm() {
        System.out.println("喵喵~");
    }
}

這兩個(gè)類(lèi)是不是除了bar()函數(shù),其余的內(nèi)容都是一樣,這就出現(xiàn)了代碼冗余,我們?cè)趺唇鉀Q呢?

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

2.2 繼承的概念

繼承(inheritance)機(jī)制:是面向?qū)ο蟪绦蛟O(shè)計(jì)使代碼可以復(fù)用的最重要的手段,它允許程序員在保持原有類(lèi)特性的基礎(chǔ)上進(jìn)行擴(kuò)展,增加新功能,這樣產(chǎn)生新的類(lèi),稱(chēng)派生類(lèi)(子類(lèi))。繼承呈現(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á)到共用。

上述圖示中,DogCat都繼承了Animal類(lèi),其中:Animal類(lèi)稱(chēng)為父類(lèi)/基類(lèi)或超類(lèi),DogCat可以稱(chēng)為Animal的子類(lèi)/派生類(lèi),繼承之后,子類(lèi)可以復(fù)用父類(lèi)中成員,子類(lèi)在實(shí)現(xiàn)時(shí)只需關(guān)心自己新增加的成員即可。從繼承概念中可以看出繼承最大的作用就是:實(shí)現(xiàn)代碼復(fù)用,還有就是來(lái)實(shí)現(xiàn)多態(tài)。

2.3 繼承的語(yǔ)法

在Java中如果要表示類(lèi)之間的繼承關(guān)系,需要借助extends關(guān)鍵字,語(yǔ)法如下:

修飾符 class 子類(lèi)名 extends 父類(lèi)名 {
 // ...  
}

對(duì)DogCat函數(shù)的重新實(shí)現(xiàn):

錯(cuò)誤示例:

cn.nyist.animal包中創(chuàng)建一個(gè)DogCat的父類(lèi)Animal類(lèi):

package cn.nyist.animal;
// 基類(lèi)(父類(lèi))
public class Animal{
    public String name;
    public String color;
    protected int age;
    //構(gòu)造器
    public Animal(String name,String color, int age){
        this.name = name;
        this.color = color;
        this.age = age;
    }
    public void eat(){
        System.out.println(name + "吃飯~");
    }
    public void sleep(){
        System.out.println(name + "睡覺(jué)~");
    }
}

cn.nyist.animal包中創(chuàng)建一個(gè)Dog,Dog繼承Animal

package cn.nyist.animal;
public class Dog extends Animal{
    // 只需要再添加一個(gè)bark()方法
    public void bark(){
        System.out.println("汪汪~(yú)");
    }
}

當(dāng)寫(xiě)完上述兩步的時(shí)候就運(yùn)行會(huì)發(fā)生報(bào)錯(cuò),這是為什么呢?不是已經(jīng)按要求寫(xiě)了嗎?

因?yàn)?Dog 類(lèi)的沒(méi)有顯示的創(chuàng)建構(gòu)造器,當(dāng)創(chuàng)建Dog類(lèi)對(duì)象的時(shí)候會(huì)調(diào)用默認(rèn)構(gòu)造器,也會(huì)調(diào)用默認(rèn)構(gòu)造器中的super()(super()是用來(lái)調(diào)用父類(lèi)的構(gòu)造器,并可以傳入?yún)?shù)),調(diào)用的super()是無(wú)參的,但是父類(lèi)Animal沒(méi)有創(chuàng)建無(wú)參的構(gòu)造器,這會(huì)導(dǎo)致發(fā)生報(bào)錯(cuò)。

正確示例:

cn.nyist.animal包中創(chuàng)建一個(gè)DogCat的父類(lèi)Animal類(lèi):

package cn.nyist.animal;
public class Animal{
    public String name;
    public String color;
    protected int age; // 子類(lèi)可以使用protected的變量
    //構(gòu)造器
    public Animal(String name,String color, int age){
        this.name = name;
        this.color = color;
        this.age = age;
    }
    public void eat(){
        System.out.println(name + "吃飯~");
    }
    public void sleep(){
        System.out.println(name + "睡覺(jué)~");
    }
}

cn.nyist.animal包中創(chuàng)建一個(gè)Dog,Dog繼承Animal

package cn.nyist.animal;
public class Dog extends Animal{
    public Dog(String name, String color, int age){
        super(name,color,age);
    }
    // 只需要再添加一個(gè)bark()方法
    public void bark(){
        System.out.println("汪汪~(yú)");
    }
}

cn.nyist.animal包中創(chuàng)建一個(gè)Cat,Dog繼承Cat

package cn.nyist.animal;
public class Cat extends Animal{
    // 構(gòu)造器
    public Cat(String name, String color, int age){
        super(name,color,age);
    }
    public void mm() {
        System.out.println("喵喵~");
    }
}

測(cè)試

package cn.nyist.animal;
public class Cat extends Animal{
    // 構(gòu)造器
    public Cat(String name, String color, int age){
        super(name,color,age);
    }
    public void mm() {
        System.out.println("喵喵~");
    }
}

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

java文件的結(jié)構(gòu)

2.4 訪問(wèn)父類(lèi)成員

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

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

cn.nyist.study包中創(chuàng)建基類(lèi)Base

package cn.nyist.study;
public class Base {
    protected int a;
    protected int b;
}

子類(lèi)和父類(lèi)不存在同名成員變量

package cn.nyist.study;
public class Son extends Base {
    int c;
    public void Fun(){
        a = 10; //訪問(wèn)父類(lèi)的成員
        b = 20; // 訪問(wèn)父類(lèi)的成員
        c = 30; // 訪問(wèn)自己的成員
    }
}

子類(lèi)和父類(lèi)存在同名成員變量

package cn.nyist.study;
public class Son extends Base {
    int b;
    int c;
    public void Fun(){
        a = 10; //訪問(wèn)父類(lèi)的成員
        b = 20; // 訪問(wèn)自己的成員
        c = 30; // 訪問(wèn)自己的成員
    }
}

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

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

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

2.4.2 訪問(wèn)父類(lèi)的成員方法

在包cn.nyist.study中創(chuàng)建一個(gè)類(lèi)Base

package cn.nyist.study;
public class Base {
    public void methodA(){
        System.out.println("Base中的methodA()");
    }
    public void methodB(){
        System.out.println("Base中的methodB()");
    }
}

成員方法不同名

package cn.nyist.study;
public class Son extends Base {
    public void methodC() {
        System.out.println("Son中的method(int)方法");
    }
    public void methodD(){
        methodA();    // 訪問(wèn)父類(lèi)中的methodA()
        methodB();   // 訪問(wèn)父類(lèi)中的methodA()
        methodC();   // 訪問(wèn)子類(lèi)中的methodC()
    }
}

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

成員方法同名

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

【說(shuō)明】

  • 通過(guò)子類(lèi)對(duì)象訪問(wèn)父類(lèi)與子類(lèi)中不同名方法時(shí),優(yōu)先在子類(lèi)中找,找到則訪問(wèn),否則在父類(lèi)中找,找到則訪問(wèn),否則編譯報(bào)錯(cuò)。
  • 通過(guò)派生類(lèi)對(duì)象訪問(wèn)父類(lèi)與子類(lèi)同名方法時(shí),如果父類(lèi)和子類(lèi)同名方法的參數(shù)列表不同(重載),根據(jù)調(diào)用方法適傳遞的參數(shù)選擇合適的方法訪問(wèn),如果沒(méi)有則報(bào)錯(cuò);

2.5 super關(guān)鍵字

在有些場(chǎng)景中,子類(lèi)和父類(lèi)中可能會(huì)存在相同名稱(chēng)的成員,如果要在子類(lèi)方法中訪問(wèn)父類(lèi)同名成員時(shí),該如何操作?

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

在包cn.nyist.study中創(chuàng)建一個(gè)類(lèi)Base

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

在包cn.nyist.study中創(chuàng)建類(lèi)Base的子類(lèi)Son

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

【注意事項(xiàng)】

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

2.6 super 和 this

superthis都可以在成員方法中用來(lái)訪問(wèn):成員變量和調(diào)用其他的成員函數(shù),都可以作為構(gòu)造方法的第一條語(yǔ)句,那他們之間有什么區(qū)別呢?

【相同點(diǎn)】

  • 都是Java中的關(guān)鍵字
  • 只能在類(lèi)的非靜態(tài)方法中使用,用來(lái)訪問(wèn)非靜態(tài)成員方法和字段
  • 在構(gòu)造方法中調(diào)用時(shí),必須是構(gòu)造方法中的第一條語(yǔ)句,并且不能同時(shí)存在

【不同點(diǎn)】

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

在非靜態(tài)成員方法中,this用來(lái)訪問(wèn)本類(lèi)的方法和屬性,super用來(lái)訪問(wèn)父類(lèi)繼承下來(lái)的方法和屬性在構(gòu)造方法中:this(…)用于調(diào)用本類(lèi)構(gòu)造方法,super(…)用于調(diào)用父類(lèi)構(gòu)造方法,兩種調(diào)用不能同時(shí)在構(gòu)造
方法中出現(xiàn)構(gòu)造方法中一定會(huì)存在super(…)的調(diào)用,用戶沒(méi)有寫(xiě)編譯器也會(huì)增加,但是this(…)用戶不寫(xiě)則沒(méi)有

2.7 子類(lèi)的構(gòu)造方法使用規(guī)則

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

在包cn.nyist.study中創(chuàng)建基類(lèi)Base

package cn.nyist.study;
public class Base {
    public Base() {
        System.out.println("Base()");
    }
}

在包cn.nyist.study中創(chuàng)建類(lèi)Base的子類(lèi)

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

在包cn.nyist.study中創(chuàng)建類(lèi)Main,運(yùn)行程序

package cn.nyist.study;
public class Main {
    public static void main(String[] args) {
        Son d = new Son();
    }
}


在子類(lèi)構(gòu)造方法中,并沒(méi)有寫(xiě)任何關(guān)于基類(lèi)構(gòu)造的代碼,但是在構(gòu)造子類(lèi)對(duì)象時(shí),先執(zhí)行基類(lèi)的構(gòu)造方法,然后執(zhí)行子類(lèi)的構(gòu)造方法,因?yàn)椋鹤宇?lèi)對(duì)象中成員是有兩部分組成的,基類(lèi)繼承下來(lái)的以及子類(lèi)新增加的部分 。父子父子
肯定是先有父再有子,所以在構(gòu)造子類(lèi)對(duì)象時(shí)候 ,先要調(diào)用基類(lèi)的構(gòu)造方法,將從基類(lèi)繼承下來(lái)的成員構(gòu)造完整,然后再調(diào)用子類(lèi)自己的構(gòu)造方法,將子類(lèi)自己新增加的成員初始化完整。
注意:

若父類(lèi)顯式定義無(wú)參或者默認(rèn)的構(gòu)造方法,在子類(lèi)構(gòu)造方法第一行默認(rèn)有隱含的super()調(diào)用,即調(diào)用基類(lèi)構(gòu)造方法

class Father{
    public String name;
    public int age;
    //不寫(xiě)構(gòu)造方法時(shí),會(huì)有一個(gè)默認(rèn)的無(wú)參構(gòu)造方法
    //public Father(){}
}
public class Son extends Father {
    public String color;
//    // 不寫(xiě)構(gòu)造方法時(shí),會(huì)有一個(gè)默認(rèn)的無(wú)參構(gòu)造方法
//    public Son(){
//       // 默認(rèn)會(huì)調(diào)用父類(lèi)的無(wú)參構(gòu)造方法
//        super();
//    }
}

如果父類(lèi)構(gòu)造方法是帶有參數(shù)的,此時(shí)需要用戶為子類(lèi)顯式定義構(gòu)造方法,并在子類(lèi)構(gòu)造方法中選擇合適的父類(lèi)構(gòu)造方法調(diào)用,否則編譯失敗。

class Father{
    public String name;
    public int age;
    //定義有參構(gòu)造方法
    public Father(String name, int age){
        this.name = name;
        this.age = age;
    }
}
public class Son extends Father {
    public String color;
    // 父類(lèi)只有有參構(gòu)造方法,子類(lèi)必須顯示的調(diào)用父類(lèi)的構(gòu)造方法
    public Son(String name, int age, String color){
        // 子類(lèi)必須顯示的調(diào)用父類(lèi)的構(gòu)造方法,否則會(huì)報(bào)錯(cuò)
        super(name, age);
        this.color = color;
    }
}

在子類(lèi)構(gòu)造方法中,super(…)調(diào)用父類(lèi)構(gòu)造時(shí),必須是子類(lèi)構(gòu)造函數(shù)中第一條語(yǔ)句。

class Father{
    public String name;
    public int age;
    //定義有參構(gòu)造方法
    public Father(String name, int age){
        this.name = name;
        this.age = age;
    }
}
public class Son extends Father {
    public String color;
    // 父類(lèi)只有有參構(gòu)造方法,子類(lèi)必須顯示的調(diào)用父類(lèi)的構(gòu)造方法
    public Son(String name, int age, String color){
        this.color = color;
        // super必須子在第一行,這種寫(xiě)法是錯(cuò)誤的
        super(name, age);
    }
}

super(...)只能在子類(lèi)構(gòu)造方法中出現(xiàn)一次,并且不能和this(…)同時(shí)出現(xiàn)。

class Father{
    public String name;
    public int age;
    //定義有參構(gòu)造方法
    public Father(String name, int age){
        this.name = name;
        this.age = age;
    }
}
public class Son extends Father {
    public String color;
    public Son(String color){
        super("張三",18);
        this.color = color;
    }
    // 父類(lèi)只有有參構(gòu)造方法,子類(lèi)必須顯示的調(diào)用父類(lèi)的構(gòu)造方法
    public Son(String name, int age, String color){
        // 子類(lèi)必須顯示的調(diào)用父類(lèi)的構(gòu)造方法,否則會(huì)報(bào)錯(cuò)
        super(name, age);
        // super()和this()不能同時(shí)使用
        this(color);
    }
}

3. 多態(tài)

3.1 多態(tài)的概念

多態(tài)允許你使用一個(gè)接口來(lái)表示不同的類(lèi)型,從而實(shí)現(xiàn)更靈活和可擴(kuò)展的代碼設(shè)計(jì)。

多態(tài)的概念:通俗來(lái)說(shuō),就是多種形態(tài),具體點(diǎn)就是去完成某個(gè)行為,當(dāng)不同的對(duì)象去完成時(shí)會(huì)產(chǎn)生出不同 的狀態(tài)。

比如,有一個(gè)基類(lèi)Animal,有一個(gè)吃飯的方法;子類(lèi)Dog,重寫(xiě)方法吃飯變?yōu)槌怨穷^;子類(lèi)Cat重寫(xiě)方法變?yōu)槌贼~(yú)。使用這兩個(gè)子類(lèi)的時(shí)候,都調(diào)用吃飯的方法,但是打印出不同的內(nèi)容。

3.2 多態(tài)的實(shí)現(xiàn)

在java中要實(shí)現(xiàn)多態(tài),必須要滿足如下幾個(gè)條件,缺一不可:

  • 必須在繼承體系下。
  • 子類(lèi)必須要對(duì)父類(lèi)中方法進(jìn)行重寫(xiě)。
  • 通過(guò)父類(lèi)的引用調(diào)用重寫(xiě)的方法。

多態(tài)體現(xiàn):在代碼運(yùn)行時(shí),當(dāng)傳遞不同類(lèi)對(duì)象時(shí),會(huì)調(diào)用對(duì)應(yīng)類(lèi)中的方法

示例:

cn.nyist.study包中創(chuàng)建一個(gè)基類(lèi)Animal

package cn.nyist.animal;
public class Animal{
    public String name;
    public String color;
    protected int age;
    //構(gòu)造器
    public Animal(String name,String color, int age){
        this.name = name;
        this.color = color;
        this.age = age;
    }
    public void eat(){
        System.out.println(name + "吃飯~");
    }
    public void sleep(){
        System.out.println(name + "睡覺(jué)~");
    }
}

cn.nyist.study包中創(chuàng)建子類(lèi)Dog

package cn.nyist.animal;
public class Dog extends Animal{
    public Dog(String name, String color, int age){
        super(name,color,age);
    }
    // 重寫(xiě)父類(lèi)方法
    public void eat(){
        System.out.println(name+"吃骨頭");
    }
}

cn.nyist.study包中創(chuàng)建子類(lèi)Cat

package cn.nyist.animal;
public class Cat extends Animal{
    // 構(gòu)造器
    public Cat(String name, String color, int age){
        super(name,color,age);
    }
   public void eat(){
        System.out.println(name + "吃魚(yú)");
   }
}

cn.nyist.study包類(lèi)Main,運(yùn)行程序

package cn.nyist.animal;
public class Main {
    public static void main(String[] args) {
        // 創(chuàng)建狗類(lèi)的對(duì)象
        Dog dog = new Dog("小狗","黑色",1);
        Fun_eat(dog);
        // 創(chuàng)建貓類(lèi)的對(duì)象
        Cat cat = new Cat("小貓","花色",3);
        Fun_eat(cat);
    }
	// 編譯器在編譯代碼時(shí),并不知道要調(diào)用Dog 還是 Cat 中eat的方法
	// 等程序運(yùn)行起來(lái)后,形參a引用的具體對(duì)象確定后,才知道調(diào)用那個(gè)方法
	// 注意:此處的形參類(lèi)型必須時(shí)父類(lèi)類(lèi)型才可以
    public static void Fun_eat(Animal a){
        a.eat();
        a.sleep();
    }
}

3.3 重寫(xiě)

重寫(xiě)(override):也稱(chēng)為覆蓋。重寫(xiě)是子類(lèi)對(duì)父類(lèi)非靜態(tài)、非private修飾,非final修飾,非構(gòu)造方法等的實(shí)現(xiàn)過(guò)程進(jìn)行重新編寫(xiě),返回值和形參都不能改變。即外殼不變,核心重寫(xiě)!重寫(xiě)的好處在于子類(lèi)可以根據(jù)需要,定義特定于自己的行為。 也就是說(shuō)子類(lèi)能夠根據(jù)需要實(shí)現(xiàn)父類(lèi)的方法。

【方法重寫(xiě)的規(guī)則】

  • 子類(lèi)在重寫(xiě)父類(lèi)的方法時(shí),一般必須與父類(lèi)方法原型一致: 返回值類(lèi)型 方法名 (參數(shù)列表) 要完全一致
  • 被重寫(xiě)的方法返回值類(lèi)型可以不同,但是必須是具有父子關(guān)系
  • 訪問(wèn)權(quán)限不能比父類(lèi)中被重寫(xiě)的方法的訪問(wèn)權(quán)限更低。例如:如果父類(lèi)方法被public修飾,則子類(lèi)中重寫(xiě)該方法就不能聲明為 protected
  • 父類(lèi)被static、private修飾的方法、構(gòu)造方法都不能被重寫(xiě)。
  • 重寫(xiě)的方法, 可以使用 @Override 注解來(lái)顯式指定. 有了這個(gè)注解能幫我們進(jìn)行一些合法性校驗(yàn). 例如不小心將方法名字拼寫(xiě)錯(cuò)了 (比如寫(xiě)成 aet), 那么此時(shí)編譯器就會(huì)發(fā)現(xiàn)父類(lèi)中沒(méi)有 aet 方法, 就會(huì)編譯報(bào)錯(cuò), 提示無(wú)法構(gòu)成重寫(xiě).

【重寫(xiě)和重載的區(qū)別】

區(qū)別點(diǎn)重寫(xiě)(override)重載(overload)
參數(shù)列表一定不能修改必須修改
返回類(lèi)型一定不能修改【除非可以構(gòu)成父子類(lèi)關(guān)系】可以修改
訪問(wèn)限定符一定不能做更嚴(yán)格的限制(可以降低限制)可以修改

到此這篇關(guān)于Java面向程序的三大特性之封裝、繼承、多態(tài)的文章就介紹到這了,更多相關(guān)Java封裝、繼承、多態(tài)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java的Semaphore信號(hào)量使用及原理解讀

    Java的Semaphore信號(hào)量使用及原理解讀

    這篇文章主要介紹了Java的Semaphore信號(hào)量使用及原理解讀,Semaphore(信號(hào)量)是Java中一個(gè)并發(fā)控制工具,用于控制對(duì)共享資源的訪問(wèn),它基于計(jì)數(shù)器的原理,可以限制同時(shí)訪問(wèn)某個(gè)資源的線程數(shù)量,需要的朋友可以參考下
    2023-12-12
  • 鴻蒙HarmonyOS App開(kāi)發(fā)造輪子之自定義圓形圖片組件的實(shí)例代碼

    鴻蒙HarmonyOS App開(kāi)發(fā)造輪子之自定義圓形圖片組件的實(shí)例代碼

    這篇文章主要介紹了鴻蒙HarmonyOS App開(kāi)發(fā)造輪子之自定義圓形圖片組件,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • Spring Cloud 系列之負(fù)載均衡 Ribbon的示例代碼

    Spring Cloud 系列之負(fù)載均衡 Ribbon的示例代碼

    Ribbon 是 Netflix 發(fā)布的負(fù)載均衡器,它有助于控制 HTTP 和 TCP 客戶端的行為。這篇文章主要介紹了Spring Cloud 系列之負(fù)載均衡 Ribbon的示例代碼,需要的朋友可以參考下
    2020-11-11
  • 分析Springboot中嵌套事務(wù)失效原因詳解

    分析Springboot中嵌套事務(wù)失效原因詳解

    這篇文章主要為大家介紹了分析Springboot中嵌套事務(wù)失效原因詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-11-11
  • kotlin java 混合代碼 maven 打包實(shí)現(xiàn)

    kotlin java 混合代碼 maven 打包實(shí)現(xiàn)

    這篇文章主要介紹了kotlin java 混合代碼 maven 打包實(shí)現(xiàn),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • 一篇文章帶你了解Java 中序列化與反序列化

    一篇文章帶你了解Java 中序列化與反序列化

    這篇文章主要介紹了Java 序列化與反序列化(Serialization),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • java基礎(chǔ)之泛型知識(shí)點(diǎn)總結(jié)

    java基礎(chǔ)之泛型知識(shí)點(diǎn)總結(jié)

    這篇文章主要介紹了java基礎(chǔ)之泛型知識(shí)點(diǎn)總結(jié),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-04-04
  • Java使用阻塞隊(duì)列控制線程通信的方法實(shí)例詳解

    Java使用阻塞隊(duì)列控制線程通信的方法實(shí)例詳解

    這篇文章主要介紹了Java使用阻塞隊(duì)列控制線程通信的方法,結(jié)合實(shí)例形式詳細(xì)分析了java使用阻塞隊(duì)列控制線程通信的相關(guān)原理、方法及操作注意事項(xiàng),需要的朋友可以參考下
    2019-09-09
  • Springboot之Jasypt配置文件加密/解密方式

    Springboot之Jasypt配置文件加密/解密方式

    Jasypt是一個(gè)用于Java項(xiàng)目加密敏感信息的庫(kù),可以避免敏感信息泄露,文章介紹了如何在Spring Boot項(xiàng)目中整合Jasypt,并提供了一些防止密碼泄露的建議
    2026-03-03
  • mybatis之foreach用法詳解

    mybatis之foreach用法詳解

    這篇文章主要介紹了mybatis之foreach用法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12

最新評(píng)論

广水市| 阜平县| 乌兰浩特市| 团风县| 弋阳县| 民丰县| 崇州市| 成安县| 咸阳市| 望奎县| 体育| 荣昌县| 齐河县| 辉南县| 孟州市| 科技| 鞍山市| 海伦市| 和顺县| 扶沟县| 巫山县| 许昌县| 磐石市| 锦屏县| 鹤峰县| 信丰县| 肇东市| 乌兰浩特市| 罗城| 江城| 河东区| 中西区| 夹江县| 如皋市| 营山县| 兴安盟| 阿克陶县| 霍林郭勒市| 蓝田县| 连云港市| 靖远县|