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

Java全面分析面向?qū)ο笾^承

 更新時間:2022年04月25日 16:17:47   作者:厚積薄發(fā)?  
繼承就是可以直接使用前輩的屬性和方法。自然界如果沒有繼承,那一切都是處于混沌狀態(tài)。多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力。多態(tài)就是同一個接口,使用不同的實例而執(zhí)行不同操作

繼承

什么是繼承呢?

繼承(Inheritance)是一種聯(lián)結(jié)類與類的層次模型。指的是一個類(稱為子類、子接口)繼承另外的一個類(稱為父類、父接口)的功能,并可以增加它自己的新功能的能力,繼承是類與類或者接口與接口之間最常見的關(guān)系;繼承是一種is-a關(guān)系。

看了這些概念你可能還是百思不得其解,我來用大白話給你講解一下,我們在現(xiàn)實生活中也聽過繼承,不過是繼承家產(chǎn),繼承傳承文明.......等等,那這些繼承是不就把上一代人傳下來的東西全部交給繼承人了,這些繼承下來的東西,繼承人隨時都可以用,但是繼承人也有屬于自己的東西。沒錯這就是繼承,而在我們寫代碼的時候?qū)⒁恍╊愃哂械墓残匀考性谝黄鸱诺揭粋€類中(這個類就是父類),然后子類想要調(diào)用從父類繼承下來的成員就隨時可以調(diào)用了。這也就將共性全部抽取出來,實現(xiàn)了代碼的復用。

說了這么多不寫代碼理解可能還是理解的不太通透,好接下來我就舉個例子來給大家理解。

實現(xiàn)一個狗類:

//實現(xiàn)一個狗類
class Dog{
      public String name;//名字
      public int age;//年齡
      public String furColor;//毛顏色
      public void eat() {
          System.out.println(this.name+"吃飯!??!");
      }
      public void sleep() {
          System.out.println(this.name+"睡覺?。?!");
      }
      public void bark() {
          System.out.println(this.name+"汪汪汪");
      }
}

實現(xiàn)一個貓類:

//實現(xiàn)一個貓類
class Cat{
    public String name;//名字
    public int age;//年齡
    public String furColor;//毛顏色
    public void eat() {
        System.out.println(this.name+"吃飯?。?!");
    }
    public void sleep() {
        System.out.println(this.name+"睡覺!?。?);
    }
    public void mew() {
        System.out.println(this.name+"喵喵喵");
    }
}

我們都知道貓和狗都是動物,他們都有共性的屬性比如名字,年齡,吃飯,睡覺,并且它們還有自己的屬性比如狗會汪汪汪,貓會喵喵喵。既然他們有共同的屬性我們就可以創(chuàng)建一個動物類。

//實現(xiàn)一個動物類
class Animal{
    public String name;//名字
    public int age;//年齡
    public String furColor;//毛顏色
    public void eat() {
        System.out.println(this.name+"吃飯?。?!");
    }
    public void sleep() {
        System.out.println(this.name+"睡覺!?。?);
    }
}
//實現(xiàn)一個狗類
class Dog{
      public void bark() {
          System.out.println("汪汪汪");
      }
}
//實現(xiàn)一個貓類
class Cat{
    public void mew() {
        System.out.println("喵喵喵");
    }
}

既然把他們共性都抽取出來怎么用呢?

顯然直接用是用不了的。那需要怎么用呢。我們想的是這個狗和貓都要有這些屬性,當我們向用的時候隨時用,號接下來我們講的繼承就會很好地解決這個問題。

 繼承的語法:繼承是利用extends關(guān)鍵字將子類與父類建立聯(lián)系。

//實現(xiàn)一個狗類
class Dog extends Animal{
      public void bark() {
          System.out.println(this.name+"汪汪汪");
      }
}
//實現(xiàn)一個貓類
class Cat extends Animal{
    public void mew() {
        System.out.println("喵喵喵");
    }
}

這回就不報錯了。

我們來分析一下這段代碼:

在這里子類又叫做派生類,父類可以叫做父類,基類還有超類。

這里有一個問題:

子類繼承了父類的什么呢?

答案是:除了構(gòu)造方法所有。

子類訪問父類的成員變量

子類訪問父類非同名成員變量

//實現(xiàn)一個貓類
class Cat extends Animal {
    public void mew() {
        System.out.println(this.name + "喵喵喵");
    }
    public void Init() {//訪問父類
        this.name = "咪咪";
        this.age = 2;
        this.furColor = "橘黃色";
    }
    public void show() {
        System.out.println(name);
        System.out.println(age);
        System.out.println(furColor);
    }
}

