Java中多态的理解
本文主要介绍Java中多态的一些特性和格式,后面附上一个实例和自己的理解。
多态
什么是多态
概念:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性。(可以理解为对象的多种特性)
多态存在的三个必要条件
1.要有继承关系的存在(实现接口也是一种继承关系)
2.要有方法的重写
3.要有父类引用指向子类对象
向上转型和向下转型
1.对象的向上转型,其实就是多态写法:
格式: 父类名称 对象名 = new 子类名称();
含义:右侧创建了一个子类对象,把它当作父类来看待使用。
Animal animal=new Cat();
创建了一直猫对象,当作动物看待,没有问题。
注意事项:向上转型一定是安全的。从小范围转向了大范围,从小范围的猫,向上转换成为更大范围的动物
2.对象的向下转型,其实就是一个还原的动作:
格式: 子类名称 对象名 =(子类名称) 父类对象;
含义:将子类还原,还原成为本来的子类对象
Cat cat =(Cat) animal;//本来是猫,向上转型成为动物,还原回来成为本来的猫
注意事项:
a. 必须保证对象本来创建的时候就是猫,才能向下转型成为猫
b.如果对象创建的时候不是猫,现在非要向下转型成为猫,就会报错
instanceof关键字
java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
用法:
result = object instanceof class
参数:
Result:布尔类型。
Object:必选项。任意对象表达式。
Class:必选项。任意已定义的对象类。
说明:
如果 object 是 class 的一个实例,则 instanceof 运算符返回 true。如果 object 不是指定类的一个实例,或者 object 是 null,则返回 false。
但是instanceof在Java的编译状态和运行状态是有区别的:
在编译状态中,class可以是object对象的父类,自身类,子类。在这三种情况下Java编译时不会报错。
在运行转态中,class可以是object对象的父类,自身类,不能是子类。在前两种情况下result的结果为true,最后一种为false。但是class为子类时编译不会报错。运行结果为false。
实例应用
题目
/*
分析以下需求,并用代码实现
1.定义动物类:
属性:
年龄
行为:
喝水,吃东西(吃什么不确定)
2.定义游泳接口:
行为:
游泳方法
3.定义狗类:
行为:
吃饭(啃骨头)和 游泳(狗刨)
4.定义羊类:
行为:
吃饭(羊啃草)
5.定义青蛙类:
行为:
吃饭(吃虫子)和 游泳(蛙泳)
6.定义饲养员类:
行为:
饲养动物:包括吃饭和喝水
7.定义测试类:
创建饲养员对象,饲养员调用三次饲养方法:饲养狗,饲养羊,饲养青蛙
要求:
1.子类重写父类中的吃东西方法
2.要求给狗和青蛙添加游泳的方法(实现游泳接口)
3.饲养员类中定义一个方法,传入动物类对象(父类),
调用吃饭方法,如果有游泳方法也需进行测试
4.打印如下格式的结果:
喝水
狗啃骨头
狗会狗刨游泳
喝水
青蛙吃小虫
青蛙会蛙泳
喝水
羊啃草
*/
动物类
package com.heima.demo1.Work2;
/*
1.定义动物类:
属性:
年龄
行为:
喝水,吃东西(吃什么不确定)
*/
public abstract class Animal {
private int age;
public void drink(){
System.out.println("喝水");
}
public abstract void eat();
}
游泳接口
package com.heima.demo1.Work2;
/*
2.定义游泳接口:
行为:
游泳方法
*/
public interface Swimming {
public abstract void swim();
}
定义狗类
package com.heima.demo1.Work2;
/*
3.定义狗类:
行为:
吃饭(啃骨头)和 游泳(狗刨)
*/
public class Dog extends Animal implements Swimming{
//继承Animal类,重写eat()方法,实现游泳接口,重写swim()方法
public void eat(){
System.out.println("狗啃骨头");
}
public void swim(){
System.out.println("狗会狗刨游泳");
}
}
定义羊类
package com.heima.demo1.Work2;
/*
4.定义羊类:
行为:
吃饭(羊啃草)
*/
public class Sheep extends Animal{
//羊不会游泳,只需要继承Animal类,重写eat()方法
public void eat(){
System.out.println("羊吃草");
}
}
定义青蛙类
package com.heima.demo1.Work2;
/*
5.定义青蛙类:
行为:
吃饭(吃虫子)和 游泳(蛙泳)
*/
public class Frog extends Animal implements Swimming{
//继承Animal类,重写eat()方法,实现游泳接口,重写swim()方法
public void eat(){
System.out.println("青蛙吃小虫");
}
public void swim(){
System.out.println("青蛙会蛙泳");
}
}
饲养员类
package com.heima.demo1.Work2;
/*
6.定义饲养员类:
行为:
饲养动物:包括吃饭和喝水
*/
public class Breeder {
public void breed(Animal animal){
//定义一个方法,接受一个Animal对象
//使用instanceof关键字判断对象是否是这个特定类或者是它的子类的一个实例。
if(animal instanceof Dog){
animal.drink();
animal.eat();
((Dog) animal).swim();
}
if(animal instanceof Frog){
animal.drink();
animal.eat();
((Frog) animal).swim();
}
if(animal instanceof Sheep){
animal.drink();
animal.eat();
}
}
}
测试类
package com.heima.demo1.Work2;
//测试类
public class Test02 {
public static void main(String[] args) {
Breeder b=new Breeder();
//传入动物对象,调用饲养方法
b.breed(new Dog());
System.out.println();
b.breed(new Frog());
System.out.println();
b.breed(new Sheep());
}
}
测试结果
喝水
狗啃骨头
狗会狗刨游泳
喝水
青蛙吃小虫
青蛙会蛙泳
喝水
羊吃草
Process finished with exit code 0
总结
多态简单来说就是父类引用指向子类对象,可以提高代码的灵活性和可扩展性。