1. 程式人生 > >Java中繼承的定義與使用

Java中繼承的定義與使用

繼承

  繼承的主要作用在於,在已有基礎上繼續進行功能的擴充。 定義兩個類(學生、人):

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; } } class Student { private String name; private int age; private String schoolName; 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; } public String getSchoolName() { return schoolName; } public void setSchoolName(String schoolName) { this.schoolName=schoolName; } }

  以上是我們定義類的方式,含有大量重複的程式碼,不僅從程式碼上重複,而且從概念上講學生一定是人,只是學生類描述的範圍小,具備更多的屬性,這個時候想要消除結構定義上的重複,就要用到繼承。

1.1 繼承的實現

  在Java中,繼承用extends關鍵字來實現,語法:class 子類 extends 父類{}   所以可將上述程式碼改為:

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;
    }
}
class Student extends Person{
   
}
public class Test2{
    public static void main(String[] args)
    {
        Student student=new Student();
        student.setName("花花");
        student.setAge(18);
        System.out.println("姓名:"+student.getName()+"  年齡:"+student.getAge());
    }
}

在這裡插入圖片描述   通過以上程式碼可以發現,當發生了類繼承關係之後,子類可以直接繼承父類的操作,可以實現程式碼的重用,子類最低也維持和父類相同的功能。   子類也可以進行功能上的擴充。

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;
    }
}
class Student extends Person{
    private String schoolName;
    public String getSchoolName()
    {
        return schoolName;
    }
    public void setSchoolName(String schoolName)
    {
        this.schoolName=schoolName;
    }
}
public class Test2{
    public static void main(String[] args)
    {
        Student student=new Student();
        student.setName("花花");
        student.setAge(18);
        student.setSchoolName("勵志中學");
        System.out.println("學校:"+student.getSchoolName() +" 姓名:"+student.getName()+"  年齡:"+student.getAge());
    }
}

在這裡插入圖片描述   繼承的主要作用是對類進行擴充以及程式碼的重用!

1.2 繼承的限制

1.2.1 子類物件在進行例項化前首先呼叫父類構造方法,產生父類物件後再呼叫子類構造方法例項化子類物件。

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;
    }
    public Person()
    {
        System.out.println("父類的構造方法");
    }
}
class Student extends Person{
    private String schoolName;
    public String getSchoolName()
    {
        return schoolName;
    }
    public void setSchoolName(String schoolName)
    {
        this.schoolName=schoolName;
    }
    public Student()
    {
        System.out.println("子類的構造方法");
    }
}
public class Test2{
    public static void main(String[] args)
    {
        Student student=new Student();
        student.setName("花花");
        student.setAge(18);
        student.setSchoolName("勵志中學");
        System.out.println("學校:"+student.getSchoolName() +" 姓名:"+student.getName()+"  年齡:"+student.getAge());
    }
}

在這裡插入圖片描述   以上程式碼我們發現,沒有任何一條語句呼叫父類構造方法。因此可以判斷,子類例項化之前一定先例項化父類物件。   注意:實際在子類構造方法中,相當於隱含了一個語句super(),同時如果父類裡沒有提供無參構造,那麼這個時候就必須使用super()明確指明你要呼叫的父類構造方法。

1.2.2 Java只允許單繼承不允許多繼承(一個子類繼承一個父類)

eg:錯誤的繼承:

class A{
}
class B{
}
class C extends A,B{
}

  C繼承A和B的主要目的是擁有A和B中的操作,為了實現這樣的目的,可以採用多層繼承的形式完成。

class A{
}
class B extends A{
}
class C extends B{
}

  Java中不允許多重繼承,但是允許多層繼承!

1.2.3 在繼承時,子類會繼承父類的所有結構。

(包括私有域與其它屬性、方法) 顯示繼承:所有非私有操作屬於顯示繼承(可以直接呼叫)。 隱式繼承:所有私有操作屬於隱式繼承(不可以直接呼叫,需要通過其它形式呼叫(getter/setter))。

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;
    }
    public Person()
    {
        System.out.println("父類的構造方法");
    }
    public void fun()
    {
        System.out.println("好好學習。");
    }
}
class Student extends Person{
    private String schoolName;
    public String getSchoolName()
    {
        return schoolName;
    }
    public void setSchoolName(String schoolName)
    {
        this.schoolName=schoolName;
    }
    public Student()
    {
        System.out.println("子類的構造方法");
    }
}
public class Test2{
    public static void main(String[] args)
    {
        Student student=new Student();
        student.setName("花花");
        student.setAge(18);
        //隱式繼承
        System.out.println("姓名:"+student.getName()+" 年齡:"+student.getAge());
        //顯示繼承
        student.fun();
    }
}

在這裡插入圖片描述   此時父類中的屬性以及方法均被子類所繼承,但是發現子類能夠使用的是所有非private操作,而所有的private操作無法被直接使用,所以稱為隱式繼承。 在這裡插入圖片描述

阿里java校招筆試題

class HelloA {
        //構造方法
        public HelloA(){
            System.out.println("Hello A!父類構造方法");
        }
        //非靜態程式碼塊
        {
            System.out.println("i'm A class.父類非靜態程式碼塊");
        }
        //靜態程式碼塊
         static{
             System.out.println("static A 父類靜態程式碼塊");      }
}
public class HelloB extends HelloA {
    //構造方法
    public HelloB() {
        System.out.println("Hello B! 構造方法");
    }
    //非靜態程式碼塊
    {
        System.out.println("i'm B class.非靜態程式碼塊");
    }
    //靜態程式碼塊
    static{
        System.out.println("static B 靜態程式碼塊");
    }
    public static void main(String[] args) {
            System.out.println("---start- ");
            new HelloB();
            new HelloB();
            System.out.println("---end- ");
    }
}

在這裡插入圖片描述 在這裡插入圖片描述