第三次学JAVA再学不好就吃翔(part35)--多态向上转型和向下转型

学习笔记,仅供参考



面向对象


多态


多态向上转型和向下转型

我们首先通过以下代码复习一下自动类型提升强制类型转换

class BunnyAnimal0602 {
	public static void main(String[] args) {
		int i = 10;
		byte b = 20;
		i = b;       //自动类型提升
		b = (byte)i; //强制类型转换
		
	}
}

由此,我们引出多态中的向上转型和向下转型:

class BunnyAnimal0602 {
	public static void main(String[] args) {
		Father f = new Son();
		f.method();
	}
}


class Father {
	int num = 10;

	public void print() {
		System.out.println("Print Father");
	}

}


class Son extends Father {
	int num = 20;

	public void print() {
		System.out.println("Print Son");
	}

	public static void method() {
		System.out.println("Method Son");
	}
}

报错信息:

---------- javac ----------
BunnyAnimal0602.java:4: 错误: 找不到符号
		f.method();
		 ^
  符号:   方法 method()
  位置: 类型为Father的变量 f
1 个错误

Output completed (2 sec consumed) - Normal Termination

父类引用指向子类对象就是向上转型。同时,我们看到在上述代码中,由于父类中没有method方法,所以编译时报错。

下面我们通过向下转型,去调用子类中的method方法:

class BunnyAnimal0602 {
	public static void main(String[] args) {
		Father f = new Son();
		System.out.println(f.num);
		Son s = (Son)f;
		s.method();
	}
}

class Father {
	int num = 10;

	public void print() {
		System.out.println("Print Father");
	}

}

class Son extends Father {
	int num = 20;

	public void print() {
		System.out.println("Print Son");
	}

	public static void method() {
		System.out.println("Method Son");
	}
}

输出:

10
Method Son

内存图:


多态的好处和弊端

  • 多态的好处
    • 提高代码的维护性
    • 提高代码的扩展性
  • 多态的弊端
    • 不能使用子类特有的属性和行为

  • 举个例子(多态的好处)
class AnimalBunnyCat {
	public static void main(String[] args) {
		method(new Bunny());
		method(new Cat());
		
	}
	public static void method(Animal a) {
		a.eat();
	}
}

class Animal {
	public void eat() {
		System.out.println("动物吃饭");
	}
}

class Bunny extends Animal {
	public void eat() {
		System.out.println("兔子吃胡萝卜");
	}
}

class Cat extends Animal {
	public void eat() {
		System.out.println("猫吃鱼");
	}
}

输出:

兔子吃胡萝卜
猫吃鱼

  • 举个例子(强转)

基于上面的代码,我们给method增加一些功能,如果输入参数是Cat的对象,则增加Cat特有的功能,如果输入参数是Bunny的对象,则增加Bunny特有的功能:

class AnimalBunnyCat {
	public static void main(String[] args) {
		method(new Bunny());
		method(new Cat());
		
	}
	public static void method(Animal a) {
		if (a instanceof Bunny) {
			Bunny b = (Bunny)a;
			b.eat();
			b.play();
		} else if (a instanceof Cat) {
			Cat c = (Cat)a;
			c.eat();
			c.sleep();
		} else {
			a.eat();
		}
	}
}

class Animal {
	public void eat() {
		System.out.println("动物吃饭");
	}
}

class Bunny extends Animal {
	public void eat() {
		System.out.println("兔子吃胡萝卜");
	}
	public void play() {
		System.out.println("兔子玩耳朵");
	}
}

class Cat extends Animal {
	public void eat() {
		System.out.println("猫吃鱼");
	}

	public void sleep() {
		System.out.println("猫睡觉");
	}
}

输出:

兔子吃胡萝卜
兔子玩耳朵
猫吃鱼
猫睡觉

关键字instanceof为判断前面的引用是否是后面的数据类型。如果没有经过instanceof判断,我们可能会把Cat强制转换为Bunny这样就会出现类型转换异常ClassCastException


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GUI Research Group

谢谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值