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

Java由淺入深刨析繼承

 更新時(shí)間:2022年03月02日 16:25:28   作者:最愛吃魚罐頭  
繼承就是子類繼承父類的特征和行為,使得子類對(duì)象(實(shí)例)具有父類的實(shí)例域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為

茫茫人海千千萬萬,感謝這一秒你看到這里。希望我的面試題系列能對(duì)你的有所幫助!共勉!

愿你在未來的日子,保持熱愛,奔赴山海!

Java基礎(chǔ)知識(shí)(繼承)

繼承

繼承的介紹

繼承是java面向?qū)ο缶幊碳夹g(shù)的一塊基石,因?yàn)樗试S創(chuàng)建分等級(jí)層次的類。描述的是事物之間的所屬關(guān)系,這種關(guān)系是:is-a 的關(guān)系。

繼承:就是子類繼承父類的屬性和行為,使得子類對(duì)象(實(shí)例)可以直接具有與父類相同的屬性、相同的行為。子類可以直接訪問父類中的非私有的屬性和行為。

生活中的繼承

兔子和長(zhǎng)頸鹿屬于食草動(dòng)物類,老虎和獅子屬于食肉動(dòng)物類。而食草動(dòng)物和食肉動(dòng)物又是屬于動(dòng)物類。

那是不是兔子、長(zhǎng)頸鹿、老虎、獅子都屬于動(dòng)物類呢?答案是沒錯(cuò)滴!雖然食草動(dòng)物和食肉動(dòng)物都是屬于動(dòng)物,但是兩者的屬性和行為上有差別,所以子類會(huì)具有父類的一般特性也會(huì)具有自身的特性。我們就可以再多個(gè)類中存在相同屬性和行為時(shí),我們可以將這些內(nèi)容抽取到單獨(dú)一個(gè)類中,那么多個(gè)類無需再定義這些屬性和行為,只要繼承那一個(gè)類即可。

繼承的好處

  • 提高代碼的復(fù)用性(減少代碼冗余,相同代碼重復(fù)利用)。
  • 使類與類之間產(chǎn)生了關(guān)系。
  • 子類擁有父類非 private 的屬性、方法。
  • 子類可以擁有自己的屬性和方法,即子類可以對(duì)父類進(jìn)行擴(kuò)展。
  • 子類可以用自己的方式實(shí)現(xiàn)父類的方法。
  • 提高了類之間的耦合性(繼承的缺點(diǎn),耦合度高就會(huì)造成代碼之間的聯(lián)系越緊密,代碼獨(dú)立性越差)。
  • Java 的繼承是單繼承,但是可以多重繼承,單繼承就是一個(gè)子類只能繼承一個(gè)父類,多重繼承就是,例如 B 類繼承 A 類,C 類繼承 B 類,所以按照關(guān)系就是 B 類是 C 類的父類,A 類是 B 類的父類,這是 Java 繼承區(qū)別于 C++ 繼承的一個(gè)特性。

繼承的格式

在Java當(dāng)中會(huì)通過extends關(guān)鍵字可以申明一個(gè)類是從另外一個(gè)類繼承而來的,一般形式如下:

class 父類 {
}

class 子類 extends 父類 {
}

需要注意一點(diǎn): Java 不支持多繼承,但支持多重繼承。就如下:

class A {
}

class B extends A { (對(duì)的)
}

class C extends A, B { (錯(cuò)的)
}

class C extends B { (對(duì)的)
}

頂層父類是Object類。所有的類默認(rèn)繼承Object,作為父類。

繼承的demo

編寫一個(gè)父類極其對(duì)應(yīng)的子類信息

結(jié)構(gòu)如下:

代碼如下:

父類Person:

package com.nz.pojo;