 這里就體現(xiàn)了繼承的關(guān)系,子類繼承了父類的屬性(成員變量和成員方法);

這里我們還可以調(diào)用構(gòu)造方法初始化成員,調(diào)用toString方法來打印信息

//實現(xiàn)一個貓類
class Cat extends Animal {
    public void mew() {
        System.out.println(this.name + "喵喵喵");
    }
    public Cat(String name,int age,String furColor) {
        this.name =name;
        this.age=age;
        this.furColor =furColor;
    }
    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", furColor='" + furColor + '\'' +
                '}';
    }
}
public class TestDemo1 {
    public static void main(String[] args) {
        //Cat cat = new Cat();
        Cat cat = new Cat("咪咪",2,"橘黃色");
        cat.eat();
        cat.sleep();
        cat.mew();
        System.out.println(cat.toString());
    }
}

子類訪問父類同名成員變量

當子類成員變量名與父類成員變量同名了會怎么辦呢???

//實現(xiàn)一個動物類
class Animal{
    public String name = "花花";//名字
    public int age;//年齡
    public String furColor;//毛顏色
    public void eat() {
        System.out.println(this.name+"吃飯!??!");
    }
    public void sleep() {
        System.out.println(this.name+"睡覺?。?!");
    }
}
//實現(xiàn)一個貓類
class Cat extends Animal {
    public String name = "咪咪";
    public void mew() {
        System.out.println(this.name + "喵喵喵");
    }
    public void Init() {//訪問父類
        name = "咪咪";
        this.age = 2;
        this.furColor = "橘黃色";
    }
}
public class TestDemo1 {
    public static void main(String[] args) {
        Cat cat = new Cat();
        System.out.println(cat.name);
    }
}

總結(jié):當父類與子類同名時遵循就近原則,如果實例化子類對象就去子類找,找不到就去父類,父類沒有就報錯,如果實例化父類對象就直接去父類找,父類沒有就報錯。

子類訪問父類的成員方法

子類訪問父類的非同名方法

class Cat extends Animal {
    public String name = "咪咪";
    public void mew() {
        System.out.println(this.name + "喵喵喵");
    }
    public void methodSon() {
        System.out.println("我是子類的方法?。?);
    }
    public void method() {
        methodSon();//訪問子類
        methodFather();//訪問父類
    }
}

子類訪問父類的同名方法

//實現(xiàn)一個動物類
class Animal{
    public String name = "花花";//名字
    public int age;//年齡
    public String furColor;//毛顏色
    public void method(int a) {
        System.out.println("我是父類的方法??!"+a);
    }
}
//實現(xiàn)一個貓類
class Cat extends Animal {
    public String name = "咪咪";
    public void mew() {
        System.out.println(this.name + "喵喵喵");
    }
    public void method() {
        System.out.println("我是子類的方法??!");
    }
}
public class TestDemo1 {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.method();//沒有帶參數(shù)的只有子類有,如果兩者都有method同樣的方法,那就涉及到重寫(前提是引用子類對象)優(yōu)先訪問子類
        cat.method(2);//帶參數(shù)的只有父類有
        //cat.method();
    }
}

子類訪問父類同名的方法也是一樣的也是采取就近原則,當引用子類對象的時候優(yōu)先子類,然后去父類尋找,找不到報錯。

但是方法這里有兩個特殊情況,一是方法重載,說明的是同一個類可以支持方法重載,不同類但是有繼承關(guān)系的也是支持方法重載的。當出現(xiàn)方法重載,就會根據(jù)參數(shù)列表的不同來訪問。

二是方法重寫,方法重寫指的是方法名相同返回值相同,參數(shù)列表相同,當出現(xiàn)方法重寫的時候(前提是引用子類對象)就優(yōu)先子類,會出現(xiàn)動態(tài)綁定,這個咱后面講解。

上面我們都說同名的時候都會遵循就近原則。就比如我們引用子類對象的時候,我就想優(yōu)先調(diào)用父類,那怎么辦呢????

那就該super關(guān)鍵字出場了;

super關(guān)鍵字

super就是一個普通的關(guān)鍵字,來引用當前對象的父類,當我們看見super的時候我們就要知道它是訪問父類的就可以了。

好我們來實踐一下。

super訪問父類成員變量

//實現(xiàn)一個動物類
class Animal{
    public String name = "花花";//名字
    public int age;//年齡
    public String furColor;//毛顏色
}
//實現(xiàn)一個貓類
class Cat extends Animal {
    public String name = "咪咪";
    public void mew() {
        System.out.println(this.name + "喵喵喵");
    }
    public void method() {
        System.out.println(super.name);
    }
}
public class TestDemo1 {
    public static void main(String[] args) {
       Cat cat =new Cat();
       cat.method();
    }
}

super訪問父類成員方法

//實現(xiàn)一個動物類
class Animal{
    public String name = "花花";//名字
    public int age;//年齡
    public String furColor;//毛顏色
    public void method() {
        System.out.println("我是父類的方法?。?!");
    }
}
//實現(xiàn)一個貓類
class Cat extends Animal {
    public void method() {
        System.out.println("我是子類的方法");
    }
    public void methodA() {
        super.method();
    }
}
public class TestDemo1 {
    public static void main(String[] args) {
       Cat cat =new Cat();
       cat.methodA();
    }
}

創(chuàng)建構(gòu)造方法 

當我們?yōu)楦割悇?chuàng)建了一個構(gòu)造方法并且為子類創(chuàng)建構(gòu)造方法的時候就會報錯,原因是什么呢???

