向上转型:将子类转化成父类

向下转型:将父类转化成子类

 

例子:

先定义一个父类,再定义一个继承父类的子类:

/**
 * 父类
 */
class Father {
	String name = "爸爸";
	public void sleep() {//睡觉方法
		System.out.println(name + "睡觉");
	}
}
/**
 * 子类继承父类
 */
class Son extends Father {
	String name = "儿子";
	public void p() {//调皮方法
		System.out.println(name + "调皮");
	}
}

我们可以看到,父类中有sleep()方法,子类中有 p()方法,由于Son继承Father,因此Son也有sleep()方法,但Father没有p()。

向上转型:

public class UpAndDown {
	public static void main(String[] args) {
		// 向上转型:将父类引用指向子类对象
		Father f = new Son();
		f.sleep();//输出“爸爸睡觉”
      
        //如果f.p();编译出错,不可执行。因为p()不是Father的方法。
	}
}

从上面代码可以看到,把子类Son转成Father后,f仍然是能调用 sleep()的,这很好理解,因为sleep是Father和Son共有的,但f是不能调用p的,因为p不属于Father类。所以向上转型,就相当于“瘦身”,例如把Son类中不属于Father类的方法屏蔽,只保留Father的方法。

向上转型后再向下转型:

public class UpAndDown {
	public static void main(String[] args) {
		// 向下转型
		Father f = new Son();
		((Son)f).P();//输出“儿子调皮”
	}
}

我们可以看到上面代码:实现了把Son向上转型为Father 后,再将其向下转型成Son。这个时候 f 是可以调用p()的。因为在向上转型过程中,并非把Son中不属于Father的方法完全去除掉,只是暂时“屏蔽”,所以当向下转型回Son时,自然就可以调用因为向上转型被屏蔽的方法了。

但是! 如果直接向下转型的话,是不能调用子类的方法的。下面给出例子。

向下转型

public class UpAndDown {
	public static void main(String[] args) {
		// 直接向下转型
		Father f = new Father();
        f.sleep();//输出“爸爸睡觉”
		((Son)f).P();//报错!!!!!!!!!!
	}
}

我们可以看到,直接把Father类对象f向下转型的话,可以看到,是不能调用子类专属的p()方法的。想想也很简单嘛,父类Father本来拥有的方法就比Son子类的少,当然不能调用子类的专属方法啦。

这种现象我们可以通俗地理解:

  • 向上转型可以当做隐藏自身的方法,所以,再转回来(向下转型)方法就会恢复原状。该是你的还是你的。
  • 直接向下转型,父类不具有子类的独有方法,所以即使转化成功,也是个残废儿子,还不如不转,所以直接报错转化失败。不是你的你想都别想。

其实吧,事情是这样的:

内存中,因为向上转型是父类的引用指向为子类的对象,所以,它只是指向了父类应该拥有的属性和方法,而子类的独有的方法和属性就不指向了(或者说隐藏了),当再强转到子类时。又重新指向了子类对象,那属于它的东西又恢复了。

 

有什么用?

Springboot 父类和子类转化 java父类转子类 方法_父类

代码如下:

class Person{
    public void dance(){
        System.out.println("person dance");
    }
}

class Man extends Person{
    @Override
    public void dance() {
        //super.dance();
        System.out.println("man dance");
    }
}

class Woman extends Person{
    @Override
    public void dance() {
        //super.dance();
        System.out.println("woman dance");
    }
}

public class HelloWorld{
    public static void main(String[]args){
            Person p = new Man();
            p.dance(); //man dance
            Person p2 = new Woman();
            p2.dance(); //woman dance
        }
}

向上转型好处就是可以用一个父类p来表示所有p的子类。 以上面为例,一开始可能不知道是Man跳舞还是Woman跳舞,所以先用Person引用,后面无论要调用Man还是Woman,都可以用Person p来表示。