public class Person {
    private String name ;
    private int age ;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

子類Student沒有額外的屬性和方法:

package com.nz.pojo;

/**
 * 繼承了Person特有的name, age,
 * 沒有額外的獨(dú)有屬性和方法
 */
public class Student extends Person{
}

子類Teacher多了一個(gè)工資的屬性和獨(dú)有的教書方法:

package com.nz.pojo;

/**
 * 繼承了Person特有的name, age,
 * 多了自己獨(dú)有的工資屬性還有獨(dú)有的教書方法
 */
public class Teacher extends Person{

    // 工資
    private double salary ;

    // 特有方法
    public void teach(){
        System.out.println("老師在認(rèn)真教書!");
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

編寫測(cè)試代碼:

package com.nz;

import com.nz.pojo.Student;
import com.nz.pojo.Teacher;

public class InheritDemo {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        teacher.setName("最愛吃魚罐頭");
        teacher.setAge(18);
        teacher.setSalary(1999.99);
        System.out.println(teacher.getName());
        System.out.println(teacher.getAge());
        System.out.println(teacher.getSalary());
        teacher.teach();

        Student student = new Student();
        student.setName("罐頭");
        student.setAge(12);
        //student.setSalary(1999.99); // student沒有工資屬性,報(bào)錯(cuò)!
        System.out.println(student.getName());
        System.out.println(student.getAge());
    }
}

結(jié)果如下:

最愛吃魚罐頭
18
1999.99
老師在認(rèn)真教書!
罐頭
12

從結(jié)果來看,子類繼承父類,就可以直接得到父類的成員變量和方法。而子類可以編寫一些特有的屬性和方法,但是是否可以繼承所有成分呢?

子類不能繼承的內(nèi)容

并不是父類的所有內(nèi)容都可以給子類繼承的:

super 與 this 關(guān)鍵字

這里先將這兩個(gè)關(guān)鍵字,super和this在繼承關(guān)系中,運(yùn)用比較頻繁。

  • super關(guān)鍵字:我們可以通過super關(guān)鍵字來實(shí)現(xiàn)對(duì)父類成員的訪問,用來引用當(dāng)前對(duì)象的父類。
  • this關(guān)鍵字:指向自己本類的引用。

super和this完整的用法如下:

this.成員變量 -- 本類的
super.成員變量 -- 父類的

this.成員方法名() -- 本類的
super.成員方法名() -- 父類的

  • 具體演示,創(chuàng)建測(cè)試InheritDemo2:
package com.nz;

public class InheritDemo2 {
    public static void main(String[] args) {
        Animal a = new Animal();
        a.eat();
        Cat cat = new Cat();
        cat.eatFish();
    }
}

class Animal {
    void eat() {
        System.out.println("animal : eat");
    }
}

class Cat extends Animal {
    void eat() {
        System.out.println("cat : eat");
    }
    void eatFish() {
        this.eat();   // this 調(diào)用自己的方法
        super.eat();  // super 調(diào)用父類方法
    }
}

調(diào)用結(jié)果如下:

animal : eat
cat : eat
animal : eat

  • 注意:

子類的每個(gè)構(gòu)造方法中均有默認(rèn)的super(),調(diào)用父類的空參構(gòu)造。手動(dòng)調(diào)用父類構(gòu)造會(huì)覆蓋默認(rèn)的super()。

super() 和 this() 都必須是在構(gòu)造方法的第一行,所以不能同時(shí)出現(xiàn)。

構(gòu)造器不能被繼承

  • 子類不能繼承父類的構(gòu)造器(構(gòu)造方法或者構(gòu)造函數(shù)),它只是調(diào)用(隱式或顯式)。因?yàn)樽宇愑凶约旱臉?gòu)造器。值得注意的是子類可以繼承父類的私有成員(成員變量,方法),只是子類無法直接訪問而已,可以通過getter/setter方法訪問父類的private成員變量。
  • 如果父類的構(gòu)造器帶有參數(shù),則必須在子類的構(gòu)造器中顯式地通過super 關(guān)鍵字調(diào)用父類的構(gòu)造器并配以適當(dāng)?shù)膮?shù)列表。
  • 如果父類構(gòu)造器沒有參數(shù),則在子類的構(gòu)造器中不需要使用 super 關(guān)鍵字調(diào)用父類構(gòu)造器,系統(tǒng)會(huì)自動(dòng)調(diào)用父類的無參構(gòu)造器。
  • 演示過程:
