Java多态性(向上转型和向下转型)

*向上转型:*子类对象转为父类,父类可以是接口。公式:Father f=new Son();Father是父类或接口,son是子类。
*向下转型:*父类对象转为子类。公式:Son s=(Son)f;

package demo2;

public class Human {
	public void sleep(){
		System.out.println("Human sleep..");
	}
	public static void main(String[] args) {
		Human human=new Male();//向上转型
		human.sleep();
		Male male=new Male();
		male.sleep();
//		human.speak();此方法不能编译。报错human没有此方法
	}
}
class Male extends Human{
	@Override
	public void sleep() {
		// TODO Auto-generated method stub
		System.out.println("Male sleep..");
	}
	public void speak(){
		System.out.println("I am Male");
	}
}

class Female extends Human{
	@Override
	public void sleep() {
		// TODO Auto-generated method stub
		System.out.println("Female sleep..");
	}
	public void speak(){
		System.out.println("I am Female");
	}
}

注意:向上转型不能强制转型。向上转型后父类的引用所指向的属性是父类的属性。如果子类重写了父类的方法,那么父类引用指向的或者调用的方法是子类的方法,这个叫做动态绑定。向上转型后父类引用不能调用子类自己的方法,就是父类没有但是子类有的方法。如果一定需要调用子类的属性呢?如果不适用向下转型就需要给需要的属性写getter方法。
例如:

package demo2;

public class Human {
	String name="Human";
	public String getName(){
		return this.name;
	}
	public void sleep(){
		System.out.println("Human sleep..");
	}
	public static void main(String[] args) {
		Human human=new Male();//向上转型
		System.out.println(human.getName());//Male
		System.out.println(human.name);//Human
	}
}
class Male extends Human{
	String name="Male";
	public String getName(){
		return this.name;
	}
	@Override
	public void sleep() {
		// TODO Auto-generated method stub
		System.out.println("Male sleep..");
	}
	public void speak(){
		System.out.println("I am Male");
	}
}

class Female extends Human{
	String name="Female";
	public String getName() {
		return this.name;
	}
	@Override
	public void sleep() {
		// TODO Auto-generated method stub
		System.out.println("Female sleep..");
	}
	public void speak(){
		System.out.println("I am Female");
	}
}

如果一定要使用子类扩展的方法,比如speak方法,就只能向下转型了。
向下转型需要考虑安全性,如果父类引用的对象是父类本身,那么在向下转型的过程中是不安全的,变异不会出错,但是运行时会出现java.lang.ClassCastException错误。它可以使用instanceof来避免出现此类错误既能否向下转型,只有先经过向上转型的对象才能继续向下转型。【instanceof是Java、php的一个二元操作符(运算符),和==,>,<是一类东西。作用是判断其左边对象是否为其右边类的实例,返回boolean类型的数据】
例子:

package demo2;

public class Human {

	public void sleep(){
		System.out.println("Human sleep..");
	}
	public static void main(String[] args) {
		Human human=new Male();//向上转型
		Human human2=new Human();
		Male male=(Male)human;
		male.speak();
//		Male male2=(Male)human2;
//		male2.speak();
		//出现java.lang.ClassCastException
		if (human2 instanceof Male) {
			Male male2=(Male)human2;
			male2.speak();
		}
	}
}
class Male extends Human{

	@Override
	public void sleep() {
		// TODO Auto-generated method stub
		System.out.println("Male sleep..");
	}
	public void speak(){
		System.out.println("I am Male");
	}
}

为什么不直接Son s=new Son();?? 原因是例子太简单,没有考虑过要把类的对象传递给其他函数的例子
例子:体现向上转型的好处,节省代码(多态性)

package demo2;

public class Human {

	public void sleep(){
		System.out.println("Human sleep..");
	}
	public static void doSleep(Human human) {
		human.sleep();
	}
	public static void main(String[] args) {
		doSleep(new Male());
		doSleep(new Female());
	}
}
class Male extends Human{

	@Override
	public void sleep() {
		// TODO Auto-generated method stub
		System.out.println("Male sleep..");
	}
}
class Female extends Human{
	@Override
	public void sleep() {
		// TODO Auto-generated method stub
		System.out.println("Female sleep..");
	}
}

假如不向上转型就必须写两个doSleep函数,一个传递Male类对象,一个传递Female类对象。一旦向上转型了,当需要用到子类的方法是,就需要向下转型。

总结
1.把子类直接赋值给父类引用叫做upcasting向上转型,向上转型不用强制转型。
2.把指向子类对象的父类引用赋值给子类引用叫做向下转型downcasting,需要强制类型转换,要向下转型,必须先向上转型,为了安全可以使用instanceof判断。
3.upcasting会丢失子类特有的方法,但是子类overriding父类的方法,子类方法邮箱,向上转型只能引用父类对象的属性,要引用子类对象的属性,则要写getter函数。
4.向上转型的作用,减少重复代码,父类为参数,调用是用子类作为参数,就是利用了向上转型。这样使代码变得简洁,体现了JAVA的抽象编程思想。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值