1.向上轉型
package test;
//祖父類
class grandfather {
public void print() {
System.out.println("我是祖父!!!");
}
}
//父親類
class father1 extends grandfather {
public void print() {
System.out.println("我是父親的大兒子!!!");
}
}
class father2 extends grandfather {
public void print() {
System.out.println("我是父親的小兒子!!!");
}
}
public class 多態 {
public static void main(String[] args) {
fun(new father1());
fun(new father2());
}
public static void fun(father1 f) {
f.print();
}
public static void fun(father2 f) {
f.print();
}
}
我們觀察到如果祖父有很多兒子的話,就要為每個兒子寫fun()方法,也會產生很多的重復代碼。
package test; //祖父類 class grandfather { public void print() { System.out.println("我是祖父!!!"); } } //父親類 class father1 extends grandfather { public void print() { System.out.println("我是父親的大兒子!!!"); } } class father2 extends grandfather { public void print() { System.out.println("我是父親的小兒子!!!"); } } public class 多態 { public static void main(String[] args) { grandfather g1 = new father1(); grandfather g2 = new father2(); fun(g1); fun(g2); } public static void fun(grandfather g) { g.print(); } }
這個時候將子類向上轉型,將存有祖父的棧內存指向子類的堆內存
2.向下轉型
一般的在向下轉型前都會向上轉型
向下轉型一般是為了重新獲得因為向上轉型而丟失的子類特性
新建一個電子產品接口
public interface Electronics { //存放電子設備國家標准 }
新建電腦類
public class computer implements Electronics { //電腦開機引導方法 public void boot(){ System.out.println("歡迎!正在開機中..."); } //使用電腦聽歌 public void music(){ System.out.println("正在播放音樂"); } }
新建鼠標類
public class mouse implements Electronics { //鼠標移動 public void move(){ System.out.println("移動鼠標"); } //鼠標點擊 public void onClick(){ System.out.println("點擊鼠標"); } }
新建鍵盤類
public class keyboard implements Electronics{ //使用鍵盤輸入 public void input(){ System.out.println("正在輸入!"); } }
新建購物車類
public class ShopCar { //存放電子產品的集合 private List<Electronics> mlist = new ArrayList<Electronics>(); //存放產品的動作 public void add(Electronics electronics){ mlist.add(electronics); } //獲得購物車的數目 public int getSize(){ return mlist.size(); } //取得購物車里的產品 public Electronics getListItem(int position){ return mlist.get(position); } }
在購物車代碼里面
ShopCar shopcar = new ShopCar();
shopcar.add(new computer());
shopcar.add(new mouse());
shopcar.add(new keyboard());
這里是接受一個電子產品的對象
新建測試類
public class Test { public static void main(String[] args){ //添加進購物車 ShopCar shopcar = new ShopCar(); shopcar.add(new computer()); shopcar.add(new mouse()); shopcar.add(new keyboard()); //獲取大小 System.out.println("購物車存放的電子產品數量為 ——> "+shopcar.getSize()); //開始測試thinkpad電腦 computer thinkpad = (computer)shopcar.getListItem(0); thinkpad.boot(); thinkpad.music(); System.out.println("-------------------"); //開始測試Mouse鼠標 mouse mouse = (mouse)shopcar.getListItem(1); mouse.move(); mouse.onClick(); System.out.println("-------------------"); //開始測試Keyboard鍵盤 keyboard k = (keyboard)shopcar.getListItem(2); k.input(); } }
在測試類代碼里面有
//添加進購物車 ShopCar shopcar = new ShopCar(); shopcar.add(new computer()); shopcar.add(new mouse()); shopcar.add(new keyboard());
使用了向上轉型把父類的名稱指向子類的堆內存里面
相當於
Electronics electronics=new computer(); Electronics electronics=new mouse(); Electronics electronics=new keyboard();
同樣的在測試類代碼里面有
//開始測試thinkpad電腦 computer thinkpad = (computer)shopcar.getListItem(0); thinkpad.boot(); thinkpad.music(); System.out.println("-------------------"); //開始測試Mouse鼠標 mouse mouse = (mouse)shopcar.getListItem(1); mouse.move(); mouse.onClick(); System.out.println("-------------------"); //開始測試Keyboard鍵盤 keyboard k = (keyboard)shopcar.getListItem(2); k.input();
這里用到了向下轉型來得到子類自己的行為屬性,子類實例已經賦值給了父類引用(即完成了向上轉型),但很遺憾的丟失了子類擴展的方法,很好的是Java語言有個向下轉型的特性,讓我們可以重新獲得丟失的方法,即強轉回子類 。
所以我們需要用到子類實例的時候,就從那個父類集合里拿出來向下轉型就可以了,一樣可以使用子類實例對象。