深入解析Java多態(tài)進(jìn)階學(xué)習(xí)
1.動態(tài)綁定機(jī)制
java的動態(tài)綁定機(jī)制非常重要
實(shí)例A
我們來看一個實(shí)例:
閱讀上面的代碼,請說明下面的程序?qū)⑤敵鍪裁唇Y(jié)果:
程序?qū)敵?0和30,這個實(shí)例很簡單,直接看運(yùn)行類型即可,該代碼的運(yùn)行類型為B,所以會調(diào)用B類的方法
實(shí)例B
我們將上面的代碼變通一下,將子類中的如下代碼塊注銷:
隨后繼承機(jī)制會訪問父類的sum方法:
那么這里有一個問題,此處的getI(),會執(zhí)行子類的還是父類的呢?
當(dāng)調(diào)用對象方法的時(shí)候,該方法會和該對象的內(nèi)存地址/運(yùn)行類型綁定
代碼的運(yùn)行類型依然是B,所以此處會執(zhí)行子類的getI()方法,結(jié)果輸出為30
實(shí)例C
現(xiàn)在我們再變通以下上面的代碼
再將子類中如下的代碼塊注銷:
繼承機(jī)制會執(zhí)行父類的sum1方法:
那么這里有一個問題,此處的i,會使用子類的還是父類的呢?
屬性沒有動態(tài)綁定機(jī)制,哪里聲明,哪里使用(使用當(dāng)前類的)
此處的i在父類進(jìn)行聲明,所以會選用父類的i屬性,結(jié)果為20
2.多態(tài)數(shù)組
定義:
數(shù)組的定義類型為父類類型,但是保存的實(shí)際元素類型為子類類型
Person父類:
/** * 多態(tài)數(shù)組父類 */ public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String say() { return name + '\t' + age; } }
Student子類:
/** * 多態(tài)數(shù)組學(xué)生子類 */ public class Student extends Person{ private double score; public Student(String name, int age, double score) { super(name, age); this.score = score; } // 重寫父類的say方法 public String say() { return super.say() + '\t' + score; } }
Teacher子類:
/** * 多態(tài)數(shù)組教師子類 */ public class Teacher extends Person { private double sal; public Teacher(String name, int age, double sal) { super(name, age); this.sal = sal; } public double getSal() { return sal; } public void setSal(double sal) { this.sal = sal; } public String say() { return super.say() + '\t' + sal; } }
測試多態(tài)數(shù)組的使用:
public class Test { public static void main(String[] args) { // 多態(tài)數(shù)組的使用 Person[] persons = new Person[5]; persons[0] = new Person("dahe",20); persons[1] = new Student("wangwei",11,100); persons[2] = new Student("zhangsan",12,60); persons[3] = new Teacher("wang",33,15000); persons[4] = new Teacher("li",55,25000); // 循環(huán)遍歷多態(tài)數(shù)組,調(diào)用say方法 for (int i = 0; i < persons.length; i++) { String out = persons[i].say(); // 動態(tài)綁定機(jī)制,編譯類型永遠(yuǎn)都是Person // 運(yùn)行類型是根據(jù)實(shí)際情況由JVM機(jī)決定 System.out.println(out); } } }
輸出:
dahe 20
wangwei 11 100.0
zhangsan 12 60.0
wang 33 15000.0
li 55 25000.0
3.多態(tài)數(shù)組的高階用法
現(xiàn)在,教師子類新增了教學(xué)方法:
public void teach() { System.out.println("老師:" + getName() + "正在講課!"); }
學(xué)生子類新增了學(xué)習(xí)方法:
public void study() { System.out.println("學(xué)生:" + getName() + "正在學(xué)習(xí)!"); }
那么,有沒有辦法通過多態(tài)數(shù)組來訪問他們子類對應(yīng)的獨(dú)有的方法呢?事實(shí)上,可以通過巧妙使用instanceof來解決:
變通一下,改變多態(tài)數(shù)組的循環(huán)操作:
// 循環(huán)遍歷多態(tài)數(shù)組,調(diào)用say方法 for (int i = 0; i < persons.length; i++) { String out = persons[i].say(); // 動態(tài)綁定機(jī)制,編譯類型永遠(yuǎn)都是Person // 運(yùn)行類型是根據(jù)實(shí)際情況由JVM機(jī)決定 System.out.println(out); if (persons[i] instanceof Student) { // 向下轉(zhuǎn)型 Student student = (Student) persons[i]; student.study(); } else if (persons[i] instanceof Teacher) { Teacher teacher = (Teacher) persons[i]; teacher.teach(); } }
輸出:
dahe 20
wangwei 11 100.0
學(xué)生:wangwei正在學(xué)習(xí)!
zhangsan 12 60.0
學(xué)生:zhangsan正在學(xué)習(xí)!
wang 33 15000.0
老師:wang正在講課!
li 55 25000.0
老師:li正在講課!
大功告成!多態(tài)數(shù)組即強(qiáng)大又完美!
4.多態(tài)參數(shù)
方法定義的形參類型為父類類型,實(shí)參類型允許為子類類型
接下來我們來演示以下多態(tài)參數(shù)的使用:
父類:
/** * 多態(tài)參數(shù) - 父類 */ public class Employee { private String name; private double sal; public Employee(String name, double sal) { this.name = name; this.sal = sal; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSal() { return sal; } public void setSal(double sal) { this.sal = sal; } // 得到年工資的方法 public double getAnnual() { return 12 * sal; } }
員工子類:
/** * 多態(tài)參數(shù) - 子類員工 */ public class Worker extends Employee{ public Worker(String name, double sal) { super(name, sal); } public void work() { System.out.println("普通員工:" + getName() + "正在工作!"); } public double getAnnual() { return super.getAnnual(); } }
經(jīng)理子類:
/** * 多態(tài)參數(shù) - 經(jīng)理子類 */ public class Manager extends Employee{ private double bonus; // 獎金 public Manager(String name, double sal, double bonus) { super(name, sal); this.bonus = bonus; } public double getBonus() { return bonus; } public void setBonus(double bonus) { this.bonus = bonus; } public void manage() { System.out.println("經(jīng)理:" + getName() + "正在管理!"); } @Override public double getAnnual() { return super.getAnnual() + bonus; } }
我們來測試一下,求不同崗位的雇員的年薪:
/** * 多態(tài)參數(shù)測試類 */ public class Test { public static void main(String[] args) { Worker zhang = new Worker("張工",1000); Manager milan = new Manager("milan", 5000, 2000); Test test = new Test(); test.showEmpAnnual(zhang); test.showEmpAnnual(milan); } // 獲取員工的年薪,采用多態(tài)參數(shù) public void showEmpAnnual(Employee e) { System.out.println(e.getAnnual()); } }
輸出:
12000.0
62000.0
5.多態(tài)參數(shù)的高階用法
我們來對上面的多態(tài)參數(shù)代碼做一個完善,如果傳入的是員工,則調(diào)用自己的work方法,如果傳入的是經(jīng)理,則調(diào)用自己的manage方法
增加一個下面的方法:
public void testWork(Employee e) { if (e instanceof Worker) { ((Worker) e).work(); // 向下轉(zhuǎn)型 } else if (e instanceof Manager) { ((Manager) e).manage(); } }
測試:
test.testWork(zhang); test.testWork(milan);
輸出:
普通員工:張工正在工作!
經(jīng)理:milan正在管理!
到此這篇關(guān)于深入解析Java多態(tài)進(jìn)階學(xué)習(xí)的文章就介紹到這了,更多相關(guān)Java多態(tài)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)在線編輯預(yù)覽office文檔詳解
PageOffice是一款在線的office編輯軟件,幫助Web應(yīng)用系統(tǒng)或Web網(wǎng)站實(shí)現(xiàn)用戶在線編輯Word、Excel、PowerPoint文檔,下面我們就來看看如何使用Java實(shí)現(xiàn)在線預(yù)覽office吧2024-01-01SpringBoot @Scope與@RefreshScope注解使用詳解
spring的bean管理中,每個bean都有對應(yīng)的scope。在BeanDefinition中就已經(jīng)指定scope,默認(rèn)的RootBeanDefinition的scope是prototype類型,使用@ComponentScan掃描出的BeanDefinition會指定是singleton,最常使用的也是singleton2022-11-11Java?guava框架LoadingCache及CacheBuilder本地小容量緩存框架總結(jié)
Guava?Cache本地緩存框架主要是一種將本地?cái)?shù)據(jù)緩存到內(nèi)存中,但數(shù)據(jù)量并不能太大,否則將會占用過多的內(nèi)存,本文給大家介紹Java?guava框架?LoadingCache及CacheBuilder?本地小容量緩存框架總結(jié),感興趣的朋友一起看看吧2023-12-12如何將maven項(xiàng)目導(dǎo)出jar包(最簡單方法)
大家都知道對于將maven項(xiàng)目導(dǎo)出jar包有好幾種方式,本文給大家分享一種方式最容易且最方便,感興趣的朋友跟隨小編一起看看吧2023-11-11java爬蟲之使用HttpClient模擬瀏覽器發(fā)送請求方法詳解
這篇文章主要介紹了java爬蟲之使用HttpClient模擬瀏覽器發(fā)送請求方法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07