面向对象特征之三:多态性

什么是多态性?

我们可以理解为一个事务的多种形态

创建一个Person类

package JavaSe;

public class Person {
    public int id;
    public String name;
    public int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

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

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

  public void eat(){
        System.out.println("父类吃");
    }

}

创建一个Man类继承Person类

package JavaSe;

public class Man extends Person {
    public int sex;

    public int getSex() {
        return sex;
    }

    public void setSex(int sex) {
        this.sex = sex;
    }

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

    public void eat(){
        System.out.println("男人吃");
    }


    public void sleep(){
        System.out.println("男人睡");
    }
}

创建一个测试类PersonTest类

public class Persontest {

    public static void main(String[] args) {
        //对象的多态性,父类的引用指向子类的对象
        Person man = new Man(1,"leo",2);
        int age = man.getAge();
        man.eat();
        System.out.println(age);
    }
}
何为多态

对象的多态性,父类的引用指向子类的对象

Person man = new Man(1,"leo",2);

多态的使用:虚拟方法调用

有了对象的多态性以后,我们在编译期,只能调用父类种声明的方法,但在运行期,我们实际执行的是子类重写父类的方法

总结

编译看左边Person 运行看右边Man

多态性的使用前提:

  1. 类的继承

  1. 方法的重写

多态性的使用案例

package JavaSe;

import java.sql.Connection;

public class AnimalTest {
    public static void main(String[] args) {
        AnimalTest test = new AnimalTest();
        test.func(new dog());
        test.func(new cat());

    }


    public void func(Animal animal){
        animal.eat();
        animal.shout();
    }


    //如果没有多态性
//    public void func(dog dogs){
//        dogs.eat();
//        dogs.shout();
//    }
//
//
//    public void func(cat cats){
//        cats.eat();
//        cats.shout();
//    }
}


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

    public void shout(){
        System.out.println("动物:叫");
    }
}

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

    @Override
    public void shout() {
        System.out.println("汪,汪,汪,");
    }
}

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

    @Override
    public void shout() {
        System.out.println("喵喵喵");
    }
}



class Order{
    public void method(Object object){

    }
}

class Driver{
    public void daData(Connection connection){ //connection = new MySqlConnection()

    }

}

对象的多态性,只适用于方法,不适应于属性

虚拟方法调用:

正常方法调用

Person e = new Person();
e.getInfo()
Dog dog = new Dog();
dog.eat()

虚拟方法调用(多态情况下)

子类定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。

Person e = new Student();
e.getInfo();//调用Student类的getInfo方法

编译时类型和运行时类型

编译时e为Person类型,而方法调用是在运行时确定的,所以调用的是Student类的getInfo()方法-----动态绑定

从编译和运行的角度看:

重载:是指运行存在多个同名方法,而这些方法的参数不同。编译器根据方法不同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名的方法就成了不同的方法。它们的调用地址在编译期就绑定了。Java重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。

所以:对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定“或"静态绑定“

而对于多态,只有等到方法调用的那一刻,解释运行期才会确定所要调用的具体方法,这称为”晚绑定“或”动态绑定

面试题:

多态是编译时行为还时运行时行为?

如何证明?

代码实现:

package aaaaaa;

import java.util.Random;

class Animail{
    protected void eat(){
        System.out.println("animal eat food");
    }
}

class dog extends Animail{
    protected void eat(){
        System.out.println("dog eat food");
    }
}
class cat extends  Animail{
    protected void eat(){
        System.out.println("cat eat food");
    }
}
class pig extends Animail{
    protected void eat(){
        System.out.println("pig eat food");
    }
}

public class AnimalTests {

    public static Animail getInstance(int key){
        switch (key){
            case 0:
            return new cat();
            case 1:
            return new pig();
            default:
                return new dog();
        }
    }

    public static void main(String[] args) {
        int key = new Random().nextInt(3);
        System.out.println(key);
        Animail instance = getInstance(key);
        instance.eat();
    }
}

运行结果:

微信公众号:

一只Java程序猿

欢迎关注哦

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值