那就是當我們創(chuàng)建一個構(gòu)造方法的時候一定要先為父類創(chuàng)建構(gòu)造方法,原因是每個類都要至少要有一個構(gòu)造方法,以前沒有報錯是因為編譯器自動為我們生成了無參的構(gòu)造方法。子類對象一般都有繼承過來的屬性還有自己獨有的屬性,在創(chuàng)建子類對象的時候,一般先執(zhí)行父類的構(gòu)造方法,將子類對象中繼承父類的屬性初始化完整,然后在調(diào)用自己的構(gòu)造方法,為自己獨有的屬性初始化完整。

所以我們一定要先為父類創(chuàng)建構(gòu)造方法。

怎么創(chuàng)建呢??? 與this一樣只不過這是父類的構(gòu)造方法,所以利用super關(guān)鍵字,利用super().

同時super不能在靜態(tài)方法中使用,并且當調(diào)用構(gòu)造方法的時候this()和super()只能出現(xiàn)一個,并且出現(xiàn)在第一行。

super要點:

  • super關(guān)鍵字不能在靜態(tài)方法中使用。
  • super關(guān)鍵字只能放在方法中的第一行,并且與this()只能出現(xiàn)一個。
  • super關(guān)鍵字訪問父類屬性  super.父類方法  super.父類成員變量  super()為父類提供構(gòu)造方法。
  • super關(guān)鍵字是引用父類的對象,當我們看見super的時候,他一定是引用父類的東西。
  • 當沒有為父類寫帶有參數(shù)的構(gòu)造方法的時候,編譯器會為子類自動提供構(gòu)造方法,當父類寫了帶有參數(shù)的構(gòu)造方法,編譯器不會為子類提供無參的構(gòu)造方法,需要用戶自己寫,并且在寫子類的構(gòu)造方法的時候一定要先為父類構(gòu)造。

super與this的區(qū)別

相同點:

  • this與super關(guān)鍵均不能在靜態(tài)方法中使用,靜態(tài)方法不依賴于對象。
  • 并且只能放在方法的第一行。
  • 都是java中的關(guān)鍵字

不同點:

  • this是引用當前對象,super是用來引用當前對象的父類
  • this()調(diào)用本類中的構(gòu)造方法,super用來調(diào)用父類的構(gòu)造方法。
  • this調(diào)用非靜態(tài)方法中本類當中的屬性,super調(diào)用非靜態(tài)方法中的父類的屬性
  • this是非靜態(tài)方法中的隱藏參數(shù),而super不是
  • 構(gòu)造方法一定會有super的調(diào)用,當沒有時候編譯器會自動增加,而this不會

同時增加一個this和super的內(nèi)部圖示:

順序

靜態(tài)代碼塊與實例代碼塊及構(gòu)造方法的初始化順序

我們之前在上一篇文章講解了初始化順序,那時候還沒有講解繼承思想,我們再來回憶一下,應該是靜態(tài)代碼塊>實例代碼塊>構(gòu)造方法,并且代碼塊只執(zhí)行一次,也就是只保存一份,當我們構(gòu)造了兩個對象的時候,在實例化第一個對象會執(zhí)行靜態(tài)代碼塊,當實例化第二個代碼塊的時候,靜態(tài)代碼塊不會執(zhí)行。

接下來我們與繼承結(jié)合也就是有了父類和子類的靜態(tài)代碼塊,構(gòu)造方法,實例代碼塊。

那他們的順序又會是怎樣的呢???

我們來用代碼實踐一下,看結(jié)果到底是什么呢???

