首頁 > 軟體

一起來了解Java的態和抽象類

2022-03-14 19:01:01

多型:

我們知道Java的三大特性:封裝、繼承、多型。前兩個之前在Java入門(六)已經講到,現在來講多型這個特性。

什麼是多型?

多型顧名思義即為多種形態的意思

Java中多型的含義:

1.傳送訊息給某個物件,讓這個物件自行決定採用哪種行為響應這個訊息

2.子類物件的參照賦值給父類別參照變數來實現動態的方法呼叫

Java中形成多型的前提:

1.繼承

2.父類別方法的重寫

3.向上轉型

我對多型的解釋:

比如我們,是人,也是學生,也是年輕人,我可以用人的身份去做事情,也可以用學生的身份去買學生票,也可以用年輕人的身份做公益,這樣我們可以通過不同的形態去做不同的事情。這樣是不是更好理解一點?

注意:

多型前提條件:必須有子父類別關係。

在使用多型後的父類別參照變數呼叫方法時,會呼叫子類重寫後的方法。

多型的定義與使用格式:

父類別型別 變數名=new 子類型別();

多型中成員的特點:

  • 多型成員變數:編譯執行看左邊
  • 多型成員方法:編譯看左邊,執行看右邊

多型的轉型:

  • 多型的轉型分為向上轉型和向下轉型兩種
  • 向上轉型:多型本身就是向上轉型過的過程

使用格式:父類別型別 變數名=new 子類型別();

適用場景:當不需要面對子類型別時,通過提高擴充套件性,或者使用父類別的功能就能完成相應的操作。

  • 向下轉型:一個已經向上轉型的子類物件可以使用強制型別轉換的格式,將父類別參照型別轉為子類參照各型別
  • 使用格式:子類型別 變數名=(子類型別) 父類別型別的變數;

適用場景:當要使用子類特有功能時。

程式碼解釋:

public class Person {     //人類,作為父類別使用
    public void speak(){
        System.out.println("我們都是一個人");
    }
}
public class Student extends Person{    //繼承父類別,相當於我們是學生,有人的方法
    @Override
    public void speak(){
        System.out.println("我是人類中的學生");
    }
}
public class Child extends Person{   //繼承父類別,相當於我們是孩子,有孩子的行為
    @Override
    public void speak(){
        System.out.println("我是人類中的孩子");
    }
}

//測試類
public class TestMain {
    public static void main(String[] args) {
		//父類別型別 變數名=new 子類型別();
        Person p = new Student();   //子類物件的參照賦值給父類別 
        p.speak(); //多型 相當於這裡使用的是Student的方法。輸出我是人類中的學生
        //我作為人,我用學生的身份,說出:我是人類中的學生
		Person p = new Child(); 
		p.speak();  //輸出:我是人類中的孩子
		//我作為人,用孩子的身份,說出我是人類中的孩子
    }
}
//這段程式碼,我們用到了 繼承,重寫,向上轉型,因為多型本來就是向上轉型的過程

多型的作用:介紹完多型,講講多型有什麼用呢?為什麼多型可以作為Java的三大特性。肯定是有原因的:

  • 提高程式碼的可重用性
  • 降低模組之間的耦合度

這裡給大家介紹一下什麼是多型機制?Java語言是如何實現多型的?(可能有點難以理解,本人對於該內容也沒用理解充分,但這也是面試會考的題)

所謂多型就是指程式中定義的參照變數所指向的具體型別和通過該參照變數發出的方法呼叫在程式設計時並不確定,而是在程式執行期間才確定,即一個參照變數倒 底會指向哪個類的範例物件,該參照變數發出的方法呼叫到底是哪個類中實現的 方法,必須在由程式執行期間才能決定。因為在程式執行時才確定具體的類,這樣,不用修改源程式程式碼,就可以讓參照變數繫結到各種不同的類實現上,從而 導致該參照呼叫的具體方法隨之改變,即不修改程式程式碼就可以改變程式執行時 所繫結的具體程式碼,讓程式可以選擇多個執行狀態,這就是多型性。 多型分為編譯時多型和執行時多型。其中編輯時多型是靜態的,主要是指方法的 過載,它是根據參數列的不同來區分不同的函數,通過編輯之後會變成兩個不 同的函數,在執行時談不上多型。而執行時多型是動態的,它是通過動態繫結來 實現的,也就是我們所說的多型性。

對於多型的理解,還可以參考一段程式碼:

class People{     //父類別
    public void eat(){
        System.out.println("我們會吃飯");
    }
}

