我們知道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修饰
抽象类,不一定有抽象方法的类
抽象类,不一定有抽象方法的类
抽象类可以有构造函数
普通类和抽象类有哪些区别?
普通类不能包含抽象方法,抽象类可以包含抽象方法
抽象类不能直接实例化,普通类可以直接实例化。
以上是Java的態和抽象類別是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!