java向上轉型思考

https://www.cnblogs.com/bangaj/p/5813738.html
下面是對向上轉型思考

作用:簡化開發,體現類的多態性  保證代碼簡潔

實現前提

            因爲java是動態綁定特點,在編譯時會編譯器會自動找尋到 是子類方法還是父類的(我想主要是依據實例類型,而不是父類引用)

 使用場景

            1:在面向對象編程中,對一類業務邏輯進行抽象時,創建時是不知道具體入參類型的,但是類型或者對象又基本是相似的,這時候就需要抽象出來基類作爲入參實現高內聚;

            2:在使用中,每個擴展類實現不同業務,這時提現了多態;

            3:儘管該方法需要父類,而你傳進來的是其子類,剩下的編譯器會做後續操作從而準確知道該調用基類還是擴展類的方法;

             編譯器在這裏做的操作:f.is(A a)

                        1):找到 f 以及它父類所有is方法;

                        2 ):找到is方法入參和A最相似的

                        3):將a向上轉型,查看f中有沒有is方法,沒有就去父類找


在《think of java》中對'向上轉型'有着如下的描述

看完之後很蒙圈,所以自己在網上找了一些描述,並自己做了簡單的總結

 

簡單的例子

class A{ 
public void A1(){
  System.out.println("父類方法1");
}
public void A2() {
  System.out.println("父類方法2");
}
}

class B extends A{
public void A1() {
  System.out.println("子類方法1");
}
public void B2() {
  System.out.println("子類方法2");
}
}

public class C{
public static void main(String args[]){
  A a=new B(); //upcast

  a.A1;

  a.A2;
}
}

輸出:System.out.println("子類方法1"); 

   System.out.println("父類方法2"); 

說明:

A a=new B();
向上轉型,通俗點就是說先創建一個B子類對象,然後把它強制轉型爲A類對象。所以A類A1()方法被子類B中的A1()方法覆蓋,而子類中的B2()丟失。

 

來自CSDN。通俗易懂。
我們在現實中常常這樣說:這個人會唱歌。在這裏,我們並不關心這個人是黑人還是白人,是成人還是小孩,也就是說我們更傾向於使用抽象概念“人”。再例如,麻雀是鳥類的一種(鳥類的子類),而鳥類則是動物中的一種(動物的子類)。我們現實中也經常這樣說:麻雀是鳥。這兩種說法實際上就是所謂的向上轉型,通俗地說就是子類轉型成父類。這也符合Java提倡的面向抽象編程思想。來看下面的代碼:
package a.b;
public class A {
public void a1() {
System.out.println("Superclass");
}
}
A的子類B:
package a.b;
public class B extends A {
public void a1() {
System.out.println("Childrenclass"); //覆蓋父類方法
}
public void b1(){} //B類定義了自己的新方法
}
C類:
package a.b;
public class C {
public static void main(String[] args) {
A a = new B(); //向上轉型
a.a1();
}
}
如果運行C,輸出的是Superclass 還是Childrenclass?不是你原來預期的Superclass,而是Childrenclass。這是因爲a實際上指向的是一個子類對象。當然,你不用擔心,Java虛擬機會自動準確地識別出究竟該調用哪個具體的方法。不過,由於向上轉型,a對象會遺失和父類不同的方法,例如b1()。有人可能會提出疑問:這不是多此一舉嗎?我們完全可以這樣寫:
B a = new B();
a.a1();
確實如此!但這樣就喪失了面向抽象的編程特色,降低了可擴展性。其實,不僅僅如此,向上轉型還可以減輕編程工作量。來看下面的顯示器類Monitor:
package a.b;
public class Monitor{
public void displayText() {}
public void displayGraphics() {}
}
液晶顯示器類LCDMonitor是Monitor的子類:
package a.b;
public class LCDMonitor extends Monitor {
public void displayText() {
System.out.println("LCD display text");
}
public void displayGraphics() {
System.out.println("LCD display graphics");
}
}
陰極射線管顯示器類CRTMonitor自然也是Monitor的子類:
package a.b;
public class CRTMonitor extends Monitor {
public void displayText() {
System.out.println("CRT display text");
}
public void displayGraphics() {
System.out.println("CRT display graphics");
}
}
等離子顯示器PlasmaMonitor也是Monitor的子類:
package a.b;
public class PlasmaMonitor extends Monitor {
public void displayText() {
System.out.println("Plasma display text");
}
public void displayGraphics() {
System.out.println("Plasma display graphics");
}
}
現在有一個MyMonitor類。假設沒有向上轉型,MyMonitor類代碼如下:
package a.b;
public class MyMonitor {
public static void main(String[] args) {
run(new LCDMonitor());
run(new CRTMonitor());
run(new PlasmaMonitor());
}
public static void run(LCDMonitor monitor) {
monitor.displayText();
monitor.displayGraphics();
}
public static void run(CRTMonitor monitor) {
monitor.displayText();
monitor.displayGraphics();
}
public static void run(PlasmaMonitor monitor) {
monitor.displayText();
monitor.displayGraphics();
}
}
可能你已經意識到上述代碼有很多重複代碼,而且也不易維護。有了向上轉型,代碼可以更爲簡潔:
package a.b;
public class MyMonitor {
public static void main(String[] args) {
run(new LCDMonitor()); //向上轉型
run(new CRTMonitor()); //向上轉型
run(new PlasmaMonitor()); //向上轉型
}
public static void run(Monitor monitor) { //父類實例作爲參數
monitor.displayText();
monitor.displayGraphics();
}
}
我們也可以採用接口的方式,例如:
package a.b;
public interface Monitor {
abstract void displayText();
abstract void displayGraphics();
}
將液晶顯示器類LCDMonitor稍作修改:
package a.b;
public class LCDMonitor implements Monitor {
public void displayText() {
System.out.println("LCD display text");
}
public void displayGraphics() {
System.out.println("LCD display graphics");
}
}
CRTMonitor、PlasmaMonitor類的修改方法與LCDMonitor類似,而MyMonitor可以不不作任何修改。
可以看出,向上轉型體現了類的多態性,增強了程序的簡潔性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章