【Java】多态

概念

多态 是面向对象三大特征之一。

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

举例:狗

狗就是狗        狗 dog = new 狗();

我们也可以说 动物 animal = new 狗();

这里狗在不同的时刻表现出来的形态,这就是多态。

多态的前提和体现

  1. 有继承 / 实现关系
  2. 方法重写
  3. 有父类引用指向子类对象

示例代码:

AnimalParent.java

package com.面向对象.Demo22;

public class AnimalParent {
    // 父类
    public void eat(){
        System.out.println("这是动物类 都有eat 方法");
    }
}

Dog.java

package com.面向对象.Demo22;

public class Dog extends AnimalParent {
    // 子类
    /**
     * 多态的基本的条件
     * 1.有继承 或 实现(后面会学习到接口的概念)的关系
     * 2.方法的重写——子类重写父类的方法
     * 3.有父类的引用指向子类
     */
    @Override
    public void eat() {
        System.out.println("子类(狗类)重写了父类 eat 方法");
    }
}

AnimalDemo.java

package com.面向对象.Demo22;

public class AnimalDemo {
    public static void main(String[] args) {
        // 本身的类型指向引用 new 本身的对象
        Dog dog = new Dog();
        dog.eat();
        // 有父类的引用指向子类对象  多态
        AnimalParent animalParent = new Dog();
        animalParent.eat();
    }
}

运行结果:

【Java】多态_第1张图片


多态的访问特点

  • 成员变量:编译看左边,执行看左边;
  • 成员方法:编译看左边,执行看右边。

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

∵ 成员方法有重写,而成员变量是没有的。

示例代码:

AnimalParent.java

package com.面向对象.Demo22;

public class AnimalParent {
    public int age = 20;

    // 父类
    public void eat() {
        System.out.println("这是动物类 都有eat 方法");
    }
}

Dog.java

package com.面向对象.Demo22;

public class Dog extends AnimalParent {
    public int age = 10;
    public int weight = 20;
    // 子类

    /**
     * 多态的基本的条件
     * 1.有继承 或 实现(后面会学习到接口的概念)的关系
     * 2.方法的重写——子类重写父类的方法
     * 3.有父类的引用指向子类
     */
    @Override
    public void eat() {
        System.out.println("子类(狗类)重写了父类 eat 方法");
    }
    public void show(){}
}

AnimalDemo.java

package com.面向对象.Demo22;

public class AnimalDemo {
    /**
     * AnimalParent animalParent = new Dog();
     * 成员属性 编译阶段是看左边(父类animalParent)执行也是看左边(父类animalParent);
     * 成员方法 编译阶段是看左边(父类animalParent)执行是看右边(子类Dog);
     * @param args
     */
    public static void main(String[] args) {
        /**
         * 本身的类型指向引用 new 本身的对象
         * 非多态
         */
        Dog dog = new Dog();
        dog.eat();
        System.out.println(dog.age);
        System.out.println(dog.weight);


        /**
         * 有父类的引用指向子类对象
         * 多态
         */
        AnimalParent animalParent = new Dog();
        animalParent.eat();

        System.out.println(animalParent.age);//20,这个age 是父类animalParent里的 age
//        System.out.println(animalParent.weight);//报错,Cannot resolve symbol 'weight'(无法解析weight)
        //成员属性 编译阶段是看左边(父类animalParent),父类没有这个属性,所以报错

//        animalParent.show();//报错,Cannot resolve method 'show' in 'AnimalParent'
        // 成员方法 编译阶段是看左边(父类animalParent),父类没有show这个方法,所以报错,
        //执行虽然看的右边 子类有show(),但是这个show()没有重写父类的show()
        // (父类没有show())所以,在编译阶段都报错,何谈执行阶段
        

        animalParent.eat(); // 输出:子类(狗类)重写了父类 eat 方法
        //父类和子类都有eat()方法,但是 执行是看右边的(子类Dog)里的eat()
        // Ctrl + Alt + 鼠标点击eat,可以看到都有那些类里面有eat()方法
    }
}

下一篇文章:

你可能感兴趣的:(java,开发语言,多态,面向对象,继承,重写,引用)