欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java中多态的理解

程序员文章站 2022-05-06 18:19:39
...

本文主要介绍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

总结

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