欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

向上转型和向下转型

程序员文章站 2024-03-21 19:07:58
...

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语言有个向下转型的特性,让我们可以重新获得丢失的方法,即强转回子类 。
       所以我们需要用到子类实例的时候,就从那个父类集合里拿出来向下转型就可以了,一样可以使用子类实例对象。

 

 

  

  

 

上一篇: 依然是BFS

下一篇: 子集生成