Java基礎之方法重寫詳解

一、java方法重寫

方法的重寫是子類根據需求對父類繼承的方法進行重新的編寫,在重寫時,可以使用super方法的方式來保留父類中的方法,註意:構造方法不可以被重寫。

創建一個人類,屬性包括姓名 性別 年齡 行為方法是輸出信息

二、super關鍵字

方法重寫時要在子類中定義一個和父類相同名稱的方法,並采用super關鍵字super.方法名();,這樣就實現瞭方法的重寫

package cn.zhz.Kind.dh;

public class Person1 {
    public String sex;
    public String name;
    public int age;

    public void showInfo() {
        System.out.println("姓名:" + name + "年齡:" + age + "性別:" + sex);
    }
}

創建一個學生類,屬性包括學號 學科,行為方法是輸出信息

package cn.zhz.Kind.dh;

public class Student1 extends Person1{
    public int stuId;
    public String stuSubject;
    public void showInfo(){
        super.showInfo();
        System.out.println("學號:"+ stuId+ "學科:"+ stuSubject);
    }
}

創建學生類的一個實例,進行賦值操作,賦值後輸出

package cn.zhz.Case.dh;

import cn.zhz.Kind.dh.Student1;

public class Student1Test {
    public static void main(String[] args) {
        Student1 student1 = new Student1();
        student1.stuId = 1;
        student1.name = "張三";
        student1.age = 18;
        student1.sex = "男";
        student1.stuSubject = "物理";
        student1.showInfo();
    }
}

2.1 super關鍵字的介紹

super可以應用在子類訪問父類成員中,比如說:

訪問父類的屬性super.print(); 註意是非private的方法
訪問父類的方法super.name;
訪問父類的構造方法super();

package cn.zhz.Inherit.dh;

public class Pet {
    private String name = "無名氏";
    private int health = 100;
    private int love = 0;
    public int age = 1;

    public Pet() {
        System.out.println("父類無參構造方法");
    }

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

    public Pet(String name, int health, int love) {
        //this可以調用本類的構造方法,且在第一行
        //this(name);
        this.name = name;
        this.health = health;
        this.love = love;
        System.out.println("父類帶參構造方法");
    }

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

    public int getAge() {
        return age;
    }

    public void setHealth(int health) {
        if (health < 0 || health > 100) {
            System.out.println("寵物的健康值在0-100之間");
            this.health = 60;
            return;
        }
        this.health = health;
    }

    public int getHealth() {
        return this.health;
    }

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

    public String getName() {
        return this.name;
    }

    public void setLove(int love) {
        if (love < 0 || love > 100) {
            System.out.println("寵物的親密度隻能在0-100之間");
            this.love = 60;
            return;
        }
        this.love = love;
    }

    public int getLove() {
        return this.love;
    }

    //輸出寵物的信息
    public void print() {
        System.out.println("寵物的自白:\n我的名字叫" + this.name + "健康值是" + this.health + "和主人的親密度是:" + this.love);
    }
}
package cn.zhz.Inherit.dh;

public class Dog extends Pet {
    private String strain = "聰明的拉佈拉多犬";

    public Dog() {
        System.out.println("子類狗狗的無參構造方法");
    }

    public Dog(String name, int health, int love, String strain) {
        //通過super調用父類的構造方法,必須是第一句
        //super();
        super(name, health, love);
        this.strain = strain;
        System.out.println("狗狗的帶參構造方法");
    }

    public void setStrain(String strain) {
        this.strain = strain;
    }

    public String getStrain() {
        return this.strain;
    }

    public void print() {
        //調用父類的非private的print()方法
        super.print();
        System.out.println("我是一隻" + this.strain);
    }

    public void m1() {
        //super不可以調用父類的private屬性
//        System.out.println(super.name);
        System.out.println(super.age);
    }
}

在使用super關鍵字來訪問父類的成員時,使用super關鍵字,super代表的是父類的對象,super隻可以出現在子類的方法和構造方法中,使用super調用構造方法時,隻可以是第一句,super不可以訪問父類的private成員。

