Java入門系列-16-繼承

這一篇文章教給新手學會使用繼承,及理解繼承的概念。掌握訪問修飾符、掌握 final 關鍵字的用法。java

繼承

爲何要使用繼承

首先咱們先看一下這兩個類:ide

public class Teacher {
    private int teachingAge;
    private String name;
    private int age;
    
    public void teach() {
        
    }
    public void seyHi() {
        System.out.println("我是:"+this.name);
    }
}
public class Student {
    private int studentNo;
    private String name;
    private int age;
    
    public void learn() {
        
    }
    public void seyHi() {
        System.out.println("我是:"+this.name);
    }
}

Student 類和 Teacher 類中有一些相同的屬性和方法,這些都屬於重複代碼,當一個程序中有大量的類時,就會產生大量的重複代碼。這些重複的代碼能不能抽取出來而後供其餘類使用以簡化呢,那就是使用繼承函數

使用繼承優化以後:學習

建立 inherit 包測試

父類:(公共代碼類)優化

package inherit;

public class People {
    private String name;
    private int age;
    
    public void sayHi() {
        System.out.println("我是:"+this.name);
    }

    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.javathis

package inherit;

public class Student extends People{
    private int studentNo;
    public void learn() {
        System.out.println("學習課程");
    }
    public int getStudentNo() {
        return studentNo;
    }
    public void setStudentNo(int studentNo) {
        this.studentNo = studentNo;
    }
}

子類:Teacher.javacode

package inherit;

public class Teacher extends People{
    private int teachingAge;
    
    public void teach() {
        System.out.println("教授課程");
    }
    
    public int getTeachingAge() {
        return teachingAge;
    }

    public void setTeachingAge(int teachingAge) {
        this.teachingAge = teachingAge;
    }
    
}

測試類:對象

package inherit;

public class TestInherit {
    public static void main(String[] args) {
        //建立Student對象
        Student stu=new Student();
        stu.setName("張三");//父類中繼承過來的方法
        stu.learn();//子類中特有的方法
        stu.sayHi();
        //建立Teacher對象
        Teacher teacher=new Teacher();
        teacher.setName("湯尼");
        teacher.setTeachingAge(2);//子類中特有的方法
        teacher.sayHi();
    }
}

觀察上面示例代碼咱們發現:繼承

1.子類的公共代碼均可以放在父類中

2.子類能夠有本身獨有的方法和屬性

3.子類一旦繼承父類就會擁有父類的屬性和方法

4.將公共代碼放入父類,更方便統一修改代碼

繼承的語法

關鍵字:extends

1.編寫父類

public class 父類{
    //公共的屬性和方法
}

2.編寫子類,繼承父類

public class 子類 extends 父類{
    //子類特有的屬性和方法
}

子類只能繼承一個父類

子類訪問父類成員

子類要想訪問父類的成員要使用 super 關鍵字,super 表明父類對象

訪問父類構造方法:

super();//訪問無參構造
super(參數);//訪問有參構造

訪問父類屬性:

super.name;

訪問父類方法:

super.print();

訪問父類構造,必須在子類構造方法中調用,必須是第一句

super 只能出如今子類的方法和構造方法中

super 不能訪問父類的 private 成員

敲一敲:訪問父類成員

建立包 visitparent 後在報下建立以下類
父類

package visitparent;

public class Animal {
    private String name;
    private int legs;
    
    public Animal() {
        this.name="無名";
        this.legs=4;
    }
    public Animal(String name,int legs) {
        this.name=name;
        this.legs=legs;
    }
    
    public void eat(String food) {
        System.out.println(name+" 吃食物:"+food);
    }

    public String getName() {
        return name;
    }

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

    public int getLegs() {
        return legs;
    }

    public void setLegs(int legs) {
        this.legs = legs;
    }
    
}

子類

package visitparent;

public class Cat extends Animal{
    private String hairColor;//毛髮顏色
    private int age;
    
    public Cat () {
        super();//調用父類無參
    }
    public Cat(String name,int legs,String hairColor,int age) {
        super(name, legs);//這裏調用至關於重用父類構造方法了
        this.hairColor=hairColor;
        this.age=age;
        //super(name, legs);//去掉註釋試試
        //this.name="無名";//去掉註釋試試
    }
    public void catchMouse() {
        System.out.println(super.getName()+":抓老鼠");
    }
    