class Animal {
    public String name = "花花";//名字
    public int age;//年齡
    public String furColor;//毛顏色
    static {
        System.out.println("我是父類的靜態(tài)代碼塊?。?!");
    }
    {
        System.out.println("我是父類的實例化代碼塊!?。?);
    }
    public void eat() {
        System.out.println(this.name + "吃飯!??!");
    }
    public void sleep() {
        System.out.println(this.name + "睡覺?。?!");
    }
    public void method() {
        System.out.println("我是父類的方法?。。?);
    }
    public Animal(String name, int age, String furColor) {
        this.name = name;
        this.age = age;
        this.furColor = furColor;
        System.out.println("我是父類的構(gòu)造方法?。?!");
    }
}
//實現(xiàn)一個貓類
class Cat extends Animal {
    public String name = "咪咪";
    static {
        System.out.println("我是子類的靜態(tài)代碼塊?。?!");
    }
    {
        System.out.println("我是子類的實例化代碼塊?。?!");
    }
    public Cat(String name, int age, String furColor) {
        super(name, age, furColor);
        System.out.println("我是子類的構(gòu)造方法?。。?);
    }
    public void mew() {
        System.out.println(this.name + "喵喵喵");
    }
    public void method() {
        System.out.println("我是子類的方法");
    }
    public void methodA() {
        super.method();
    }
    }
public class TestDemo {
    public static void main(String[] args) {
        Cat cat = new Cat("咪咪",18,"橘黃色");
    }
}

這里還是用了上面的代碼,定義了兩個類,Animal類和子類Cat,我們同時定義了靜態(tài)代碼塊實例代碼塊,構(gòu)造方法。接下來運行一下看看順序到底是什么呢???

我們這里就可以總結(jié)一下了,還是靜態(tài)代碼塊優(yōu)先執(zhí)行,只不過這里因為在構(gòu)造子類時候優(yōu)先構(gòu)造父類所以是父類的靜態(tài)的代碼塊優(yōu)先于子類的靜態(tài)代碼塊,然后是父類的實例和構(gòu)造方法,最后是子類的實例和構(gòu)造。

還是一樣的我們在創(chuàng)建一個對象看還會跟上次的結(jié)果一樣么??

總結(jié):

 初始化順序:父類靜態(tài)代碼塊>子類靜態(tài)代碼塊>父類實例代碼塊>父類構(gòu)造方法>子類實例代碼塊>子類構(gòu)造方法。如果是第二次實例化對象,那就沒有靜態(tài)代碼塊。

這個應該很好記憶就是靜態(tài)代碼塊優(yōu)先然后實例代碼塊然后構(gòu)造方法,因為構(gòu)造子類之前要先構(gòu)造父類所以父類的實例代碼塊和構(gòu)造方法要大于子類的實例代碼塊和構(gòu)造方法。

詳解訪問修飾限定符

訪問修飾限定符public(公共的)private(私有的)protected(受保護的)default(默認權(quán)限)
同一包的同一類yes√yes√yes√yes√
同一包的不同類yes√No×yes√yes√
不同包的子類yes√No×yes√No×
不同報的非子類yes√No×No×No×

看這個你可能會有些懵,接下來我會詳細講解。前提我們先要知道這些都是訪問權(quán)限超過它自己的權(quán)限就不可以訪問了。

public:它是公共的意思是無論在哪里同一個包還是不同的包,同一類還是不同的類都可以進行訪問。

pivate :只能訪問本類中的成員。

default:默認權(quán)限就是成員前面啥也不加只能在同一個包中訪問。

這里注意:

 protected:可以在同一包中訪問,可以再不同包中的子類訪問,但是不可以在非子類訪問,所以它與繼承有很大的關(guān)系。

總結(jié)訪問修飾限定符:

public 可以再同一包中的同一類不同類都能夠訪問,不同包的子類和非子類也能夠訪問。

private 只能在本類中使用。

default 也就是默認訪問權(quán)限,什么也不加,只能在同一個包中訪問。

protected 可以在同一包中訪問,也可以在不同包的子類訪問。

繼承方式與組合

繼承方式

繼承方式多種多樣,如果能的話就可以一直繼承下去,但在java中繼承方式都有哪些呢???

java中的繼承方式可以進行單繼承,多層繼承。

這里還有一個重要的點:那就是雖然可以繼承很多,但是最少不要超過3成繼承關(guān)系。那如果不小心多繼承了呢?沒關(guān)系我們可以利用final修飾,這樣就可以停止繼承了。

 但是java中不支持多繼承也就是一個子類同時繼承兩個父類。

 這種是不可以的,如果java中要進行多繼承的話那就出現(xiàn)了接口。

組合

如果要說組合的話,我們舉個例子,組合嘛那就是一個東西由什么組成唄,比如汽車由發(fā)動機引擎,輪胎等等組成,學校由老師,學生,工作人員等等組成,而這些老師,學生,工作人員又有自己的屬性。我們把這個學校就稱為組合。

那用代碼如何表示呢??

class Teacher{//老師類
    private String name;
    private int age;
}
class Student{//學生類
    private String name;
    private int id;
}
class School{
    //學校由學生和老師組成
    private Student student[];
    private Teacher teacher[];
}

從這里我們也可以知道繼承與組成本質(zhì)到底是什么樣的關(guān)系;

我們把繼承看做是一種 is   a 關(guān)系:比如狗是一個動物,貓是一個動物

我們把組合看做是一種 has   a的關(guān)系:比如學校有 學生,老師,工作人員組成。

那我們到底什么時候用組合,什么時候用繼承呢???

兩種方式不一定就要用哪個。我們他們兩的區(qū)別:1.繼承是一種is....a的關(guān)系,我們都知道程序是先編譯后運行,而繼承關(guān)系就是在編譯器編譯截斷下確定好的。組合關(guān)系是在運行時確定的。

所以組合比繼承更加簡單靈活高效。我們?nèi)绻潜匾闆r下優(yōu)先選擇組合。

到此這篇關(guān)于Java全面分析面向?qū)ο笾^承的文章就介紹到這了,更多相關(guān)Java繼承內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談Java常見的排序算法

