静态方法的继承问题

 

  最近看到静态方法的继承问题,看到网上的说法,自己还是有点不太理解,静态方法不是不可以被继承,同样的,静态方法也可以被继承,但是子类对于静态方法的“重写”是通过隐藏父类的静态方法来实现的,所以静态方法可以被继承,但是不能被重写,因此不能实现多态。

  先看父类实例代码:

  

package test;

public class StaticMethodExtendTestParent {
    public static void MethodA(){
        System.out.println("Parent MethodA!");
    }
    public void MethodB(){
        System.out.println("Parent MethodB Call MethodA!");
        MethodA();
    }
    
    public void MethodC(){
        System.out.println("Parent MethodC!");
    }
    public void MethodD(){
        System.out.println("Parent MethodD Call MethodC!");
        MethodC();
    }
}

  在子类中,“重写”了方法A和方法C:

  

package test;

public class StaticMethodExtendTest extends StaticMethodExtendTestParent{
    public static void MethodA(){
        System.out.println("Child MethodA!");
    }
    
    
    public void MethodC(){
        System.out.println("Child MethodC!");
    }
}

  基于以上的情况我们考虑多中情形:

  (1)当我们直接用子类对象调用方法A和方法C

    

public static void main(String[] args) {
        StaticMethodExtendTest child = new StaticMethodExtendTest();
        child.MethodA();
        child.MethodC();

    }

  输出:

  

  和我们平时的理解一样,调用的都是子类的A和C方法,这样看起来静态方法和非静态方法是一样的,好像都将父类的方法进行了重写覆盖。

  (2)父类对象接受子类对象向上转型调用方法A和方法C

    public static void main(String[] args) {

        StaticMethodExtendTestParent parent = new StaticMethodExtendTest();
        parent.MethodA();
        parent.MethodC();
    }

  输出:

  这里我们看到方法C的输出很好的体现了java的多态性质,但是方法A仍然调用的是父类的方法A,这也就是我们前面说的,对于父类的静态方法,子类的“重写”只是将父类的方法隐藏。对于方法C,程序只有在程序运行时才能确定调用的到底是哪个类中实现的方法,有可能是基类的方法,有可能是基类的方法,这取决于StaticMethodExtendTestParent的实例对象接受的是哪一种类(StaticMethodExtendTestParent基类还是子类)。但是对于方法A,在实例对象的类型定义后就已经确定了,如果实例对象为StaticMethodExtendTestParent类型,那么无论对象实际接受的是哪一个子类的对象,方法A的调用始终是StaticMethodExtendTestParent的A方法。在上述实例中如果子类没有MethodA方法,那么子类对象对A方法的调用都将调用父类的A方法,所以静态方法可以被继承,但是不能被重写,无法实现多态

 (3)通过子类对象在父类的方法中调用被子类“重写”的方法

  

public static void main(String[] args) {
        StaticMethodExtendTest child = new StaticMethodExtendTest();
        child.MethodA();
        child.MethodB();
        child.MethodC();
        child.MethodD();
        System.out.println("=====================");
        StaticMethodExtendTestParent parent = new StaticMethodExtendTest();
        parent.MethodA();
        parent.MethodB();
        parent.MethodC();
        parent.MethodD();
    }

测试结果:

  这里直接测试了两种情况,可以看出无论子类有没有向上转型,当调用父类方法时B,B中有对静态方法A的调用,都是直接调用的父类的静态方法A,方法D和C的调用则是我们熟知的多态的情形。

  

posted @ 2017-11-13 21:18  封尘寒剑  阅读(2875)  评论(0编辑  收藏  举报