13_Java中的多态

Java中的多态

一、多态的概述

1、同一个对象,在不同时刻表现出来的不同形态

2、多态的前提和体现

有继承/实现关系

有方法重写

有父类引用指向子类对象

3、代码示例:

package com.itheima_01;
/*
动物类
 */
public class Animal {

    public void eat(){
        System.out.println("动物吃东西");
    }
}
package com.itheima_01;
/*
猫类
 */
public class Cat extends Animal{    //此处完成继承关系
    @Override
    public void eat(){      //此处实现方法重写
        System.out.println("猫吃老鼠");
    }
}
package com.itheima_01;
/*
测试类, 用于测试多态前提
 */
public class AnimalDemo {
    public static void main(String[] args){
        //父类引用指向子类对象
        Animal animal = new Cat();
        //可以看到此时 调用eat方法实现的是猫吃老鼠
        animal.eat();
    }
}

二、多态中成员访问特点

成员变量:编译看左边,执行看左边

成员函数:编译看左边,执行看右边

为什么成员变量与成员方法的访问不一样呢?

因为成员方法有重写,而成员变量没有

参考代码:

package com.itheima_02;
/*
动物类
 */
public class Animal {

    public int age = 40;

    public void eat(){
        System.out.println("动物吃东西");
    }

}
package com.itheima_02;
/*
猫类
 */
public class Cat extends Animal{
    public int age = 20;
    public int weight = 10;

    @Override
    public void eat(){
        System.out.println("猫吃老鼠");
    }

    public void playGame(){
        System.out.println("猫捉迷藏");
    }
}
package com.itheima_02;
/*
测试类
 */
public class AnimalDemo {
    public static void main(String[] args){
        //有父类引用指向子类对象
        Animal a = new Cat();

        //在多态中 针对于属性而言 编译与运行都是以 左边(此处是父类引用)为准
        System.out.println(a.age);
//        System.out.println(a.weigth);

        //在多态中 针对于方法而言 编译以左边为准 运行则是看右边
        a.eat();
//        a.playGame();
    }
}

三、多态的好处和弊端

1、多态的好处:

提高了程序的拓展性,具体体现:定义方法的时候,使用父类作为参数,将来使用的时候,传入具体的子类类型参与操作

2、多态的弊端:

不能使用子类的特有功能(理解:多态是通过父类引用进行方法的调用,但是子类中的特有方法无法通过父类引用进行调用)

3、参考代码:

package com.itheima_03;
/*
动物操作类
 */
public class AnimalOperator {
    /*public void useAnimal(Cat c){   //Cat c = new Cat();
        c.eat();
    }

    public void useAnimal(Dog d){   //Dog d = new Dog();
        d.eat();
    }*/

    //利用多态思想 传入我所需要的对应的子类对象
    public void useAnimal(Animal a){
        a.eat();

//        a.lookDoor(); 不能利用父类引用访问子类特有的功能
    }
}
package com.itheima_03;

public class Cat extends Animal{
    @Override
    public void eat(){
        System.out.println("猫吃老鼠");
    }
}
package com.itheima_03;

public class Dog extends Animal{
    @Override
    public void eat(){
        System.out.println("狗吃骨头");
    }

    public void lookDoor(){
        System.out.println("狗看门");
    }
}
package com.itheima_03;

public class Pig extends Animal{
    @Override
    public void eat(){
        System.out.println("猪吃饲料");
    }
}
package com.itheima_03;
/*
动物操作类
 */
public class AnimalOperator {
    /*public void useAnimal(Cat c){   //Cat c = new Cat();
        c.eat();
    }

    public void useAnimal(Dog d){   //Dog d = new Dog();
        d.eat();
    }*/

    //利用多态思想 传入我所需要的对应的子类对象
    public void useAnimal(Animal a){
        a.eat();

//        a.lookDoor(); 不能利用父类引用访问子类特有的功能
    }
}
package com.itheima_03;