package com.nz;

public class InheritDemo3  {
    public static void main(String[] args) {
        System.out.println("------Teacher 類繼承------");
        Teacher teacher = new Teacher();
        Teacher teacher2 = new Teacher("張三");
        System.out.println("------Student 類繼承------");
        Student student = new Student();
        Student student2 = new Student("張三三");
    }
}
// 父類
class Person {
    private String name;
    Person(){
        System.out.println("調(diào)用了父類的無參構(gòu)造器: Person()");
    }
    Person(String name) {
        System.out.println("調(diào)用了父類的帶參構(gòu)造器: Person(String name)");
        this.name = name;
    }
}
// Teacher子類繼承Person
class Teacher extends Person{
    private String name;
    Teacher(){
        // 自動(dòng)調(diào)用父類的無參數(shù)構(gòu)造器 因?yàn)闀?huì)有默認(rèn)super();
        System.out.println("Teacher");
    }

    public Teacher(String name){
        super("最愛吃魚罐頭");  // 調(diào)用父類中帶有參數(shù)的構(gòu)造器
        System.out.println("Teacher(String name):"+name);
        this.name = name;
    }
}
// Student子類繼承Person
class Student extends Person{
    private String name;

    Student(){
        super("heihei");  // 調(diào)用父類中帶有參數(shù)的構(gòu)造器
        System.out.println("SubClass2");
    }

    public Student(String name){ // 自動(dòng)調(diào)用父類的無參數(shù)構(gòu)造器
        System.out.println("Student(String name):"+name);
        this.name = name;
    }
}

結(jié)果如下:

------Teacher 類繼承------
調(diào)用了父類的無參構(gòu)造器: Person()
Teacher
調(diào)用了父類的帶參構(gòu)造器: Person(String name)
Teacher(String name):張三
------Student 類繼承------
調(diào)用了父類的帶參構(gòu)造器: Person(String name)
SubClass2
調(diào)用了父類的無參構(gòu)造器: Person()
Student(String name):張三三

final修飾的類不能被繼承

final 關(guān)鍵字主要用在三個(gè)地方:變量、方法、類。

  • 修飾類:表示該類不能被繼承;
  • 修飾方法:表示方法不能被重寫;
  • 修飾變量:表示變量只能一次賦值以后值不能被修改(常量)。

final 的特點(diǎn):

  • 對(duì)于一個(gè) final 變量,如果是基本數(shù)據(jù)類型的變量,則其數(shù)值一旦在初始 化之后便不能更改;如果是引用類型的變量,則在對(duì)其初始化之后便不 能再讓其指向另一個(gè)對(duì)象。
  • 當(dāng)用 final 修飾一個(gè)類時(shí),表明這個(gè)類不能被繼承。final 類中的所有成員 方法都會(huì)被隱式地指定為 final 方法。
  • 使用 final 方法的原因有兩個(gè)。第一個(gè)原因是把方法鎖定,以防任何繼承 類修改它的含義;第二個(gè)原因是效率。在早期的 Java 實(shí)現(xiàn)版本中,會(huì)將 final 方法轉(zhuǎn)為內(nèi)嵌調(diào)用。但是如果方法過于龐大,可能看不到內(nèi)嵌調(diào)用 帶來的任何性能提升(現(xiàn)在的 Java 版本已經(jīng)不需要使用 final方法進(jìn)行這些優(yōu)化了)。類中所有的 private 方法都隱式地指定為 final。

我們測(cè)試下修飾類后到底能不能繼承:

package com.nz;

public class InheritDemo4 {
}

// 父類
final class Fu {
    private String name;
}

//class Zi extends Fu{ // Cannot inherit from final 'com.nz.Fu' 會(huì)顯示沒辦法繼承Fu
//}

