1.概念
(1)多态:父类型的引用指向子类的对象。
父类类名 引用名 = new 子类类名(实参);
引用对象
父类型 子类型的
主观类型 客观实际类型
(2)以父类型的引用调用属性和方法,只能调用父类中定义的属性和方法;
注意:编译时编译器会检测以父类调用的属性和方法是否在父类中定义,定义,则编译通过,没有定义,则编译报错。
(3)运行的时候,JVM会自动检测,子类中是否覆盖父类中的方法,如果子类覆盖了父类中的方法,则优先调用子类覆盖的方法,没有覆盖,则运行父类中的方法。
2.引用之间的转换
(1)父类型的引用 赋值给 子类型的引用–》强制类型转换大类型 小类型
a.语法:子类型名 引用名 = (子类类名)父类型引用;强转过程,引用中存储的实际对象类型不会随着转换而改变。
b.案例:
Animal a = new Dog();
Dog d = (Dog)a;
c.强制转换的结果:
1.如果引用中存储的实际对象类型和要转换的类型一致,编译通过,运行也通过。
Animal a = new Dog();//new后面就实际存储对象类型--》Dog
Dog d = (Dog)a //()代表要转换的类型--》Dog
2.如果实际存储的对象类型,和要转换的类型不一致,则编译通过,但是运行报错,错误信息:
java.lang.ClassCastException(类型转换异常)
Animal a = new Cat();//Animal a = new Cat();//实际存储对象类型为:Cat
Dog d = (Dog)a;//要转换的类型为--》Dog
(2)子类型的引用 赋值给父类型的引用–》直接赋值(体现多态)小类型赋值给大类型
a.语法:父类型名 引用名 = 子类型的引用名;
(3)没有继承的关系引用,之间是不允许转换,强制类型转换也不可以;一旦转换,编译报错。
Animal a = new Dog();
Person p = (person)a;//编译报错
3.instanceof的应用
(1)语法:引用名instanceof类名
(2)作用:将引用中存储的实际对象类型和instanceof后面的类型进行判断,如果实际存储的对象类型兼容于后面的类型,结果为true;若干不是后面的一种,则结果为false。
(3)开发中的应用:在进行引用类型转换之前,可以先通过instanceof进行判断,可以避免出现java.lang.ClassCastException(类型转换异常)。
public class TestAnimal2{
public static void main(String[] args){
Animal a = new Dog();
// System.out.println(a instanceof Animal);//true
// System.out.println(a instanceof Cat);// true
// System.out.println(a instanceof Dog);// false
if(a instanceof Dog){
Dog d = (Dog)a;
System.out.println("转换成功....");
}
}
}
4.多态的开发应用
(1)多态用在数组上:本类型+所以子类型的对象都可以作为元素进行存储
public class TestAnimal3{
public static void main(String[] args){
Animal[] as = new Animal[5];
as[0] = new Fish();
as[1] = new Cat();
as[2] = new Dog();
as[3] = new Fish();
as[4] = new Dog();
for(int i =0;i<as.length;i++){
as[i].eat();
//as[i].run();
}
// 统计 狗对象的个数
// 遍历数组:获取数组中每一个对象
int count = 0;
for(int i=0;i<as.length;i++){
// as[i]
if(as[i] instanceof Dog){
count++;
}
}
System.out.println("狗对象的个 数:"+count);
// 调用数组中 所有鱼对象的 swim方法(Fish独有 方法)
for(int i=0;i<as.length;i++){
if(as[i] instanceof Fish){
/*Fish f = (Fish)as[i]; f.swim();*/
((Fish)as[i]).swim();
}
}
}
}
(2)多态应用在形式参数上:本类型+所有子类型的对象(或是引用)都可以作为实际参数传递。
public class TestPerson2{
public static void main(String[] args){
//饲养员对象
person p = new person();
//狗对象
Dog d = new Dog();
//p.feedDog(d);
Cat c = new Cat();// 猫对象
//p.feedCat(c);
p.feedAnimal(d);// Animal a = d = new Dog();
p.feedAnimal(c); // Animal a = c = new Cat();
p.feedAnimal(new Tiger()); // Animal a = new Tiger();
}
}
// 饲养员
class Person{
/*public void feedDog(Dog d){ // d = new Dog();
d.eat();
}
public void feedCat(Cat c){
c.eat();
}*/
public void feedAnimal(Animal a){
a.eat();
}
}
class Animal{
public void eat(){
System.out.println("Animal..eat..");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗吃骨头...");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
}
class Tiger extends Animal{
public void eat(){
System.out.println("老虎吃肉...");
}
}
(3) 多态应用在返回值上:本类型+所有子类对象(或是引用)
都可以作为返回值进行返回。
- 多态的好处:
将不同子类进行统一管理和操作。