12Java基础之多态
多态
-
多态是在继承/实现情况下的一种现象,表现为:对象多态、行为多态。
-
多态存在的条件
- 有继承关系
- 子类重写父类的方法
- 父类引用指向子类对象
多态的一个注意事项
- 多态是对象、行为的多态,Java中的属性(成员变量)不谈多态。
案例:
父类:
public class Animal {
public String name ="动物名称";
public void cry(){
System.out.println("动物会叫");
}
}
子类:
public class Cat extends Animal{
public String name = "猫的名称";
@Override
public void cry(){
System.out.println("喵喵叫");
}
}
public class Dog extends Animal{
public String name = "狗的名称";
@Override
public void cry(){
System.out.println("汪汪叫");
}
}
main方法:
public static void main(String[] args) {
// 对象多态
Animal c = new Cat();
Animal d = new Dog();
c.cry();// 编译看左边,运行看右边
d.cry();
System.out.println(c.name);// 成员变量:编译看左,运行也看左。
System.out.println(d.name);
}
输出结果:
喵喵叫
汪汪叫
动物名称
动物名称
使用多态的好处
- 在多态形式下,右边对象时解耦合的,更便于拓展和维护。
- 定义方法时,使用父类类型的形参,可以接收一切子类对象,拓展性更强、更便利。
案例:
父类:
public class Animal {
public void cry(){
System.out.println("动物会叫");
}
}
子类:
public class Cat extends Animal{
@Override
public void cry(){
System.out.println("喵喵叫");
}
}
public class Dog extends Animal{
@Override
public void cry(){
System.out.println("汪汪叫");
}
}
main方法:
public static void main(String[] args) {
// 1. 多态下右边对象时解耦合的。
// Animal a = new Cat();
Animal a = new Dog();
a.cry();
Cat c = new Cat();
go(c);
Dog d = new Dog();
go(d);
System.out.println("--------------------------------");
}
// 2.多态下,父类类型作为方法的形参,可以接收一切子类对象,方法更便利。
public static void go(Animal c){
System.out.println("开始。。。");
c.cry();// 对象回调
// 多态下存在的一个问题:不能调用子类独有的功能方法
// c.lookDoor(); // 报错
// c.catchMouse(); // 报错
System.out.println("结束。。。");
}
输出结果:
汪汪叫
开始。。。
喵喵叫
结束。。。
开始。。。
汪汪叫
结束。。。
- 多态下存在一个问题:不能调用子类独有的功能方法。
多态下类型转换问题
-
类型转换
- 自动类型转换:父类 变量名 = new 子类()。例如:People p = new Teacher();
- 强制类型转换:子类 变量名 = (子类)父类变量。例如:Teacher t = (Teacher)p;
-
强制类型转换的一个注意事项
- 存在继承/实现关系就可以在编译阶段进行强制类型转换,编译阶段不会报错。
- 运行时,如果发现对象的真实类型与强转后的类型不同,就会报类型转换异常(ClassCastException)的错误出来。
-
强制类型转换前,Java建议我们去做什么事情?
-
建议使用instanceof判断当前对象的真实类型:对象 instanceof 类型
案例:
父子类沿用上边的动物类和猫类、狗类
main方法:
public static void main(String[] args) {
// 1. 多态下右边对象时解耦合的。
Animal a = new Dog();
a.cry();
// 强制类型转换:可以解决多态下不能直接调用子类的方法的问题。
Dog d = (Dog)a;
d.lookDoor();
// 强制类型转换的注意事项:1.只要有继承或者实现关系的两个类就可以强制转换。
// 编译阶段不会报错(写代码),但是运行时可能出现强制类型转换异常。
// Cat c = (Cat) a;// 编译不报,运行时会报错
Cat c = new Cat();
go(c);
}
// 2.多态下,父类类型作为方法的形参,可以接收一切子类对象,方法更便利。
public static void go(Animal a){
System.out.println("开始。。。");
a.cry();// 对象回调
//因此,Java建议强制类型转换之前,先判断对象的真实类型,在进行强转。
if(a instanceof Dog){
Dog d1 = (Dog)a;
d1.lookDoor();
}
else if(a instanceof Cat){
Cat c1 = (Cat)a;
c1.catchMouse();
}
else{
System.out.println("不是狗,不能强转");
}
System.out.println("结束。。。");
}
输出结果:
汪汪叫
狗会看门
开始。。。
喵喵叫
猫会抓老鼠
结束。。。

浙公网安备 33010602011771号