結(jié)果:可以看出來在被final修飾的Fu類沒辦法繼承,而且在編譯期間就會(huì)報(bào)錯(cuò)了,沒辦法通過運(yùn)行。

方法重寫

介紹

子類中出現(xiàn)與父類一模一樣的方法時(shí)(返回值類型,方法名和參數(shù)列表都相同),會(huì)出現(xiàn)覆蓋效果,也稱為重寫或者復(fù)寫。聲明不變,重新實(shí)現(xiàn)。

使用場(chǎng)景與案例

發(fā)生在子父類之間的關(guān)系。 子類繼承了父類的方法,但是子類覺得父類的這方法不足以滿足自己的需求,子類重新寫了一個(gè)與父類同名的方法,以便覆蓋父類的該方法。

寫個(gè)測(cè)試案例:

package com.nz;

public class InheritDemo5 {

    public static void main(String[] args) {
        // 創(chuàng)建子類對(duì)象
        Cat lanMao = new Cat();
        // 調(diào)用父類繼承而來的方法
        lanMao.run();
        // 調(diào)用子類重寫的方法
        lanMao.sing();

    }
}

class Animal{
    public void sing(){
        System.out.println("動(dòng)物都可以唱歌!");
    }
    public void run(){
        System.out.println("動(dòng)物都可以跑!");
    }
}

class Cat extends Animal {
    public void sing(){
        System.out.println("我們一起學(xué)貓叫,一起喵喵喵!讓我們一起撒個(gè)嬌");
    }
}

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

動(dòng)物都可以跑!
我們一起學(xué)貓叫,一起喵喵喵!讓我們一起撒個(gè)嬌

可以看出,藍(lán)貓調(diào)用了重寫后的sing方法。

@Override重寫注解

  • @Override:注解,重寫注解校驗(yàn)!
  • 這個(gè)注解標(biāo)記的方法,就說明這個(gè)方法必須是重寫父類的方法,否則編譯階段報(bào)錯(cuò)。
  • 建議重寫都加上這個(gè)注解,一方面可以提高代碼的可讀性,一方面可以防止重寫出錯(cuò)!

加上后的子類代碼形式如下:

class Cat extends Animal {
    // 聲明不變,重新實(shí)現(xiàn)
    // 方法名稱與父類全部一樣,只是方法體中的功能重寫了!
    @Override
    public void sing(){
        System.out.println("我們一起學(xué)貓叫,一起喵喵喵!讓我們一起撒個(gè)嬌");
    }
}

注意事項(xiàng)

  • 方法重寫是發(fā)生在子父類之間的關(guān)系。
  • 子類方法覆蓋父類方法,必須要保證權(quán)限大于等于父類權(quán)限。
  • 子類方法覆蓋父類方法,返回值類型、函數(shù)名和參數(shù)列表都要一模一樣。、

完結(jié)

相信各位看官看到這里,都對(duì)Java繼承有了一定的了解吧,繼承在Java的特性里還是占據(jù)比較大得多作用,他還有很多特點(diǎn):

  • 高代碼的復(fù)用性(減少代碼冗余,相同代碼重復(fù)利用)。
  • 使類與類之間產(chǎn)生了關(guān)系。
  • 子類擁有父類非 private 的屬性、方法。
  • 子類可以擁有自己的屬性和方法,即子類可以對(duì)父類進(jìn)行擴(kuò)展,可以用自己的方式實(shí)現(xiàn)父類的方法。
  • 提高了類之間的耦合性(繼承的缺點(diǎn),耦合度高就會(huì)造成代碼之間的聯(lián)系越緊密,代碼獨(dú)立性越差)。

讓我們也一起加油吧!本人不才,如有什么缺漏、錯(cuò)誤的地方,也歡迎各位人才大佬評(píng)論中批評(píng)指正!

學(xué)到這里,今天的世界打烊了,晚安!雖然這篇文章完結(jié)了,但是我還在,永不完結(jié)。我會(huì)努力保持寫文章。來日方長(zhǎng),何懼車遙馬慢!