    淺談Java常見的排序算法

    今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識,文章圍繞著Java常見的排序算法展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • 你必須得會的SpringBoot全局統(tǒng)一處理異常詳解

    你必須得會的SpringBoot全局統(tǒng)一處理異常詳解

    程序在運行的過程中,不可避免會產(chǎn)生各種各樣的錯誤,這個時候就需要進行異常處理,本文主要為大家介紹了SpringBoot實現(xiàn)全局統(tǒng)一處理異常的方法,需要的可以參考一下
    2023-06-06
  • 深入了解Java?Synchronized鎖升級過程

    深入了解Java?Synchronized鎖升級過程

    java中的鎖是針對對象而言的,它鎖住的是一個對象,并且具有可重入的性質(zhì),下面這篇文章主要給大家介紹了關(guān)于Java?Synchronized鎖升級過程的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • springBoot加入thymeleaf模板的方式

    springBoot加入thymeleaf模板的方式

    這篇文章主要介紹了springBoot加入thymeleaf模板的方式,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • mybatis批量插入時,有字段可能為null會報錯問題

    mybatis批量插入時,有字段可能為null會報錯問題

    這篇文章主要介紹了mybatis批量插入時,有字段可能為null會報錯問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Java編程中10個最佳的異常處理技巧

    Java編程中10個最佳的異常處理技巧

    這篇文章主要介紹了Java編程中10個最佳的異常處理技巧,在本文中,將討論Java異常處理最佳實踐,這些Java最佳實踐遵循標準的JDK庫,和幾個處理錯誤和異常的開源代碼,這還是一個提供給java程序員編寫健壯代碼的便利手冊,需要的朋友可以參考下
    2015-01-01
  • Java Clone深拷貝與淺拷貝的兩種實現(xiàn)方法

    Java Clone深拷貝與淺拷貝的兩種實現(xiàn)方法

    今天小編就為大家分享一篇關(guān)于Java Clone深拷貝與淺拷貝的兩種實現(xiàn)方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • MyBatis-Plus中使用EntityWrappe進行列表數(shù)據(jù)倒序設(shè)置方式

    MyBatis-Plus中使用EntityWrappe進行列表數(shù)據(jù)倒序設(shè)置方式

    這篇文章主要介紹了MyBatis-Plus中使用EntityWrappe進行列表數(shù)據(jù)倒序設(shè)置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • springboot配置http跳轉(zhuǎn)https的過程

    springboot配置http跳轉(zhuǎn)https的過程

    SSL是為網(wǎng)絡(luò)通信提供安全以及保證數(shù)據(jù)完整性的的一種安全協(xié)議,SSL在網(wǎng)絡(luò)傳輸層對網(wǎng)絡(luò)連接進行加密,這篇文章主要介紹了springboot配置http跳轉(zhuǎn)https的過程,需要的朋友可以參考下
    2023-04-04
  • Java8中l(wèi)ambda表達式的應用及一些泛型相關(guān)知識

    Java8中l(wèi)ambda表達式的應用及一些泛型相關(guān)知識

    這篇文章主要介紹了Java8中l(wèi)ambda表達式的應用及一些泛型相關(guān)知識的相關(guān)資料
    2017-01-01

最新評論