Java-static方法

    java中静态属性和静态方法可以被继承,但是没有被重写(overwrite)而是被隐藏. 

    原因: 
        1). 静态方法和属性是属于类的,调用的时候直接通过类名.方法名完成,不需要继承机制就可以调用。如果子类里面定义了静态方法和属性,那么这时候父类的静态方法或属性称之为"隐藏"。如果你想要调用父类的静态方法和属性,直接通过父类名.方法或变量名完成。 

        2). 多态之所以能够实现依赖于继承、接口和重写、重载(继承和重写最为关键)。有了继承和重写就可以实现父类的引用指向不同子类的对象。静态属性、静态方法都可以被继承和隐藏而不能被重写,因此不能实现多态,而非静态方法可以被继承和重写,因此可以实现多态。重写的功能是:"重写"后子类的优先级要高于父类的优先级,但是“隐藏”是没有这个优先级之分的。 


    隐藏(Hide)与覆写有两点不同:

    (1)表现形式不同。隐藏用于静态方法,覆写用于非静态方法。在代码上的表现是:@Override注解可以用于覆写,不能用于隐藏。
    (2)职责不同。隐藏的目的是为了抛弃父类静态方法,重现子类方法,例如我们的例子,Sub.doSomething的出现是为了遮盖父类的Base.doSomething方法,也就是期望父类的静态方法不要破坏子类的业务行为;而覆写则是将父类的行为增强或减弱,延续父类的职责。

我们先看一个例子:

public class Client {  
     public static void main(String[] args) {  
          Base base = new Sub();  
          //调用非静态方法  
          base.doAnything();  
          //调用静态方法  
          base.doSomething();  
     }  
}  
 
class Base{  
     //父类静态方法  
     public static void doSomething(){  
          System.out.println("我是父类静态方法");  
     }  
     //父类非静态方法  
     public void doAnything(){  
          System.out.println("我是父类非静态方法");  
     }  
}  
 
class Sub extends Base{  
     //子类同名、同参数的静态方法  
     public static void doSomething(){  
          System.out.println("我是子类静态方法");  
     }  
     //覆写父类的非静态方法  
     @Override  
     public void doAnything(){  
          System.out.println("我是子类非静态方法");  
     }  
} 

输出结果是:

我是子类非静态方法

我是父类静态方法

    我们知道一个实例对象有两个类型:表面类型(Apparent Type)和实际类型(Actual Type),表面类型是声明时的类型,实际类型是对象产生时的类型,比如我们例子,变量base的表面类型是Base,实际类型是Sub。对于非静态方法,它是根据对象的实际类型来执行的,也就是执行了Sub类中的doAnything方法。而对于静态方法来说就比较特殊了,首先静态方法不依赖实例对象,它是通过类名访问的;其次,可以通过对象访问静态方法,如果是通过对象调用静态方法,JVM则会通过对象的表面类型查找到静态方法的入口,继而执行之。因此上面的程序打印出“我是父类静态方法”,也就不足为奇了。

    通过实例对象访问静态方法或静态属性不是好习惯,它给代码带来了“坏味道”,建议读者阅之戒之。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值