感謝各位看到這里!愿你韶華不負(fù),青春無悔!

到此這篇關(guān)于Java由淺入深刨析繼承的文章就介紹到這了,更多相關(guān)Java 繼承內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java8中Optional操作的實(shí)際應(yīng)用

    Java8中Optional操作的實(shí)際應(yīng)用

    Optional類是一個(gè)可以為null的容器對(duì)象,如果值存在則isPresent()方法會(huì)返回true,調(diào)用get()方法會(huì)返回該對(duì)象,下面這篇文章主要給大家介紹了關(guān)于Java8中Optional操作實(shí)際應(yīng)用的相關(guān)資料,需要的朋友可以參考下
    2022-02-02
  • Java Netty核心模塊超詳細(xì)梳理

    Java Netty核心模塊超詳細(xì)梳理

    Netty是一個(gè)java開源項(xiàng)目,是一個(gè)異步的、基于事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用框架,用以開發(fā)高性能、高可用的網(wǎng)絡(luò)io程序,這篇文章主要介紹了Netty核心模塊
    2022-11-11
  • 注解@CrossOrigin解決跨域的問題

    注解@CrossOrigin解決跨域的問題

    這篇文章主要介紹了注解@CrossOrigin解決跨域的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • 基于RocketMQ推拉模式詳解

    基于RocketMQ推拉模式詳解

    這篇文章主要介紹了RocketMQ推拉模式的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • spring boot使用thymeleaf為模板的基本步驟介紹

    spring boot使用thymeleaf為模板的基本步驟介紹

    Spring Boot項(xiàng)目的默認(rèn)模板引擎是Thymeleaf,這沒什么好說的,個(gè)人覺得也非常好,下面這篇文章主要給大家介紹了關(guān)于spring boot使用thymeleaf為模板的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • 教你在JNA中將本地方法映射到JAVA代碼中的示例

    教你在JNA中將本地方法映射到JAVA代碼中的示例

    對(duì)于JNI來說,我們可以使用native關(guān)鍵字來定義本地方法。那么在JNA中有那些在JAVA代碼中定義本地方法的方式呢?對(duì)JNA本地方法映射JAVA代碼的相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-04-04
  • Spring?@Cacheable注解類內(nèi)部調(diào)用失效的解決方案

    Spring?@Cacheable注解類內(nèi)部調(diào)用失效的解決方案

    這篇文章主要介紹了Spring?@Cacheable注解類內(nèi)部調(diào)用失效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • 掃二維碼自動(dòng)跳轉(zhuǎn)【java】詳解

    掃二維碼自動(dòng)跳轉(zhuǎn)【java】詳解

    這篇文章主要介紹了java掃二維碼自動(dòng)跳轉(zhuǎn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • Spring MVC 基于URL的映射規(guī)則(注解版)

    Spring MVC 基于URL的映射規(guī)則(注解版)

    這篇文章主要介紹了Spring MVC 基于URL的映射規(guī)則(注解版) ,詳細(xì)的介紹了幾種方式,有興趣的可以了解一下
    2017-05-05
  • spring項(xiàng)目實(shí)現(xiàn)單元測(cè)試過程解析

    spring項(xiàng)目實(shí)現(xiàn)單元測(cè)試過程解析

    這篇文章主要介紹了spring項(xiàng)目實(shí)現(xiàn)單元測(cè)試過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10

最新評(píng)論

丹江口市| 垦利县| 腾冲县| 闸北区| 海宁市| 杂多县| 留坝县| 无锡市| 湘潭县| 石渠县| 桃园市| 怀安县| 梨树县| 宿松县| 彰化县| 阳江市| 凯里市| 德格县| 微山县| 龙口市| 襄汾县| 静乐县| 西青区| 云安县| 高青县| 道真| 乌鲁木齐县| 临海市| 宁城县| 北辰区| 昭觉县| 清远市| 如东县| 绥江县| 汾西县| 自治县| 临清市| 额济纳旗| 江津市| 沾化县| 天全县|