多態(tài)理解
當(dāng)使用多態(tài)方式調(diào)用方法時(shí),首先檢查父類中是否有該方法,如果沒有,則編譯錯(cuò)誤;如果有,再去調(diào)用子類的同名方法
多態(tài)必要條件
- 繼承
- 重寫
- 父類引用指向子類對(duì)象
多態(tài)簡(jiǎn)單例子
package basicForMando俄精;
/*
* @name 多態(tài)
* @description 公共父類
* @question
* 1.Cat 是什么 和 Animal2 有關(guān)嗎
* 2. instanceof 如何判斷類型
* 3. (Cat)a 是什么意思 為什么帶括號(hào)
* */
public class Polymorphic {
public static void main(String[] args) {
show(new Cat());//3 Cat對(duì)象調(diào)用show方法
}
// 3.1 傳參new Cat() 到 a => Animal2 a = new Cat();
public static void show(Animal2 a){
//4.1 輸出 new Cat().eat()
a.eat();
// 判斷類型
if(a instanceof Cat){
System.out.println(a);
// instanceof Cat ?
System.out.println(a instanceof Cat);
//(Cat)a
Cat cat =(Cat)a;
//4.2 輸出 Cat().work()
cat.work();
}
}
}
//1.建立父類(超類)
abstract class Animal2{
// 方法還是變量?
abstract void eat();
}
//2.繼承父類
class Cat extends Animal2{
//2.1 重寫父類方法(父類中沒有就會(huì)報(bào)錯(cuò))
public void eat(){
System.out.println("吃魚");
}
//2.2 子類獨(dú)有方法
public void work(){
System.out.println("抓老鼠");
}
}
多態(tài)復(fù)雜例子
Employee(父類超類)
package finance;
/*
* 父類(超類)
* 構(gòu)造函數(shù)里 this.name 是成員變量private String name,name 為參數(shù)String name;
* */
public class Employee {
private String name;
private String address;
private int number;
// 父類(超類)構(gòu)造函數(shù)
public Employee(String name, String address, int number) {
System.out.println("Employee 構(gòu)造函數(shù)");
//構(gòu)造函數(shù)里 this.name 是成員變量private String name,name 為參數(shù)String name;
this.name = name;
this.address = address;
this.number = number;
}
public void mailCheck() {
System.out.println("郵寄支票給:" + this.name + " " + this.address);
}
public String toString() {
return name + " " + address + " " + number;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public void setAddress(String newAddress) {
address = newAddress;
}
public int getNumber() {
return number;
}
}
Salary(子類繼承父類)
package finance;
public class Salary extends Employee {
private double salary;//全年工資
// 繼承父類,子類構(gòu)造函數(shù)
public Salary(String name,String address,int number,double salary){
// 傳參繼承的父類Employee
super(name,address,number);
setSalary(salary);
}
public void mailCheck(){
System.out.println("Salary 類的 mailCheck 方法");
System.out.println("郵寄支票給:" + getName() +",工資為:" +salary);
}
public double getSalary(){
return salary;
}
public void setSalary(double newSalary){
if(newSalary >= 0.0){
salary = newSalary ;
}
}
public double computePay(){
System.out.println("計(jì)算公司,付給:" + getName());
return salary/52;
}
}
輸出
package finance;
public class VirtualDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Salary s = new Salary("員工 A", "北京", 3 , 3600.00);
Employee e = new Salary("員工 B", "上海", 2, 2400.00);
System.out.println("使用 Salary 的引用調(diào)用 mailCheck -- ");
s.mailCheck();
System.out.println("\n使用 Employee 的引用調(diào)用 mailCheck--");
e.mailCheck();
}
}
--print--
Employee 構(gòu)造函數(shù)
Employee 構(gòu)造函數(shù)
使用 Salary 的引用調(diào)用 mailCheck --
Salary 類的 mailCheck 方法
郵寄支票給:員工 A,工資為:3600.0
使用 Employee 的引用調(diào)用 mailCheck--
Salary 類的 mailCheck 方法
郵寄支票給:員工 B,工資為:2400.0
例子解析
- 實(shí)例中瞒窒,實(shí)例化了兩個(gè) Salary 對(duì)象:一個(gè)使用 Salary 引用 s盼忌,另一個(gè)使用 Employee 引用 e剿干。
- 當(dāng)調(diào)用 s.mailCheck() 時(shí),編譯器在編譯時(shí)會(huì)在 Salary 類中找到mailCheck(),執(zhí)行過程 JVM 就調(diào)用 Salary 類的 mailCheck()。
- 因?yàn)?e 是 Employee 的引用近范,所以調(diào)用 e 的 mailCheck() 方法時(shí)嘶摊,編譯器會(huì)去 Employee 類查找 mailCheck() 方法 延蟹。
- 在編譯的時(shí)候,編譯器使用 Employee 類中的 mailCheck() 方法驗(yàn)證該語句叶堆, 但是在運(yùn)行的時(shí)候阱飘,Java虛擬機(jī)(JVM)調(diào)用的是 Salary 類中的 mailCheck() 方法。
以上整個(gè)過程被稱為虛擬方法調(diào)用虱颗,該方法被稱為虛擬方法沥匈。
Java中所有的方法都能以這種方式表現(xiàn),因此忘渔,重寫的方法能在運(yùn)行時(shí)調(diào)用高帖,不管編譯的時(shí)候源代碼中引用變量是什么數(shù)據(jù)類型。
多態(tài)的實(shí)現(xiàn)方式
多態(tài)的實(shí)現(xiàn)方式
方式一:重寫
這個(gè)內(nèi)容已經(jīng)在上一章節(jié)詳細(xì)講過畦粮,就不再闡述散址,詳細(xì)可訪問:Java 重寫(Override)與重載(Overload)。
方式二:接口
- 生活中的接口最具代表性的就是插座宣赔,例如一個(gè)三接頭的插頭都能接在三孔插座中预麸,因?yàn)檫@個(gè)是每個(gè)國家都有各自規(guī)定的接口規(guī)則,有可能到國外就不行儒将,那是因?yàn)閲庾约憾x的接口類型吏祸。
- java中的接口類似于生活中的接口,就是一些方法特征的集合钩蚊,但沒有方法的實(shí)現(xiàn)贡翘。具體可以看 java接口 這一章節(jié)的內(nèi)容蹈矮。
方式三:抽象類和抽象方法
詳情請(qǐng)看 Java抽象類 章節(jié)。