2.2 super關鍵字的使用

當子類中的方法重寫瞭父類的方法,或者是在子類中定義瞭和父類的同名稱的成員變量,使用super關鍵字可以使被屏蔽的成員可見。.

package cn.zhz.Inherit.dh;

public class Pet {
    private String name = "無名氏";
    private int health = 100;
    private int love = 0;
    public int age = 1;

    public Pet() {
        System.out.println("父類無參構造方法");
    }

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

    public Pet(String name, int health, int love) {
        //this可以調用本類的構造方法,且在第一行
        //this(name);
        this.name = name;
        this.health = health;
        this.love = love;
        System.out.println("父類帶參構造方法");
    }

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

    public int getAge() {
        return age;
    }

    public void setHealth(int health) {
        if (health < 0 || health > 100) {
            System.out.println("寵物的健康值在0-100之間");
            this.health = 60;
            return;
        }
        this.health = health;
    }

    public int getHealth() {
        return this.health;
    }

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

    public String getName() {
        return this.name;
    }

    public void setLove(int love) {
        if (love < 0 || love > 100) {
            System.out.println("寵物的親密度隻能在0-100之間");
            this.love = 60;
            return;
        }
        this.love = love;
    }

    public int getLove() {
        return this.love;
    }

    //輸出寵物的信息
    public void print() {
        System.out.println("寵物的自白:\n我的名字叫" + this.name + "健康值是" + this.health + "和主人的親密度是:" + this.love);
    }
}

子類和父類中同時定義瞭一個age屬性,子類調用這個age屬性時先會在本類中找,這時可以使用super關鍵字代表父類,用super.屬性的方式調用父類中的age屬性

package cn.zhz.Inherit.dh;

public class Dog extends Pet {
    private String strain = "聰明的拉佈拉多犬";
    private int age = 10;

    public Dog() {
        System.out.println("子類狗狗的無參構造方法");
    }

    public Dog(String name, int health, int love, String strain) {
        //通過super調用父類的構造方法,必須是第一句
        //super();
        super(name, health, love);
        this.strain = strain;
        System.out.println("狗狗的帶參構造方法");
    }

    public void setStrain(String strain) {
        this.strain = strain;
    }

    public String getStrain() {
        return this.strain;
    }

    public void print() {
        //調用父類的非private的print()方法
        super.print();
        System.out.println("我是一隻" + this.strain);
    }

    public void m1() {
        //super不可以調用父類的private屬性
//        System.out.println(super.name);
        System.out.println(super.age);
    }

    public void m2() {
        //子類會覆蓋服瞭誒的同名成員
        System.out.println(this.age);
        //可以使用super關鍵字調用父類被子類覆蓋的成員
        System.out.println(super.age);
    }
}

super和this的區別

區別 this super
訪問屬性 訪問本類的屬性,如果沒有則從父類中找 訪問父類中的屬性
訪問方法 訪問本類方法,如果沒有從父類中找 訪問父類的方法
訪問構造方法 調用本類的構造方法,方法構造方法的首行 調用父類的構造方法,放在子類的構造方法的首行

總結的來說是this代表的是本類,而super代表的是父類
因為super代表的是父類,那麼如果聲明瞭多個類時,子類中如果要訪問父類的父類的成員,難道要使用的是super.super.的方式嗎?

package cn.zhz.Kind;

//爺爺類
public class Animal {
    private int age;
    private String sex;

    public int getAge() {
        return age;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public void print() {
        System.out.println("爺爺類下的方法");
    }
}
package cn.zhz.Kind;

public class Person extends Animal {
    public String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
package cn.zhz.Kind;

//孫子類
public class Student extends Person {
    private String sid;

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

