1. 程式人生 > >Java學習之繼承

Java學習之繼承

面向物件的語言一共有四大特性:封裝、繼承、多型、抽象,Java作為面向物件的語言之一,同時也滿足了這幾個特性。繼承能夠帶來的最大好處,就是對程式碼的複用。但是繼承也存在著許多的缺點。下面先講述一下Java繼承的優缺點:

好處

  1. 有效減少程式碼的冗餘,程式碼簡潔
  2. 能夠提升開發效率

缺點

  1. 打破了封裝,迫使開發者瞭解超類的實現細節,子類和超類耦合度高。
  2. 超類更新後可能會導致子類發生錯誤

下面簡單舉一個例子說明繼承

public class Person {
    protected String name;
    protected int age;
    protected
String sex; Person() { System.out.println("Person Constructor!"); } public Person(String name, int age, String sex) { this.name = name; this.age = age; this.sex = sex; } } //定義一個員工類繼承Person class Employee extends Person{ private double salary; //無參建構函式
Employee(){ //編譯器自動呼叫父類無參建構函式 System.out.println("Employee Constructor!"); } //有參建構函式 Employee(String name, int age, String sex, double salary){ //手動呼叫父類有參建構函式 super(name,age,sex); this.salary=salary; } @Override public String toString() { return
"Employee{" + "name='" + name + '\'' + ", age=" + age + ", sex='" + sex + '\'' + ", salary=" + salary + '}'; } public static void main(String[] args) { Employee ee1=new Employee(); Employee ee2=new Employee("張三",20,"男",6000.00); System.out.println(ee1); System.out.println(ee2); } }

執行結果如下:

Person Constructor!
Employee ConstructorEmployee{name='null', age=0, sex='null', salary=0.0}
Employee{name='張三', age=20, sex='男', salary=6000.0}

從上面的例子,我們來說明幾個問題:

構造器

我們都知道建構函式是不能被繼承的,只能被子類呼叫。在上面的例子中,父類的構造方法先執行,然後才是子類的構造方法。因為當類實現繼承時,預設的會將基類的一個子物件傳給子類,而子類需要對這個子物件進行初始化,所以需要呼叫父類的構造器,但是,這一切都是隱式進行的。並且,子類自動呼叫的只能是父類的無參構造方法,==如果父類只定義了有參構造方法(預設的無參構造方法自然也就不存在),子類則需要使用super關鍵字來呼叫有參構造方法,並且super必須在子類構造方法的第一行==。

此外,在討論繼承時,還要注意以下幾種情況: 1. 子類只能繼承父類非private許可權的屬性和方法。 2. 當子類呼叫一個方法時,如果在子類中沒有找到,它會往父類去找。這其中可能涉及向上轉型或者一些方法的覆蓋重寫等。

針對第二種情況舉個例子:

class A{
    int a=10;
    void Print(){
        System.out.println(a);
        System.out.println(getClass().getName());
    }
}
class B extends A {
    int a = 20;

/*    void Print() {
        System.out.println(a);
        System.out.println(getClass().getName());
        System.out.println(this.a);
        System.out.println(super.a);
    }*/
    public static void main(String[] args) {
        B b=new B();
        b.Print();
    }
}

輸出結果:

10
JavaReview.Inherit.B

上述程式碼中,我們註釋了B類中的Print方法,系統就自動呼叫了父類的方法,但是呼叫getClass()獲取的仍然是B。當我們將上述程式碼中的註釋去掉,則輸出:

20
JavaReview.Inherit.B
20
10

即子類的Print方法會被優先呼叫,而super則是呼叫父類的資訊,this關鍵字呼叫的是當前類的資訊。