日期:2014-05-20  浏览次数:20876 次

关于覆写静态方法的问题

public class StaticTest {
public static void  test(){
}
public static void main(String[] args){
new test().test();
}
}
class test extends StaticTest{
public void  test(){
}
}
//Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
// This instance method cannot override the static method from StaticTest
//
// at test.test(StaticTest.java:10)
// at StaticTest.main(StaticTest.java:6)


我知道静态方法是没有多态的,求高人解释,JAVA为什么要这样设计,
使得我用一个子类去继承一个父类的时候,当我把子类的一个非静态方法的签名与父类的静态方法签名一样的时候,会报错?
------最佳解决方案--------------------
如果你子类没有test方法,通过
StaticTest t = new test;
t.test();//虽然不建议这样使用静态方法,但存在这样的用法

调用的就是父类的静态方法,现在子类弄一个public void  test()来,上面代码究竟该如何执行?当然可以做出硬性规定,但,太容易引起混乱了
------其他解决方案--------------------
其实这是 Java 设计的一个不足之处,在 Java 中,可以通过 类名.方法名,或者 实例名.方法名 这两种方式来调用静态方法

也就是说,在 test 类没有定义 test 方法时,也是可以通过
new test().test() 来访问其父类定义好的静态方法的

而这时如果在子类 test 中定义了和父类相同签名的方法,则 javac 在执行时可能会产生歧义:它不知道该调用父类的静态方法还是子类的非静态方法了

所以,严格来说,静态方法应该只能由 类名.方法名 来调用,而不能通过实例调用(C# 就是这样的规则)
------其他解决方案--------------------
引用:
我知道静态方法是没有多态的,求高人解释,JAVA为什么要这样设计,
使得我用一个子类去继承一个父类的时候,当我把子类的一个非静态方法的签名与父类的静态方法签名一样的时候,会报错?


你那样写是会报错的,子类覆盖不了静态方法。
本来静态方法就是属于整个类的,下面的所有的 子类 以及 实例化对象 都能用。
你现在要在子类覆盖静态方法,相当于把类的方法私有化,那肯定是不行的。会引起混乱的。

------其他解决方案--------------------
静态方法是类在加载时就被加载到内存中的方法,在整个运行过程中保持不变,因而不能重写。但非静态方法是在对象实例化时才单独申请内存空间,为每一个实例分配独立的运行内存,因而可以重写。
------其他解决方案--------------------
静态方法是一终态方法,不能被继承,因此子类的方法不能覆盖父类的方法。

public class StaticTest
{
    public static void  test() //也可以直接去掉static
{   
   System.out.println("------------");
}
    public static void main(String[] args){
        new test().test();
    }
}
class test extends StaticTest
{
    public void  test1() //可以这样改
{
    System.out.println("____________________");
}
}
------其他解决方案--------------------
记住这个
 
public class StaticTest {    
     public static void  test(){
       System.out.println("test from StaticTest")    
     }    
     public void test2(){
       System.out.println("test2 from StaticTest");
     }

class test extends StaticTest{    
   public static void  test(){ System.out.println("test from test")   }