Java多态性

Java多态性

面向对象三大特征:封装性,继承性,多态性.

extends继承或者implements实现,是多态的前提

一个对象拥有多种形态这就是:对象的多态性

image-20230507100303689

多态的实现

代码中体现多态性:父类引用指向子类对象

格式

父类名称 对象名 = new 子类名称();

或者

接口名称 对象名 = new 实现类名称();

image-20230507101819419

代码示例

Fu类

public class Fu {
    public void method() {
        System.out.println("父类成员方法");
    }

    public void methodFu() {
        System.out.println("我是父类独有的成员方法");
    }
}


Zi类

public class Zi extends Fu {
    public void method()
    {
        System.out.println("子类成员方法");

    }
}

Main方法

public class Multi {
    public static void main(String[] args) {
        //使用多态的写法
        //左侧父类引用,指向了右侧的子类对象

        Fu one = new Zi();//
        one.method();//还是优先使用子类方法,new的谁将优先使用谁
        one.methodFu();//如果子类没有会向上寻找父类方法

    }
}

多态中成员变量的访问特点

访问成员变量的两种方式

  1. 直接通过对象名称访问成员变量,看等号左边是谁,优先用谁,没有,则向上找.
  2. 间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找.

image-20230507103007035

Fu类

public class Fu {
    int num=10;
  public void show()
  {
      System.out.println(num);
  }

}

public class Fu {
    int num=10;
  public void show()
  {
      System.out.println(num);
  }

}

Zi类

public class Zi extends Fu{
    int num =20;
    int age=20;
    public void show()
    {
        System.out.println(num);
    }
}

Main方法

public class Main {
    public static void main(String[] args) {
        Fu one = new Zi();//多态写法
        System.out.println(one.num);//父类 10;
//        System.out.println(one.age);子类当中才有age错误写法
        System.out.println("=========");
        //如果子类没有覆盖重写,就是父:10;
        //如果子类覆盖重写之后就是子:20;
        one.show();


    }
}

多态中成员方法的使用特点

在多态代码中,成员方法的访问规则是:

看new的是谁,就优先用谁,没有则向上找.

口角:编译看左边,运行看右边.

和成员变量的区别

成员变量:编译看左边,运行还看左边.

成员方法:编译看左边,运行看右边

image-20230507161455926

代码示例

父类

public class Fu {
    public void method()
    {
        System.out.println("父类方法");
    }
    public void methodFu()
    {
        System.out.println("父类独有方法");

    }
}

子类

public class Zi extends Fu{
    @Override
    public void method() {
        System.out.println("子类方法");
    }
    public void methodZi()
    {
        System.out.println("子类独有方法");
    }
}

main方法

public class Main {
    public static void main(String[] args) {
        Fu one = new Zi();
        one.method();//父子都有优先用子
        one.methodFu();//子类没有,父类有,优先用父类
//        one.methodZi();错误写法
        //编译看左边,Fu类没有该方法编译报错,不能这样写
    }
}

使用多态的好处

image-20230507163121004

无论右边new的时候换成哪个子类对象,等号左边调用方法都不会变化.

对象的向上转型

对象的向上转型,就是多态写法:

格式:父类名称 对象名 = new 子类名称();

含义:右侧创建一个对象,把它当作父类来看待使用

注意:向上转型一定是安全的,范围从大变小

image-20230508141623081

代码示例

父类

public abstract class Animal {
    public abstract void eat();
}

子类

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

Main方法

public class Main {
    public static void main(String[] args) {
        Animal one = new Cat();
        //对象向上转型,就是,父类对象引用指向子类对象
        one.eat();//运行看左,编译看右

    }
}

对象的向下转型

向上转型一定是安全的,没有问题的,正确的,但是也有一个弊端.

对象一旦向上转型为父类,那么就无法调用子类原本的内容.

解决方法,用对象的向下转型[还原]

对象的向下转型是一个[还原]的动作

格式:子类名称 对象名 =(子类名称) 父类对象

含义:将父类对象,[还原]成为本来的子类对象

注意:

必须保证对象创建的时候就是猫,才能向下转型成为猫.

image-20230508145347822

Animal类

public abstract class Animal {
    public abstract void eat();
}

Cat类

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

Dog类

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

Main类

public class Main {
    public static void main(String[] args) {
        Animal one = new Cat();
        //对象向上转型,就是,父类对象引用指向子类对象
        one.eat();//运行看左,编译看右
//        one.catch_mouse();//错误写法
        //向下转型,进行"还原动作"
        Cat two = (Cat)one;//像下转型,将动物转换为了猫
        two.catch_mouse();//可以使用Cat的成员变量
        two.eat();
        Dog three =(Dog) one;//编译正常运行出错,猫不能变成狗
    }
}

instanceof关键字

如何才能知道一个父类引用的对象本来是什么子类?

格式:

对象 instandof 类名称

这将会得到一个boolean值

image-20230510164616544

image-20230510164638045

代码示例

动物类

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

Dog类

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

Cat类

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

Main方法

public class Main {
    public static void main(String[] args) {
        Animal one = new Dog();
        if (one instanceof Cat)//使用instandof进行判断
        {
            Cat two = (Cat) one;//向下转型
            two.eat();
            two.catch_mouse();
        }
        if (one instanceof Dog)//使用instandof进行判断
        {
            Dog two = (Dog) one;
            two.eat();
            two.look();
        }
        gevMeAPat(new Cat());//传入一个人dog
    }

    public static void gevMeAPat(Animal three)//需要一个animal
    //下面进行判断
    {
        if (three instanceof Cat)//使用instandof进行判断
        {
            Cat two = (Cat) three;//向下转型
            two.eat();
            two.catch_mouse();
        }
        if (three instanceof Dog)//使用instandof进行判断
        {
            Dog two = (Dog) three;
            two.eat();
            two.look();
        }


    }
}

posted @ 2023-05-07 16:33  harper886  阅读(23)  评论(0编辑  收藏  举报