日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java不用抽象类实现多态_原来你是这样的JAVA[03]-继承、多态、抽象类

發布時間:2024/9/19 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java不用抽象类实现多态_原来你是这样的JAVA[03]-继承、多态、抽象类 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、繼承

Java中的繼承使用關鍵字extends ,跟C#的語法略有差別。

1.子類構造器

java會自動在子類的構造器中插入對父類構造器的調用,也就是說在子類可以訪問父類之前已經完成了父類的初始化。

如果想調用帶參數的父類構造器,應該使用super關鍵字。

/***@author陳敬

* @date 18/1/17*/

public classProduct {privateString name;publicProduct(String name) {this.name =name;

System.out.println("[Product constructor]");

}

}public class Bread extendsProduct {private intprice;public Bread(String name, intprice) {super(name);//調用父類構造器this.price =price;

System.out.println("[Bread constructor]");

}

}

我們創建一個Bread類的實例,看看調用順序。

@Testpublic voidtestConstructor(){

Bread bread=new Bread("毛毛蟲面包",10);

}

打印結果:

[Product constructor]

[Bread constructor]

2.調用父類方法

子類是不能直接訪問到父類的私有域的,如果想訪問只能借助父類公開的get訪問器。子類調用父類中的方法也需要使用super關鍵字。

public classProduct {privateString name;publicString getName() {returnname;

}publicProduct(String name) {this.name =name;

}

}public class Bread extendsProduct {publicBread(String name) {super(name);

}public voiddisplay(){

System.out.println(getName());

}

}

然后寫個單元測試:

@Testpublic voidtestPrivate(){

Bread bread=new Bread("毛毛蟲面包");

bread.display();//毛毛蟲面包

}

需要說明一點,super并不是一個對象的引用,不能將super賦值給變量,它只是一個特殊的關鍵字,告訴編輯器要調用父類中的方法。

3.關于重載

如果父類中存在重載方法,子類又進行了重載,會覆蓋父類中的方法嗎?實際上,父類和子類中的方法都可以正常重載,不會被覆蓋。

首先在父類Product中添加方法getDescription():

public classProduct {

……publicString getDescription() {return "[Product]name="+name;

}

}

然后在子類中重載該方法:

public class Bread extendsProduct {

……publicString getDescription(String storeName) {return "[Bread]storename="+storeName;

}

}

增加一個單元測試:

public classExtendClassTests {

@Testpublic voidtestOverload(){

Bread bread=new Bread("豆沙面包",9);

System.out.println(bread.getDescription());

System.out.println(bread.getDescription("味多美"));

}

}

輸出:

[Product]name=豆沙面包

[Bread]storename=味多美

4.繼承準則

繼承準則:盡量少用繼承。一般用繼承表達行為間的差異,用組合表示狀態上的變化。

二、多態

1.變量多態

在Java中對象變量是多態的,一個Product變量可以引用Product對象,也可以引用一個Product子類的對象。

@Test

public void testParent(){

Product product=new Bread("毛毛蟲面包",10);

product.display();

//強制類型轉換

if(product instanceof Bread){

Bread brand=(Bread)product;

brand.display("味多美");

}

}

由于Bread實例向上轉型為Product類型,所以不能再調用Bread.getDescription(String storeName)方法。

如果需要將父類強制轉換為子類時,要先通過instanceof檢測對象類型,我們最好盡量避免使用強制類型轉換。

2.動態綁定

所謂動態綁定,就是在運行時根據對象的類型決定要調用的方法。在java中,動態綁定是默認行為,不需要添加額外的關鍵字實現多態。

再寫個demo來看一下,在父類和子類中重載了display方法。

public classProduct {privateString name;publicProduct(String name) {this.name =name;

}public voiddisplay() {

System.out.println("[Product]getDescription()");

}

}public class Bread extendsProduct {private intprice;public Bread(String name, intprice) {super(name);this.price =price;

}

@Overridepublic voiddisplay() {

System.out.println("[Bread]getDescription()");

}public voiddisplay(String storeName) {

System.out.println("[Bread]getDescription(String storeName)");

}

}

添加單元測試:

@Testpublic voiddynamicBind(){

Product product=new Product("product");

product.display();//[Product]getDescription()

Bread bread=new Bread("毛毛蟲",9);

bread.display();//[Bread]getDescription()

bread.display("maimai"); //[Bread]getDescription(String storeName)

Product product1=bread;

product1.display();//[Bread]getDescription()

}

虛擬機為每個類創建一個方法表,列出所有方法的簽名和實際調用的方法。這樣一來,當動態調用方法的時候,只需要查找方法表就能快速的找到真正調用的方法了。

Product:

display()->Product.display()

Bread:

display()->Bread.display()

display(String name)->Bread.display(String name)

完整源碼參見:https://github.com/cathychen00/cathyjava???? /_08_extend

三、抽象類

定義抽象方法用用abstract關鍵字,它僅有聲明而沒有方法體。

包含抽象方法的類叫做抽象類,如果一個類包含一個或多個抽象方法,那么必須被定義為抽象類。

如果一個類從抽象類繼承,那么必須為抽象類中的所有抽象方法提供實現,否則該類也必須被定義為抽象類。

看一個場景:我們有一些定時任務,要進行的工作流程類似,只有具體一部分細節內容不同。我們可以定義一個抽象基類BaseJob,再不同的部分封裝為抽象方法,具體的實現在子類中進行。

public abstract classBaseJob {public voidrun(){

System.out.println("==START "+getDescription()+"==");

String lastJobId=getLastJobId();

execute(lastJobId);

writeLog();

System.out.println("==END "+getDescription()+"==");

}protected abstractString getDescription();protected abstract voidexecute(String jobId);private voidwriteLog() {

System.out.println("write log to DB");

}privateString getLastJobId() {return "job1221";

}

}

public class ArticleJob extendsBaseJob {

@OverrideprotectedString getDescription() {return "抓取文章任務";

}

@Overrideprotected voidexecute(String jobId) {

System.out.println("抓取站點新聞文章 jobid="+jobId);

}public static voidmain(String[] args) {

BaseJob articleJob=newArticleJob();

articleJob.run();

}

}

創建單元測試,調用ArticleJob看看。

@Testpublic voidarticleJob(){

BaseJob articleJob=newArticleJob();

articleJob.run();

}

運行結果:

==START 抓取文章任務==抓取站點新聞文章 jobid=job1221

write log to DB==END 抓取文章任務==

當再次添加符合該流程的定時任務時,只需要新建一個類,實現BaseJob就可以了。

總結

以上是生活随笔為你收集整理的java不用抽象类实现多态_原来你是这样的JAVA[03]-继承、多态、抽象类的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。