天天看點

深入了解面向對象中的封裝與繼承

在學習spring中又對面向對象中的封裝與繼承有了更加深入的了解,以前總覺得一個子類要繼承一個父類,隻會繼承父類中的非私有屬性及方法。但是事實并不是這樣的。

對于成員變量的繼承,其底層是記憶體空間的複制,是資料的拷貝,如果我們在Animal類裡寫如下代碼

public class Animal {
  private String name = "張三";
  public 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;
  }
}      

然後我們設計一個Cat類繼承Animal類

public class Cat extends Animal{
}      

然後進行測試

public class Test {
  public static void main(String[] args) {
    Cat cat = new Cat();
    System.out.println(cat.getName());
  }
}      

此時,它将輸出張三,也就是說Cat類将Animal類全部繼承,并且将資料進行了拷貝

如果是進行方法的繼承,記憶體空間是沒有增加的,但是如果進行方法重寫的話,會在Cat類的記憶體空間裡新開辟一段記憶體空間,比如我們在Cat類裡将父類Animal類的call方法進行重載

public class Cat extends Animal{
  @Override
  public void call(){
    System.out.println("貓咪叫");
  }
}      

然後進行測試

public class Test {
  public static void main(String[] args) {
    Cat cat = new Cat();
    System.out.println(cat.getName());
    cat.call();
  }
}      

此時将輸出

張三
貓咪叫      

這時Cat類裡的call方法又重新開辟了一段新的空間

靜态方法也是可以覆寫的,如果一個字類繼承了一個父類,而且他們都有一個方法名相同的靜态方法,如果删掉字子類的的靜态方法,他會自動調用父類的靜态方法,比如現在Animal的代碼為

public class Animal {
  private String name = "張三";
  public 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 static void call(){
    System.out.println("動物叫");
  }
}      

Cat類為

public class Cat extends Animal{
  public static void call(){
    System.out.println("貓咪叫");
  }
}      

Test類為

public class Test {
  public static void main(String[] args) {
    Cat.call();
    Animal.call();
  }
}      

輸出為:

貓咪叫
動物叫      
public class Cat extends Animal{
}      
動物叫
動物叫