深入解析Java多態(tài)進(jìn)階學(xué)習(xí)
1.動(dòng)態(tài)綁定機(jī)制
java的動(dòng)態(tài)綁定機(jī)制非常重要
實(shí)例A
我們來看一個(gè)實(shí)例:

閱讀上面的代碼,請說明下面的程序?qū)⑤敵鍪裁唇Y(jié)果:

程序?qū)?huì)輸出40和30,這個(gè)實(shí)例很簡單,直接看運(yùn)行類型即可,該代碼的運(yùn)行類型為B,所以會(huì)調(diào)用B類的方法
實(shí)例B
我們將上面的代碼變通一下,將子類中的如下代碼塊注銷:

隨后繼承機(jī)制會(huì)訪問父類的sum方法:

那么這里有一個(gè)問題,此處的getI(),會(huì)執(zhí)行子類的還是父類的呢?
當(dāng)調(diào)用對象方法的時(shí)候,該方法會(huì)和該對象的內(nèi)存地址/運(yùn)行類型綁定
代碼的運(yùn)行類型依然是B,所以此處會(huì)執(zhí)行子類的getI()方法,結(jié)果輸出為30
實(shí)例C
現(xiàn)在我們再變通以下上面的代碼
再將子類中如下的代碼塊注銷:

繼承機(jī)制會(huì)執(zhí)行父類的sum1方法:

那么這里有一個(gè)問題,此處的i,會(huì)使用子類的還是父類的呢?
屬性沒有動(dòng)態(tài)綁定機(jī)制,哪里聲明,哪里使用(使用當(dāng)前類的)
此處的i在父類進(jìn)行聲明,所以會(huì)選用父類的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(); // 動(dòng)態(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(); // 動(dòng)態(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; // 獎(jiǎng)金
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ù)代碼做一個(gè)完善,如果傳入的是員工,則調(diào)用自己的work方法,如果傳入的是經(jīng)理,則調(diào)用自己的manage方法
增加一個(gè)下面的方法:
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-01
SpringBoot @Scope與@RefreshScope注解使用詳解
spring的bean管理中,每個(gè)bean都有對應(yīng)的scope。在BeanDefinition中就已經(jīng)指定scope,默認(rèn)的RootBeanDefinition的scope是prototype類型,使用@ComponentScan掃描出的BeanDefinition會(huì)指定是singleton,最常使用的也是singleton2022-11-11
Java?guava框架LoadingCache及CacheBuilder本地小容量緩存框架總結(jié)
Guava?Cache本地緩存框架主要是一種將本地?cái)?shù)據(jù)緩存到內(nèi)存中,但數(shù)據(jù)量并不能太大,否則將會(huì)占用過多的內(nèi)存,本文給大家介紹Java?guava框架?LoadingCache及CacheBuilder?本地小容量緩存框架總結(jié),感興趣的朋友一起看看吧2023-12-12
如何將maven項(xiàng)目導(dǎo)出jar包(最簡單方法)
大家都知道對于將maven項(xiàng)目導(dǎo)出jar包有好幾種方式,本文給大家分享一種方式最容易且最方便,感興趣的朋友跟隨小編一起看看吧2023-11-11
java爬蟲之使用HttpClient模擬瀏覽器發(fā)送請求方法詳解
這篇文章主要介紹了java爬蟲之使用HttpClient模擬瀏覽器發(fā)送請求方法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07

