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