class Student extends People{  //繼承父類別
    @Override
    public void eat(){
        System.out.println("我會吃肉");
    }
    public void study(){
        System.out.println("我們要好好學習");
    }
}

class Teacher extends People{     //繼承父類別
    @Override
    public void eat(){
        System.out.println("老師會吃蔬菜");
    }
    public void teach(){
        System.out.println("老師要認真上課");
    }
}
//測試類:
public class TestMain {
    public static void main(String[] args) {
        People p=new Stu();      //子類物件的參照賦值給父類別 
        p.eat();       //輸出: 我會吃肉
    }
}

抽象類:

什麼是抽象類?

普通類是一個完善的功能類,可以直接產生範例化物件,並且在普通類中可以包含有構造方法、普通方法、static方法、常數和變數等內容。而抽象類是指在普通類的結構裡面增加抽象方法的組成部分。

抽象方法:

在所有的普通方法上面都會有一個“{}”,這個表示方法體,有方法體的方法一定可以被物件直接使用。而抽象方法,是指沒有方法體的方法,同時抽象方法還必須使用關鍵字abstract做修飾。也就是說,抽象類裡面的抽象方法,可以不寫,在被繼承後,再重寫。

抽象類宣告關鍵字: abstracat

定義一個抽象類:

public abstract class studnet{//定義一個抽象類
	public void study(){                         //普通方法
		System.out.println("我會學習");
	}
	public abstract void eat();         //抽象方法,沒有方法體,有abstract關鍵字做修飾
}
//注意: 有抽象方法,這個類必須是抽象的!!!

舉例解釋:形狀類Shape需要提供用於計算面積和周長的方法,但是形狀本身沒有被確定,那麼計算周長和麵積的方法就無法確定,此時我們就需要使用抽象類和抽象方法。

由於Shape類計算周長和麵積的方法無法確定,那麼就可以將這樣的方法宣告為抽象的,以便在具體的子類中進行實現。

//定義一個shape類,但是沒有具體的形狀,所以我們定義成抽象類
public abstract class Shape {
    private int a;
    public abstract void area(){}     //求面積的方法
    public abstract void perimeter();   //求周長的方法
    public Shape() {    //無參構造
    }
    public Shape(int a) {
        this.a = a;
    }
}
//計算圓形面積的子類
public  abstract class shape {    //有抽象方法的類,則一定是抽象類,需要關鍵字abstract修飾
        private int a;
        public abstract void area();     //求面積的方法,沒有方法體的方法,需要關鍵字abstract修飾
        public abstract void perimeter();   //求周長的方法
}

//建立計算圓面積和周長的子類,並繼承抽象類shape,並重寫shape內的方法
public class Circle extends shape{
    public static double pi = 3.14;
    private double r;  //半徑

    @Override
    public void area() {
        System.out.println("圓的面積:"+Circle.pi*this.r*this.r);
    }
    @Override
    public void perimeter() {
        System.out.println("圓的周長為:"+2*Circle.pi*this.r);
    }
    public Circle() {
    }
    public Circle(double r) {  //
        this.r = r;
    }
}

//測試類:
public class TestMain {
    public static void main(String[] args) {
        Circle c = new Circle(5);        //傳入半徑為:5
        c.area();
        c.perimeter();
    }
}
//輸出結果: 圓的面積:78.5
//			圓的周長為:31.400000000000002

抽象方法和抽象類的注意事項:

  • 抽象類中是可以有建構函式的,並且建構函式的寫法和其它類沒有區別,只不過它真正跑起來是因為子類建構函式的super呼叫,畢竟我們沒辦法new一個抽象類物件出來,只能把抽象類別建構函式交給子類別建構函式去使用。
  • 抽象類中不一定包含抽象方法,但是有抽象方法的類一定是抽象類。
  • 抽象類的子類,必須重寫父類別中所有的抽象方法,如果有一個抽象方法沒有重寫,都會出現編譯錯誤不給過,這時也可以把子類也宣告為抽象類,報錯就會消失。

簡潔總結:

  • 抽象方法:沒有方法體的方法,需要關鍵字abstract修飾
  • 有抽象方法的類,則一定是抽象類,需要關鍵字abstract修飾
  • 抽象方法不能使用private和static修飾
  • 抽象類,不一定有抽象方法的類
  • 抽象類,不一定有抽象方法的類
  • 抽象類可以有建構函式

普通類和抽象類有哪些區別?

  • 普通類不能包含抽象方法,抽象類可以包含抽象方法
  • 抽象類不能直接範例化,普通類可以直接範例化。

總結

本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注it145.com的更多內容!    


IT145.com E-mail:sddin#qq.com