java知識點總結(繼承,封裝,多態)

java就是一個面向對象的思想,而面向對象有三大特性:

  • 封裝
  • 繼承
  • 多態

封裝

1,定義:

封裝把一個對象的屬性私有化,同時提供一些可以被外界訪問的屬性的方法。

2,好處:

1,實現了低耦合高內聚。
2,類內部的結構可以自由修改。
3,隱藏實現細節,提供公共的訪問方式。

繼承

1,概述:

繼承就是子類繼承父類的特徵、行爲,體現了類與類之間的"is-a"關係。A類是B類的父類,可以說B類是A類的子類,B類繼承了A類各種的方法和屬性(私有化的除外)。子類繼承父類的同時,可以重新定義某些屬性,並重寫某些方法,即覆蓋父類的原有屬性和方法,使其獲得與父類不同的功能。

繼承通過關鍵字extends實現。

java.lang.Object類是所有類的父類

2,限制:

1,java中繼承是單繼承,即一個子類只能繼承一個父類。
2,支持多重繼承,即一個父類可以有多個子類。
3,繼承只能繼承非私有化的屬性和方法。
4,構造方法不能被繼承。

3,格式:

class 子類名 extends 父類名{}

案例:

public class Animal{
	String name;
	String age;
	public void eat(){
	Sysotem.out.println(name+"動物在吃肉"+age)
	}
}

public class cat extends Animal{
	Cat cat = new Cat();
	c.name="tOM";
	c.age=18;
	p.eat();
}

輸出:
在這裏插入圖片描述
4,子類滿足重寫父類方法的要求

  • 重寫方法與被重寫方法必須具有相同的方法名。
  • 重寫方法與被重寫方法必須具有相同的參數列表。
  • 重寫方法的返回值類型必須和被重寫方法的返回值類型相同
  • 重寫方法不能縮小被重寫方法的訪問權限。

5,重寫方法和重載的區別和聯繫

重載涉及同一個類中的同名方法,要求方法名相同,要求參數列表不同,與返回值類型,訪問修飾符無關,而重寫涉及的是子類和父類之間的同名方法,要求方法名稱相同,參數列表相同,

6,方法重載

  • 當子類繼承父類時,可以從父類繼承它的屬性和方法。
  • 如果從父類繼承的方法不能滿足子類的需求,可以對其進行改寫,這個過程叫方法的覆蓋(override),也稱爲方法的重寫。
  • 當對父類的方法進行重寫時,子類中的方法必須和父類中對應的方法具有相同的方法名稱、輸入參數(包括參數的個數和類型)和返回值。
  • 子類中的覆蓋方法不能使用比父類中被覆蓋方法更嚴格的訪問權限。

7,構造器
父類的構造器只能夠被調用,而不能被子類繼承。

如果父類沒有構造器,java會給出一個默認構造器。父類帶有一個帶參的構造器,子類必須通過super關鍵字來調用父類的構造器並配以相關的參數。

父類構造器沒有參數,則在子類的構造器中不需要使用 super 關鍵字調用父類構造器,系統會自動調用父類的無參構造器。

創建父類:

class Animal{
    private Integer high;
 
    public Animal() {
        System.out.println("Animal()");
    }
 
    public Animal(Integer high) {
        System.out.println("Animal(Integer high)");
        this.high = high;//this表示對該對象的引用
    }
 
//    set、get方法
    public Integer getHigh() {
        return high;
    }
 
    public void setHigh(Integer high) {
        this.high = high;
    }
}

創建子類:

class Dog extends Animal{
    private String name;
 
    public Dog() {
        System.out.println("Dog()");
    }
 
    public Dog(String name) {
        this.name = name;
        System.out.println("Dog(String name)");
    }
 
    public Dog(Integer high) {
        super(high);
        System.out.println("Dog(Integer high)");
    }
 
    public Dog(Integer high, String name) {
        super(high);
        this.name = name;
        System.out.println("Dog(Integer high, String name)");
    }
 
//    set、get方法
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
}

創建測試類:

public class MyMain {
    public static void main(String[] args) {
        System.out.println("- - - - - - - new Dog() - - - - - - -");
        Dog dog = new Dog();
 
        System.out.println("- - - - - - - new Dog(Integer high) - - - - - - -");
        Dog highDog = new Dog(180);
 
        System.out.println("- - - - - - - new Dog(String name) - - - - - - -");
        Dog nameDog  = new Dog("張二狗");
 
        System.out.println("- - - - - - - new Dog(Integer high, String name) - - - - - - -");
        Dog highNameDog = new Dog(180,"張二狗");
 
    }
}

結果:

- - - - - - - new Dog() - - - - - - -
Animal()
Dog()
- - - - - - - new Dog(Integer high) - - - - - - -
Animal(Integer high)
Dog(Integer high)
- - - - - - - new Dog(String name) - - - - - - -
Animal()
Dog(String name)
- - - - - - - new Dog(Integer high, String name) - - - - - - -
Animal(Integer high)
Dog(Integer high, String name)

1.子類通過super調用父類構造器

子類通過super()調用父類無參構造器;通過super(參數)調用父類有參構造器;如果不寫super,子類默認調用父類無參構造器

2.子類創建對象時,父類構造器會先執行。

super必須放在子類構造器內第一行,否則會報錯。

3,多態

同一個對象在不同時刻體現出來的不同狀態。例如,動物中有貓和狗,都有吃這個共性,而貓吃魚,狗吃骨頭。

繼承的前提:

  • 繼承
  • 重寫
  • 父類引用指向子類對象

當提到多態時,不得不提出向上轉型。

class Animal{}
class Dog extends Animal{}
Animal a = new Dog()//向上轉型


將子類轉換成父類,在繼承關係上面是向上移動的,所以一般稱之爲向上轉型。

在這裏我們這樣理解,這裏定義了一個 Animal 類型的a,它指向 Dog 對象實例。由於Dog 是繼承 Animal,所以 Dog 可以自動向上轉型爲Animal,所以 a 是可以指向Dog 實例對象的。這樣做存在一個非常大的好處,在繼承中我們知道子類是父類的擴展,它可以提供比父類更加強大的功能,如果我們定義了一個指向子類的父類引用類型,那麼它除了能夠引用父類的共性外,還可以使用子類強大的功能。

但是向上轉型存在一些缺憾,那就是它必定會導致一些方法和屬性的丟失,而導致我們不能夠獲取它們。所以父類類型的引用可以調用父類中定義的所有屬性和方法,卻不能調用子類中的方法和屬性。

當使用多態方式調用方法時,首先檢查父類中是否有該方法,如果沒有,則編譯錯誤;如果有,再去調用子類的同名方法。這是多態的一個弊端:不能使用子類特定的功能

public class test {
    public static void main(String[] args) {
        father people = new son();
        people.speak();
        System.out.println("i am "+people.getAge());
        people.play();
    }
}

class father{
    private int age ;
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void speak() {
        System.out.println("i am father !");
    }
}
class son extends father{
     public son() {
        setAge(17);
    }
    public void speak(){
        System.out.println("i am son !");
    }
    public void play(){
        System.out.println("i am son , i want to play!");
    }
}

這個例子的結果會報錯,因爲父類沒有play()方法。對於子類中存在而父類中不存在的方法,該引用是不能使用的,儘管是重載該方法。

實現多態的方式:

  • 接口多態性
  • 繼承多態性
  • 通過抽象類實現的多態性

4,多態和繼承的區別

繼承:子類繼承父類中所以的屬性和方法,但是對於private的屬相和方法,由於這個是父類的隱私,所以子類雖然是繼承了,但是沒有可以訪問這些屬性和方法的引用,所以相當於沒有繼承到。很多時候,可以理解爲,沒有繼承。

多態:就是父類引用可以持有子類對象。這時候只能調用父類中的方法,而子類中特有方法是無法訪問的,因爲這個時候(編譯時)你把他看作父類對象的原因,但是到了運行的時候,編譯器就會發現這個父類引用中原來是一個子類的對像,所以如果父類和子類中有相同的方法時,調用的會是子類中的方法,而不是父類的。可以這麼說:編譯時看父類,運行時看子類。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章