Java中的多态

302 阅读4分钟

多态是同一个行为具有多个不同表现形式或形态的能力。

多态的优点:1、低耦合  2、易扩展  3、可替换性

多态存在的必要条件:继承 重写 父类引用指向子类对象

成员变量的多态性:

编译的时候,参考父类中的成员变量,如果有,编译成功,如果没有,编译失败。 运行的时候,运行的是父类中的变量值。

package com.shamgod.polymorphism;
/**
 * 动物父类
 * @author ShammGod
 *
 */
public class Animal {

    String name = "动物";
    int age = 10;

}

package com.shamgod.polymorphism;
/**
 * 动物的子类,猪类
 * @author ShammGod
 *
 */
public class Pig extends Animal{
    int age = 2;
    String name = "佩奇";
    String color = "pink";
}


package com.shamgod.polymorphism;
/**
 * 测试类
 * @author ShammGod
 *
 */
public class TestPolymorphism {
    public static void main(String[] args) {

        //父类的引用指向子类的对象
        Animal pig = new Pig();
        //编译不通过,父类没有该属性
        //System.out.println(pig.color);
        //输出的是父类的成员变量的值
        System.out.println(pig.name + " " +pig.age);//动物 10
    }
}

成员方法的多态性:

编译的时候,参考父类中的成员方法,如果有,编译成功,如果没有,编译失败。 运行的时候,运行的是子类的方法。

package com.shamgod.polymorphism;
/**
 * 动物父类
 * @author ShammGod
 *
 */
public class Animal {

    void say() {
        System.out.println("I'm an animal!");
    }
}

package com.shamgod.polymorphism;
/**
 * 动物的子类,猪类
 * @author ShammGod
 *
 */
public class Pig extends Animal{
    
    /*
     * 子类自己的成员方法
     */
    void sayHello() {
        System.out.println("hello");
    }
    
    /*
     * 子类重写父类的方法
     */
    @Override
    void say() {
        // TODO Auto-generated method stub
        System.out.println("I'm a pig!");
    }
}

package com.shamgod.polymorphism;
/**
 * 测试类
 * @author ShammGod
 *
 */
public class TestPolymorphism {
    public static void main(String[] args) {
        
        //父类的引用指向子类的对象
        Animal pig = new Pig();
        //编译不通过,父类没有该方法
        //pig.sayHello();
        //调用的是子类的成员方法
        pig.say();//I'm a pig!
    }
}

静态变量的多态性(一般类变量直接使用类名调用即可,该例子只演示,实际没有人这么用,静态变量属于类,不属于对象):

编译的时候,参考父类中的静态变量,如果有,编译成功,如果没有,编译失败。 运行的时候,运行的是父类中的静态变量值。

package com.shamgod.polymorphism;
/**
 * 动物父类
 * @author ShammGod
 *
 */
public class Animal {
    //父类静态变量
    static String name = "animal";
}

package com.shamgod.polymorphism;
/**
 * 动物的子类,猪类
 * @author ShammGod
 *
 */
public class Pig extends Animal{
    //子类静态变量
    static String name = "pig";
    static int age = 23;
}

package com.shamgod.polymorphism;
/**
 * 测试类
 * @author ShammGod
 *
 */
public class TestPolymorphism {
    public static void main(String[] args) {

        //父类的引用指向子类的对象
        Animal pig = new Pig();
        //父类没有该静态变量,编译不通过
        //System.out.println(pig.age);
        //输出的是父类的静态变量的值
        System.out.println(pig.name);//animal
    }
}

静态方法的多态性:

编译的时候,参考父类中的成员方法,如果有,编译成功,如果没有,编译失败

运行的时候,运行的是父类的方法

package com.shamgod.polymorphism;
/**
 * 动物父类
 * @author ShammGod
 *
 */
public class Animal {
    //父类静态方法
    static void say() {
        System.out.println("I'm an animal");
    }
}

package com.shamgod.polymorphism;
/**
 * 动物的子类,猪类
 * @author ShammGod
 *
 */
public class Pig extends Animal{

    //子类重写父类的静态方法
    static void say() {
        System.out.println("I'm a pig!");
    }
    //子类自己的静态方法
    static void sayHello() {
        System.out.println("Hello!");
    }
}

package com.shamgod.polymorphism;
/**
 * 测试类
 * @author ShammGod
 *
 */
public class TestPolymorphism {
    public static void main(String[] args) {

        //父类的引用指向子类的对象
        Animal pig = new Pig();
        //父类没有该静态方法,编译不通过
        //pig.sayHello();
        //输出的是父类的静态变量的值
        pig.say();//I'm an animal
    }
}

总结

首先说一下静态和非静态,static修饰的变量和方法属于类,不属于对象,是共享的,多态的必要条件包括重写,静态方法是不允许被重写的,所以调用一个对象的静态,就是调用该对象的对应的类的方法,不属于多态的范围。还是那句,多态的必要条件是重写,所以不管成员属性还是类属性,都不能算是多态,调用成员变量的时候调用的是父类引用的值,调用静态变量的时候调用的就是该对象所对应的类的静态变量的值。所以在多态的讨论范围中,应该只有成员方法,当父类的引用指向子类的对象时,调用该对象的方法就是调用子类的成员方法,这就是父子类之间的多态。另外还有一种叫重载,属于类内的多态性。这也符合了多态的定义:“多态是同一个行为具有多个不同表现形式或形态的能力”。