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)而是被隐藏”。原因如下:

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

总结:

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

参考链接:

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值