Java面向?qū)ο蠡A(chǔ)之多態(tài)性,抽象類(lèi)和接口
一、多態(tài)性
多態(tài)是指一個(gè)對(duì)象可以擁有多種不同的形態(tài),繼承是實(shí)現(xiàn)多態(tài)的基礎(chǔ)。
1.1 引用多態(tài)和方法多態(tài)
引用多態(tài):父類(lèi)引用可以指向本類(lèi)的對(duì)象,也可以指向子類(lèi)的對(duì)象
方法多態(tài):
1、創(chuàng)建本類(lèi)對(duì)象時(shí),調(diào)用的方法為本類(lèi)方法;
2、創(chuàng)建子類(lèi)對(duì)象時(shí),調(diào)用的方法為子類(lèi)重寫(xiě)或繼承的方法。
首先建立父類(lèi)Animal,包含一個(gè)eat()方法,如下代碼所示:
public class Animal { public void eat(){ System.out.println("動(dòng)物可以吃東西"); } }
然后建立子類(lèi)Dog繼承父類(lèi)Animal,并重寫(xiě)eat()方法。
public class Dog extends Animal{ public void eat(){ System.out.println("狗狗可以吃東西"); } }
最后建立一個(gè)Cat類(lèi)繼承Animal,并獨(dú)有g(shù)etMouse()方法。
public class Cat extends Animal{ public void getMouse(){ System.out.println("貓會(huì)抓老鼠"); } }
通過(guò)測(cè)試類(lèi)進(jìn)行測(cè)試發(fā)現(xiàn),父類(lèi)的引用不能調(diào)用子類(lèi)獨(dú)有的方法。
public class InitTest { public static void main(String[] args) { Animal obj1 = new Animal();//父類(lèi)的引用指向本類(lèi)對(duì)象 Animal obj2 = new Dog();//父類(lèi)的引用指向子類(lèi)對(duì)象 Animal obj3 = new Cat(); obj1.eat();//動(dòng)物可以吃東西 obj2.eat();//20歲的狗狗可以吃東西 obj3.eat();//動(dòng)物可以吃東西 } }
1.2 引用類(lèi)型轉(zhuǎn)換
向上類(lèi)型轉(zhuǎn)換(隱式或自動(dòng)類(lèi)型轉(zhuǎn)換):子類(lèi)轉(zhuǎn)換為父類(lèi)對(duì)象
向下類(lèi)型轉(zhuǎn)換(強(qiáng)制類(lèi)型轉(zhuǎn)換):父類(lèi)轉(zhuǎn)換為子類(lèi),有風(fēng)險(xiǎn)
向上類(lèi)型轉(zhuǎn)換好比是把杯子中的水倒進(jìn)壺里,不會(huì)存在風(fēng)險(xiǎn);而向下類(lèi)型轉(zhuǎn)換則是把壺里的水倒進(jìn)杯子里,可能會(huì)溢出。為了避免這種風(fēng)險(xiǎn)的發(fā)生,可以使用instanceof關(guān)鍵字進(jìn)行判斷。如下代碼所示:
public class InitTest { public static void main(String[] args) { Animal obj = new Dog();//向上類(lèi)型轉(zhuǎn)換 if(obj instanceof Dog){ Dog dog = (Dog)obj; //向下類(lèi)型轉(zhuǎn)換 }else{ System.out.println("不能進(jìn)行Dog類(lèi)型轉(zhuǎn)換"); } if(obj instanceof Cat){ Cat cat = (Cat)obj; }else{ System.out.println("不能進(jìn)行Cat類(lèi)型轉(zhuǎn)換"); } } }
程序能夠正常運(yùn)行,且不能進(jìn)行Cat類(lèi)型轉(zhuǎn)換。
二、抽象類(lèi)與接口
2.1 抽象類(lèi)
當(dāng)某個(gè)父類(lèi)只知道子類(lèi)應(yīng)該包含這些方法卻不知如何實(shí)現(xiàn)時(shí),需要用到抽象類(lèi)。抽象類(lèi)用abstract關(guān)鍵字修飾,它限制子類(lèi)必須有哪些方法,但不關(guān)注實(shí)現(xiàn)。抽象類(lèi)中可以包含普通方法,也可以沒(méi)有方法。
例:利用抽象類(lèi)編寫(xiě)程序,求矩形和圓的周長(zhǎng)和面積。
實(shí)現(xiàn)步驟:
1、抽象出矩形和圓形的抽象類(lèi)Shape作為父類(lèi),并定義要實(shí)現(xiàn)的方法求周長(zhǎng)premeter()和求面積area();
2、分別創(chuàng)建子類(lèi)Rectangle和Circle,繼承抽象父類(lèi)Shape;
3、根據(jù)相關(guān)圖形的求解算法,分別實(shí)現(xiàn)父類(lèi)的抽象方法。
public abstract class Shape { public abstract double perimeter(); public abstract double area(); } public class Rectangle extends Shape { double length; double width; public Rectangle(double length,double width){ this.length = length; this.width = width; } @Override public double perimeter() { return 2*(length+width); } @Override public double area() { return length*width; } } public class Circle extends Shape { double radius; final double PI = 3.14; public Circle(double radius){ this.radius = radius; } @Override public double perimeter() { return 2*PI*radius; } @Override public double area() { return PI*radius*radius; } } 這里,由于不同的形狀求解周長(zhǎng)和面積時(shí),需要的參數(shù)個(gè)數(shù)不同,在定義抽象方法中無(wú)法統(tǒng)一給出參數(shù),可以在子類(lèi)中定義變量,通過(guò)初始化構(gòu)造方法進(jìn)行參數(shù)的傳遞。下面是測(cè)試方法代碼: public class ShapeTest { public static void main(String[] args) { Shape s1 = new Rectangle(2,4); Shape s2 = new Circle(3.9); System.out.println("矩形的周長(zhǎng):"+s1.perimeter()); System.out.println("矩形的面積:"+s1.area()); System.out.println("圓形的周長(zhǎng):"+s2.perimeter()); System.out.println("圓形的面積:"+s2.area()); } }
2.2 接口
接口是一種特殊的類(lèi),由全局變量和公共方法組成。它定義了某一批類(lèi)的規(guī)范,而不關(guān)心這些類(lèi)的內(nèi)部數(shù)據(jù)和實(shí)現(xiàn)細(xì)節(jié),只規(guī)定這些類(lèi)里必須提供某些方法。
接口里的屬性是常量,默認(rèn)會(huì)加上public static final三個(gè)關(guān)鍵字,接口里的方法只能是抽象方法,默認(rèn)會(huì)加上public abstract關(guān)鍵字。
一個(gè)類(lèi)可以實(shí)現(xiàn)多個(gè)接口,但類(lèi)必須是先繼承,然后實(shí)現(xiàn)接口。
例:傻瓜機(jī)和智能機(jī)繼承了父類(lèi)手機(jī),父類(lèi)的抽象方法里面都定義了打電話和發(fā)短信的功能,而智能機(jī)和PSP都有玩游戲的功能。此時(shí)PSP不具備手機(jī)的特征所以不宜繼承手機(jī)類(lèi),而可以將玩游戲定義為一個(gè)接口,由智能機(jī)和PSP實(shí)現(xiàn)。
public interface IPlayGame { public void playGame(); } public class SmartPhone extends Telphone implements IPlayGame{ @Override public void call() { System.out.println("SmartPhone可以打電話"); } @Override public void message() { System.out.println("SmartPhone可以發(fā)短信"); } @Override public void playGame() { System.out.println("玩游戲的功能"); } } public class PSP implements IPlayGame{ @Override public void playGame() { System.out.println("玩游戲的功能"); } } public class InterfaceTest { public static void main(String[] args) { IPlayGame ip1 = new SmartPhone(); IPlayGame ip2 = new PSP(); ip1.playGame(); ip2.playGame(); } }
接口還可以通過(guò)匿名內(nèi)部類(lèi)的方式實(shí)現(xiàn),即沒(méi)有名字的內(nèi)部類(lèi)。此方式常用于高級(jí)開(kāi)發(fā)中。
public static void main(String[] args) { IPlayGame ip3 = new IPlayGame(){ @Override public void playGame() { System.out.println("使用匿名內(nèi)部類(lèi)的方式實(shí)現(xiàn)接口"); } }; ip3.playGame(); }
注:文章根據(jù)本站相關(guān)課程的學(xué)習(xí)筆記整理而來(lái),有錯(cuò)誤或其他任何問(wèn)題敬請(qǐng)指正,歡迎共同學(xué)習(xí)交流!
以上就是Java面向?qū)ο蠡A(chǔ):多態(tài)性,抽象類(lèi)和接口的詳細(xì)內(nèi)容,更多關(guān)于Java面向?qū)ο蠖鄳B(tài)性 抽象類(lèi)和接口的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java實(shí)現(xiàn)web實(shí)時(shí)消息推送的七種方案
這篇文章主要為大家介紹了java實(shí)現(xiàn)web實(shí)時(shí)消息推送的七種方案示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07關(guān)于Java類(lèi)的構(gòu)造方法詳解
這篇文章主要介紹了關(guān)于Java類(lèi)的構(gòu)造方法詳解的相關(guān)資料,需要的朋友可以參考下2023-01-01SpringBoot整合Mybatis-Plus、Jwt實(shí)現(xiàn)登錄token設(shè)置
Spring Boot整合Mybatis-plus實(shí)現(xiàn)登錄常常需要使用JWT來(lái)生成用戶(hù)的token并設(shè)置用戶(hù)權(quán)限的攔截器,本文就來(lái)詳細(xì)的介紹一下,具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02SpringSecurity集成圖片驗(yàn)證碼的詳細(xì)過(guò)程
SpringSecurity是通過(guò)過(guò)濾器鏈來(lái)完成的,接下來(lái)的驗(yàn)證碼,可以嘗試創(chuàng)建一個(gè)過(guò)濾器放到Security的過(guò)濾器鏈中,在自定義的過(guò)濾器中比較驗(yàn)證碼,本文通過(guò)實(shí)例代碼介紹SpringSecurity集成圖片驗(yàn)證碼的詳細(xì)過(guò)程,感興趣的朋友一起看看吧2023-12-12一文解決pom.xml報(bào)錯(cuò)Dependency "xxx" not f
我們?cè)谑褂胢aven進(jìn)行jar包管理時(shí)有時(shí)會(huì)遇到pom.xml中報(bào)錯(cuò)Dependency “XXX” not found,所以在本文中將給大家介紹一下pom.xml報(bào)錯(cuò)Dependency "xxx" not found的解決方案,需要的朋友可以參考下2024-01-01多個(gè)springboot項(xiàng)目如何使用一個(gè)外部共同的application.yml
這篇文章主要介紹了多個(gè)springboot項(xiàng)目如何使用一個(gè)外部共同的application.yml問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05JAVA查詢(xún)MongoDB的幾種方法小結(jié)
本文主要介紹了JAVA查詢(xún)MongoDB的幾種方法小結(jié),通過(guò)閱讀本文,讀者可以了解如何使用Java查詢(xún)MongoDB,并在實(shí)際應(yīng)用中應(yīng)用這些技能,具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08Java Collections集合繼承結(jié)構(gòu)圖_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java Collections集合繼承結(jié)構(gòu)圖_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理,需要的朋友可以參考下2017-04-04