java-多态
生活中的多态是指“客观事物在人脑中的主观反映”。
主观意识上的类别与客观存在的对象具有“is a”关系时,即形成多态。
程序中的多态:
概念:父类引用指向子类对象,从而产生多态。
多态:子类对象可以赋值给父类引用
1)只能对引用调用其引用类型中声明的方法(父类没有的,子类有的不能调用)
2)运行时,根据引用类型里装的对象的实际类型,调用子类覆盖之后的方法
3)对象类型不变,强制类型转换,用于父类引用赋值给子类引用,无法改变其对象类型。
这种情况是错误的:(Dog是动物的子类)
运行结果:
代码例子1:
package day10; public class TestPolymorphism { public static void main(String[] args) { Animal a=new Dog(); //创建的类型能不能赋值给Animal类型的引用? 可以,强类型转换 // 多态:子类对象可以赋值给父类 } } class Animal{ public void eat() { System.out.println("Animal eat"); } public void sleep() { System.out.println("sleep 8 hours"); } } class Dog extends Animal{ public void sleep() { System.out.println("sleep 6 hours"); } } class Cat extends Animal{ }
运行截图:
代码例子2:
package day10; public class TestPolymorphism { public static void main(String[] args) { Animal a=new Dog(); a.sleep(); a.eat(); // a.shout();不能调用??? 为什么? 只知道它是动物,不知道是狗 //创建的类型能不能赋值给Animal类型的引用? 可以,强类型转换 // 多态:子类对象可以赋值给父类 /* * Dog d=(Dog)a; d.shout(); */ Animal b=new Cat(); b.eat(); b.sleep(); Dog c=(Dog)b; c.shout(); } } class Animal{ public void eat() { System.out.println("Animal eat"); } public void sleep() { System.out.println("sleep 8 hours"); } } class Dog extends Animal{ public void sleep() { System.out.println("sleep 6 hours"); } public void shout() { System.out.println("shout"); } } class Cat extends Animal{ }
出现错误原因:
强制转换不能强制将猫转换成狗。引用间的强转无法改变对象类型(仅仅只是让编译器不报错)。但是如果两者之间有继承关系的话,可以正确调用,但是不符合逻辑。
如下图修改:
package day10; public class TestPolymorphism { public static void main(String[] args) { Animal a = new Cat(); a.sleep(); a.eat(); // a.shout();不能调用??? 为什么? 只知道它是动物,不知道是狗 if (a instanceof Dog) { Dog d = (Dog) a; d.shout();//规避了类型转换异常 } Dog d = (Dog) a; d.shout(); } } class Animal { public void eat() { System.out.println("Animal eat"); } public void sleep() { System.out.println("sleep 8 hours"); } } class Dog extends Animal { public void sleep() { System.out.println("sleep 6 hours"); } public void shout() { System.out.println("shout"); } } class Cat extends Animal{ }
运行结果:
运行结果:
instanceof关键字:
引用 instanceof 类名 “判断引用中的对象 是不是 类名” 用作在强制类型转换之前进行类型判断,避免类型转换异常。
例子:
package day10;
public class TestPolymorphism { public static void main(String[] args) { Animal a = new Cat(); a.sleep(); a.eat(); // a.shout();不能调用??? 为什么? 只知道它是动物,不知道是狗 if (a instanceof Dog) { Dog d = (Dog) a; d.shout();//规避了类型转换异常 } Dog d = (Dog) a; d.shout();//不用instanceof的关键字的情况下,无法规避类型转换异常
} } class Animal { public void eat() { System.out.println("Animal eat"); } public void sleep() { System.out.println("sleep 8 hours"); } } class Dog extends Animal { public void sleep() { System.out.println("sleep 6 hours"); } public void shout() { System.out.println("shout"); } } class Cat extends Animal{ }
运行结果:
package day10;
public class TestPolymorphism {public static void main(String[] args) {Animal a=new Dog();a.sleep();a.eat();//a.shout();不能调用??? 为什么? 只知道它是动物,不知道是狗//创建的类型能不能赋值给Animal类型的引用? 可以,强类型转换//多态:子类对象可以赋值给父类 w/* * Dog d=(Dog)a; d.shout(); */Animal b=new Cat();b.eat();b.sleep();Dog c=(Dog)b;c.shout();
}}class Animal{public void eat() {System.out.println("Animal eat");}public void sleep() {System.out.println("sleep 8 hours");}}class Dog extends Animal{public void sleep() {System.out.println("sleep 6 hours");}public void shout() {System.out.println("shout");}}class Cat extends Animal{}