    @Override
    public void print() {
        //訪問父類的父類的成員,不可以使用super.super.的方法,可以直接使用super.print();來進行調用
        super.print();
        System.out.println("這個是孫子類下的方法");
    }
}
package cn.zhz.Instance;

import cn.zhz.Kind.Student;

public class StudentTest {
    public static void main(String[] args) {
        Student student = new Student();
        student.print();
    }
}

Student孫子類調用Animal爺爺類時也是通過super.成員的方式來調用,這是因為java是隻支持單根繼承的,一個類隻可以有一個直接父類,但是一個類可以有多個的間接父類

三、繼承下的構造方法的調用規則

package cn.zhz.Kind;

public class Car {
    private int site = 4;
    Car(){
        System.out.println("載客量是"+site+"人");
    }
    public void setSite(int site){
        this.site = site;
    }
    public void print(){
        System.out.println("載客量是"+site+"人");
    }
}
package cn.zhz.Kind;

public class Bus extends Car{
    public Bus(int site){
        setSite(site);
    }
}
package cn.zhz.Instance;

import cn.zhz.Kind.Bus;

public class BusTest {
    public static void main(String[] args) {
        Bus bus = new Bus(20);
        bus.print();
    }
}

子類構造方法沒有通過super顯示調用父類的有參構造方法,也沒有通過this顯示調用自身的其他構造方法時,系統會默認調用父類的無參構造方法

子類構造方法通過super顯示調用父類的有參構造方法時,執行父類相應的構造方法,而不執行父類無參構造方法

子類構造方法通過this顯示調用自身的其他構造方法,在相應構造方法中應用以上的兩條規則

四、深入理解方法重寫

 方法重寫規則

方法名稱相同
參數列表相同
返回值類型相同或者是其子類
訪問權限不可以嚴於父類
父類的靜態方法不可以背子類覆蓋為非靜態方法,父類的非靜態方法不可以背子類覆蓋為靜態方法
子類可以定義於父類同名的靜態方法,以便在子類中隱藏父類的靜態方法(靜態方法中無法使用super)
父類的私有方法不可以被子類覆蓋
不可以跑出比父類方法更多的異常

package cn.zhz.Kind;

public class Father {
    public void m1() {
        System.out.println("父類的m1的方法");
    }
    //同一個類中同名不同參的是方法重載
    public String m1(int num1){
        return "test";
    }
    //方法返回值類型可以是自定義的數據類型
    public Father m2() {
        System.out.println("父類的m2方法");
        return new Father();
    }
    public static void m3(){
        System.out.println("父類的靜態方法m3");
    }
    private void m4(){
        System.out.println("父類的私有方法m4");
    }
}
package cn.zhz.Kind;

public class Son extends Father {
    //子類重寫方法不可以比父類方法訪問權限小,可以擴大方法的訪問權限
    //子類方法隻要訪問權限不嚴於父類,就構成瞭方法重寫
    public void m1() {
        System.out.println("子類重寫後的m1方法");
    }
    //方法重寫是父子類的同名同參的
    //子類方法返回值類型可以是父類方法返回值類型的子類,也是方法重寫
    public Son m2() {
        System.out.println("子類重寫後的m2方法");
        return new Son();
    }
    /*
    父類的靜態方法不能被重寫為非靜態方法
    反之,父類的非靜態方法也不可以被重寫為靜態方法
    public void m3(){
        System.out.println("子類的非靜態方法m3");
    }
     */
    //在子類中可以定義和父類一模一樣的靜態方法
    public static void m3(){
        //在靜態方法中不可以使用super
//        super.m3();
        Father.m3();
        System.out.println("子類的非靜態方法m3");
    }
    public static void main(String[] args) {
        Son son = new Son();
        son.m1();
        son.m2();
        Son.m3();
    }
}
比較項 位置 方法名稱 參數列表 返回值 權限訪問修飾符
方法重寫 子類 相同 相同 相同或是其子類 不可以比父類更嚴格
方法重載 同類 相同 不相同 無關 無關

到此這篇關於Java基礎之方法重寫詳解的文章就介紹到這瞭,更多相關java方法重寫內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: