1借浊、什么是多態(tài)塘淑?
概念:同一操作作用于不同的對象,可以有不同的解釋蚂斤,產(chǎn)生不同的執(zhí)行結(jié)果存捺,這就是多態(tài)性。簡單的說: “一個接口曙蒸,多種實現(xiàn)”捌治。
2、為什么要用多態(tài)呢纽窟?
原因:我們知道肖油,封裝可以隱藏實現(xiàn)細(xì)節(jié),使得代碼模塊化臂港;繼承可以擴(kuò)展已存在的代碼模塊(類)森枪;它們的目的都是為了——代碼重用视搏。而多態(tài)除了代碼的復(fù)用性外,還可以解決項目中緊偶合的問題,提高程序的可擴(kuò)展性.县袱。耦合度講的是模塊模塊之間浑娜,代碼代碼之間的關(guān)聯(lián)度,通過對系統(tǒng)的分析把他分解成一個一個子模塊式散,子模塊提供穩(wěn)定的接口筋遭,達(dá)到降低系統(tǒng)耦合度的的目的,模塊模塊之間盡量使用模塊接口訪問暴拄,而不是隨意引用其他模塊的成員變量漓滔。
3、多態(tài)在什么地方用揍移?
可以用在方法的參數(shù)中和方法的返回類型中次和。
在方法中的參數(shù),請看下面的例子:
public abstract class Driver{
public void run();//讓子類來運行
}
class SBenz extends Driver{
public void run(){
Console.WriteLine("Benz在以200邁的速度在run");
}
}
class JD extends Driver{
public void run(){
Console.WriteLine("JD is running...");
}
}
class Person{
private Driver driver;
public Person(){
}
public Person(Driver driver){
this.driver = driver;
}
public void drive(){
driver.run();
}
public void setDriver(Driver driver){
//運用參數(shù)多態(tài),以后不管買什么車都可以
this.driver = driver;
}
}
static void Main(string[] args){
Person p = new Person();
JD jd = new JD();//剛開始沒錢就買輛JD吧
p.setDriver(jd);
p.drive();
SBenz benz = new SBenz();//有錢換車了
p.setDriver(benz);
p.drive();
}
在方法的返回類型中那伐,請看下面的例子(工廠模式):
public class CarFactory{
public Driver factory(String carName){
if (carName.Equals("JD")){
return new JD();
} else if (carName.Equals("Benz")){
return new SBenz();
} else {
Console.WriteLine("對不起,不伺候");
return null;
}
}
}
4踏施、實現(xiàn)原理:動態(tài)綁定
Java 的方法調(diào)用有兩類,動態(tài)方法調(diào)用與靜態(tài)方法調(diào)用罕邀。靜態(tài)方法調(diào)用是指對于類的靜態(tài)方法的調(diào)用方式畅形,是靜態(tài)綁定的;而動態(tài)方法調(diào)用需要有方法調(diào)用所作用的對象诉探,是動態(tài)綁定的日熬。類調(diào)用 (invokestatic) 是在編譯時刻就已經(jīng)確定好具體調(diào)用方法的情況,而實例調(diào)用 (invokevirtual) 則是在調(diào)用的時候才確定具體的調(diào)用方法肾胯,這就是動態(tài)綁定竖席,也是多態(tài)要解決的核心問題。
相關(guān)面試題
class A {
public String show(D obj)...{
return ("A and D");
}
public String show(A obj)...{
return ("A and A");
}
}
class B extends A{
public String show(B obj)...{
return ("B and B");
}
public String show(A obj)...{
return ("B and A");
}
}
class C extends B...{}
class D extends B...{}
問題:以下輸出結(jié)果是什么敬肚?
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
System.out.println(a1.show(b)); ①
System.out.println(a1.show(c)); ②
System.out.println(a1.show(d)); ③
System.out.println(a2.show(b)); ④
System.out.println(a2.show(c)); ⑤
System.out.println(a2.show(d)); ⑥
System.out.println(b.show(b)); ⑦
System.out.println(b.show(c)); ⑧
System.out.println(b.show(d)); ⑨
答案
① A and A
② A and A
③ A and D
④ B and A
⑤ B and A
⑥ A and D
⑦ B and B
⑧ B and B
⑨ A and D
分析:
做這種題的話要時時刻刻使用那個優(yōu)先級順序: 優(yōu)先級從高到低:this.show(O)毕荐、super.show(O)、this.show((super)O)艳馒、super.show((super)O)憎亚。
①,②,③調(diào)用a1.show()方法,a1 屬于A類弄慰,A類有兩個方法show(D obj)和show(A obj)第美。①a1.show(b),參數(shù)b為A類的子類對象陆爽,這里為向上轉(zhuǎn)型什往,相當(dāng)于A obj=b;所以調(diào)用show(A obj)方法慌闭,得到A and A結(jié)果别威。②同理第献,③參數(shù)為d,調(diào)用show(D obj),得到A and D兔港。
④,⑤仔拟,⑥調(diào)用a2.show()方法衫樊,A a2 = new B();是向上轉(zhuǎn)型,所以對a2方法的調(diào)用利花,使用A1類的方法show(D obj)和show(A obj)科侈,但此時show(A obj)已經(jīng)被重寫為return ("B and A"), ④a2.show(b)炒事,調(diào)用show(A obj)臀栈,得到B and A。⑤同理挠乳,⑥調(diào)用show(D obj)权薯,得到A and D。
⑦睡扬,⑧盟蚣,⑨調(diào)用b.show()方法,b為B類,B類的show方法有繼承的show(D obj)卖怜,自己的兩個show(B obj)屎开、show(A obj)。
⑦調(diào)用show(B obj)马靠,得到B and B奄抽,⑧向上轉(zhuǎn)型,調(diào)用show(B obj)甩鳄,得到B and B⑨show(D obj)逞度,得到A and D
參考文獻(xiàn)
[1]Java多態(tài)性理解
[2]java提高篇之理解java的三大特性——多態(tài)
[3]java多態(tài)實現(xiàn)原理
[4]深入理解java多態(tài)性