public class AnimalDemo {
    public static void main(String[] args) {
        //创建动物操作类的对象,调用方法
        AnimalOperator ao = new AnimalOperator();
        /*Cat c = new Cat();
        ao.useAnimal(c);

        Dog d = new Dog();
        ao.useAnimal(d);*/

        //可以看到:每添加一个类,就要到动物操作类中去添加新的方法(也可以使用上面注释的方法传参)
        Animal a = new Cat();
        ao.useAnimal(a);

        a = new Dog();
        ao.useAnimal(a);

        a = new Pig();
        ao.useAnimal(a);
    }
}

四、多态中的转型

1、向上转型:

​ 从子到父,父类引用指向子类对象(就是多态条件操作)

2、向下转型:

​ 从父到子,父类引用转换为子类对象

例如:Animal a = new Cat(); Cat c = (Cat)a; 注意a,c中存放的引用类型相同才可进行 这里都是Cat类在堆区的地址值

3、代码示例:

package com.itheima_04;

public class Animal {
    public void eat(){
        System.out.println("动物吃东西");
    }
}
package com.itheima_04;

public class Cat extends Animal{
    @Override
    public void eat(){
        System.out.println("猫吃老鼠");
    }

    public void playGame(){
        System.out.println("猫捉迷藏");
    }
}
package com.itheima_04;
/*
     向上转型
        从子到父
        父类引用指向子类对象
     向下转型
        从父到子
        父类引用转为子类对象
 */
public class AnimalDemo {
    public static void main(String[] args) {
        //多态
        Animal a = new Cat();   //向上转型
        a.eat();

//        a.playGame(); //报错编译看左边

       /* //创建Cat对象
        Cat c = new Cat();
        c.eat();
        c.playGame();*/

        //向下转型
        Cat c = (Cat)a; //强制转换 a中存的也是Cat的堆区地址值才行,如果此时不是就会报错
        c.playGame();
    }
}

五、多态案例

1、案例一猫和狗:

package com.itheima_05;
/*
动物类
 */
public class Animal {
    //成员属性
    private String name;
    private int age;

    //构造方法
    public Animal(){

    }

    public Animal(String name, int age){
        this.name = name;
        this.age = age;
    }

    //set/get/show方法
    public void setName(String name){
        this.name = name;
    }

    public String getName(){
        return this.name;
    }

    public void setAge(int age){
        this.age = age;
    }

    public int getAge(){
        return this.age;
    }

    public void show(){
        System.out.println(getName() + "," + getAge());
    }

    //定义一个吃东西的方法
    public void eat(){
        System.out.println("动物在吃东西");
    }
}
package com.itheima_05;
/*
猫类
 */
public class Cat extends Animal{
    //构造方法
    public Cat() {
    }

    public Cat(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat(){
        System.out.println("猫吃老鼠");
    }
}
package com.itheima_05;
/*
狗类
 */
public class Dog extends Animal{
    //构造方法
    public Dog() {
    }

    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat(){
        System.out.println("狗吃骨头");
    }
}
package com.itheima_05;
/*
测试类
 */
public class AnimalDemo {
    public static void main(String[] args){
        //实现猫类的调用
        Animal a = new Cat();
        /*
        此处如果我们创建子类对象也只会到父类中去找属性和方法,我们并没有在子类中写
        所以直接利用父类引用来调用方法、来实现初始化
        当我们是使用子类引用来调用时,就需要参考继承中的调用规则中
         */
        //Cat c = (Cat)a;   一般又用于调用子类中特有的方法此处没有
        a.setName("加菲猫");
        a.setAge(8);
        a.show();
        a.eat();

        Animal a2 = new Cat("Tom", 6);
        a2.show();
        a2.eat();

        //实现狗类的调用
        Animal a3 = new Dog();
        a3.setName("旺财");
        a3.setAge(7);
        a3.show();
        a3.eat();

        Animal a4 = new Dog("来福", 5);
        a4.show();
        a4.eat();
    }
}
posted @ 2022-10-03 23:10  如此而已~~~  阅读(25)  评论(0编辑  收藏  举报