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]-继承、多态、抽象类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 澳洲龙虾蒸多久才熟
- 下一篇: 征信系统多久更新一次(征信一般几号更新一