Java中静态变量与静态方法的继承

Posted 二木成林

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中静态变量与静态方法的继承相关的知识,希望对你有一定的参考价值。

看下面的代码:

public class Demo {
    public static void main(String[] args) {
        // 子类SonB继承父类Father,子类可以获取父类的所有属性和方法,无论是静态的还是非静态的。
        // 表明静态属性和静态方法可以被继承
        SonB sonB = new SonB();
        System.out.println(sonB.staticStr);// 获取父类的静态变量
        System.out.println(sonB.notStaticStr);// 获取父类的成员变量(非静态变量)
        sonB.staticMethod();// 调用父类的静态方法
        sonB.notStaticMethod();// 调用父类的非静态方法(成员方法)

        System.out.println("=============================================");

        // 表明在使用多态的情况下,静态属性和静态方法又可以被继承
        Father sonBF = new SonB();
        System.out.println(sonBF.staticStr);// 多态获取父类的静态变量
        System.out.println(sonBF.notStaticStr);// 多态获取父类的成员变量(非静态变量)
        sonBF.staticMethod();// 多态调用父类的静态方法
        sonBF.notStaticMethod();// 多态调用父类的非静态方法(成员方法)

        System.out.println("=============================================");
        System.out.println("=============================================");

        // 子类SonA继承父类Father,并且重写了父类的属性和方法。
        // 表明父类的静态属性和静态方法可以被覆盖
        SonA sonA = new SonA();
        System.out.println(sonA.staticStr);// 获取子类重写后的静态变量
        System.out.println(sonA.notStaticStr);// 获取子类重写后的成员变量(非静态变量)
        sonA.staticMethod();// 调用子类重写后的静态方法
        sonA.notStaticMethod();// 调用子类重写后的非静态方法(成员方法)

        System.out.println("=============================================");

        // 表明父类的静态属性和静态方法可以被覆盖,但覆盖后就没有多态了
        Father sonAF = new SonA();
        System.out.println(sonAF.staticStr);// 多态获取子类重写后的静态变量
        System.out.println(sonAF.notStaticStr);// 多态获取子类重写后的成员变量(非静态变量)
        sonAF.staticMethod();// 多态调用子类重写后的静态方法
        sonAF.notStaticMethod();// 多态调用子类重写后的非静态方法(成员方法)

        Father.staticMethod();
        SonA.staticMethod();
    }
}

/**
 * 父类
 */
class Father {
    public static String staticStr = "父类的静态变量";
    public String notStaticStr = "父类的成员变量(非静态变量)";

    public static void staticMethod() {
        System.out.println("父类的静态方法");
    }

    public void notStaticMethod() {
        System.out.println("父类的成员方法(非静态方法)");
    }
}

/**
 * 子类继承父类,改写静态变量和方法
 */
class SonA extends Father {
    public static String staticStr = "子类改写后的静态变量";
    public String notStaticStr = "子类改写后的成员变量(非静态变量)";

    public static void staticMethod() {
        System.out.println("子类改写后的静态方法");
    }

    @Override
    public void notStaticMethod() {
        // 成员方法是可以被子类重写的,这里仅作说明
        System.out.println("子类改写后的成员方法(非静态方法)");
    }
}

/**
 * 子类继承父类中的所有属性和方法,但不修改
 */
class SonB extends Father {

}

/*打印结果:
    父类的静态变量
    父类的成员变量(非静态变量)
    父类的静态方法
    父类的成员方法(非静态方法)
    =============================================
    父类的静态变量
    父类的成员变量(非静态变量)
    父类的静态方法
    父类的成员方法(非静态方法)
    =============================================
    =============================================
    子类改写后的静态变量
    子类改写后的成员变量(非静态变量)
    子类改写后的静态方法
    子类改写后的成员方法(非静态方法)
    =============================================
    父类的静态变量
    父类的成员变量(非静态变量)
    父类的静态方法
    子类改写后的成员方法(非静态方法)
    父类的静态方法
    子类改写后的静态方法
 */

可以看到父类的静态方法和变量可以被覆盖,也允许在子类中定义同名的静态变量和静态方法,但没有多态。

即“Java中静态属性和静态方法可以被继承,但是没有被重写(overwrite)而是被隐藏”。原因如下:

  • 静态方法和属性是属于类的,与类绑定在一起的,调用的时候直接通过类名,不需要继承机制就可以调用。如果子类里面定义了同名的静态方法和属性,那么这时候父类的静态方法和属性称之为“隐藏”,也就是上面第三段代码所表现出来的结果。如果要调用父类的静态方法和属性,直接通过父类名调用方法或属性即可完成。
  • 多态的实现是依赖于继承、接口和重写,有了继承和重写才可以实现父类的引用指向不同子类的对象。重写后子类的优先级要高于父类的优先级,但是隐藏没有这个优先级。
  • 静态属性和静态方法都可以被继承和隐藏而不能被重写,因此不能实现多态,也就不能使用父类的引用指向不同的子类对象。

总结:

  • 如果子类定义了与父类同名的静态属性和静态方法,那么在子类调用的一定是子类的静态属性和静态方法。
  • 如果子类没有定义与父类同名的静态属性和静态方法,那么在子类调用的一定是父类的静态属性和静态方法。

参考链接:

以上是关于Java中静态变量与静态方法的继承的主要内容,如果未能解决你的问题,请参考以下文章

Java中静态变量与静态方法的继承

Java类的各种成员初始化顺序如:父子类继承时的静态代码块,普通代码块,静态方法,构造方法,等先后顺

继承,修饰符

JAVA继承:编译与运行的关系(编译看左边,运行看右边)

java中的静态

记一次抽象类中定义的静态变量,多个子类继承后,在方法中被重写引起的问题