    public void paly() {
        System.out.println(super.getName()+" 玩累了。");
        super.eat("小魚乾");
    }

    public String getHairColor() {
        return hairColor;
    }

    public void setHairColor(String hairColor) {
        this.hairColor = hairColor;
    }

    public int getAge() {
        return age;
    }

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

子類不能繼承父類的 private 成員

子類不能繼承不一樣包使用默認訪問權限的成員(默認訪問權限就是不寫訪問修飾符)

子類不能繼承父類的構造方法

多重繼承的執行流程

在建立子類的時候父類在作什麼?

下面建立3個類觀察執行流程,C類繼承B類,B類繼承A類。

A.java

public class A {
    public A() {
        System.out.println("A類的無參構造函數執行");
    }
}

B.java

public class B extends A{
    public B() {
        System.out.println("B類的無參構造函數執行");
    }
}

C.java

public class C extends B{
    public C() {
        System.out.println("C類的無參構造函數執行");
    }
}

TestRunFlow.java 測試類,展現運行結果

public class TestRunFlow {
    public static void main(String[] args) {
        C c=new C();
    }
}

運行結果爲:

A類的無參構造函數執行
B類的無參構造函數執行
C類的無參構造函數執行

若是子類構造方法經過 super 顯式調用父類相應構造方法,則不執行父類無參構造方法

子類構造方法默認會調用父類無參構造方法

調用父類無參構造方法,一直到執行頂級父類Object類的的無參構造方法爲止

根據以上規則,判斷下面的代碼是否能編譯經過

父類

public class Pet {
    private String name;
    public Pet(String name) {
        this.name=name;
    }
}

子類

public class Dog extends Pet{
}

答案是不能,父類中只有有參構造方法沒有無參構造方法,子類中沒有任何代碼默認有一個隱式無參構造方法,子類無參構造方法默認調用父類無參構造方法,然而父類中沒有,全部在子類中報錯。

解決辦法:1.在父類中顯式添加無參構造方法,2.在子類構造方法中顯式調用父類有參構造方法。

java 中的訪問修飾符

訪問修飾符 protected 能修飾屬性和方法,修飾後本類、子類、同包能夠訪問。

訪問修飾符 本類 同包 子類 其餘
private
默認(friendly)
protected
public

方法重寫

在"繼承優化後"的代碼中,Teacher 繼承了 People 類,(忘記代碼能夠翻回去再看一遍) People 類中有個一個打招呼的方法 sayHi() 用於輸出人的名字,可是 Teacher 調用這個方法並不能打印出 Teacher 的屬性 teachingAge 的值,可是咱們還想用這個方法實現這個功能,應該怎麼辦呢?

咱們可使用 方法重寫 解決這個問題,修改子類 Teacher 中的代碼,下面看一下使用方法重寫後的效果。

Teacher.java

package inherit;

public class Teacher extends People{
    //省略其餘屬性
    
    @Override
    public void sayHi() {
        System.out.println("我是:"+super.getName()+" ,從事教育行業 "+this.teachingAge+" 年了。");
    }

    //省略其餘方法、getter、setter
}

在 Eclipse 中重寫某方法的快捷鍵是 Alt+Shift+S+V ,按完後選擇要重寫的方法

在 Idea 中重寫某方法的快捷鍵是 Ctrl+O ,按完後選擇要重寫的方法

@Override 註解的做用, 用來檢測是否符合重寫規則,不符合重寫規則將報錯,這個註解能夠不寫

構造方法不能重寫,由於構造方法不能被繼承

方法重寫的規則:

1.方法名相同

2.參數列表相同

3.返回值類型相同或者是其子類

4.訪問權限不能嚴於父類

final 關鍵字的使用

1.final 修飾變量後變爲常量

private static final long serialVersionUID = -6849794470754667710L;

2.final 修飾類後,該類不能被繼承

package java.lang;
public final class Math {
    //省略屬性和方法……
}

3.final 修飾方法後,該方法不能被重寫

public final void teach() {
        System.out.println("教授課程");
    }

4.final 修飾建立的對象後,該對像不能再次實例化(能夠修改屬性)

final Teacher teacher=new Teacher();
teacher.setName("湯尼");
//teacher=new Teacher();//去掉註釋試試

String 類就是一個典型的被 final 修飾的類

搜索關注公衆號「享智同行」,第一時間獲取技術乾貨

相關文章
相關標籤/搜索