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

总结

多态简单来说就是父类引用指向子类对象,可以提高代码的灵活性和可扩展性。

猜你喜欢

转载自blog.csdn.net/hpuxiaofang/article/details/81225159