Java中的继承与静态

Gee*_*eek 2 java oop

我不太明白为什么静态方法可以在Java中继承?

继承就像从基类继承AND静态属于Class而不是Object.

因此,如果静态属于类只有为什么它会逐渐渗透到派生类?它不应该只停留在定义它的类中吗?

继承静态方法是一种很好的编程习惯吗?

Naw*_*Man 10

在java中,静态方法不会被继承(或者正确的单词被覆盖),但它们可以被隐藏.

这里的不同之处在于它们不像对象方法那样受多态性影响.

public class C1 {

    static public void M1() {
        System.out.println("C1.M1().");
    }

    static public void main(String ... Args) {
        M1();
    }

}

public class C2 extends C1 {

    static public void M1() {
        System.out.println("C2.M1().");
    }

    static public void main(String ... Args) {
        M1();
        C1.main(Args);
    }

}
Run Code Online (Sandbox Code Playgroud)

运行时C2.main(null),您将获得:

C2.M1().
C1.M1().
Run Code Online (Sandbox Code Playgroud)

如你看到的,

M1()在C1.main(...)中调用是指C1和M1的M1

M1()在C2.main(...)中调用是指C2的M1.

M1的调用(没有任何前缀,参见每个的第一行main())不受多态性的影响,因为C1中的M1不会被C2覆盖.

但是从C2调用指的是C2的M1,因为C2的M1 隐藏了C1中的M1 .

在这里阅读更多.

编辑:我刚刚重新阅读你的问题,只看到关于"良好编程实践"的部分.

正如我所说,静态方法不是继承的,而是隐藏的,因此它们与不同的方法一样好.

从代码的角度来看,它们是完全不同的方法.

让我们说吧.

C1                has static method M1.
C2 extends C1 and has static method M1.
C3 extends C2.
Run Code Online (Sandbox Code Playgroud)

从C1调用M1(无前缀)时,调用C1.M1().从C2调用M1(无前缀)时,调用C2.M1().//派生但隐藏当从C3调用M1(没有前缀)时,调用C3.M1().//派生而不是隐藏

要指定哪一种方法,使用类的名字一样C1.M1(),C2.M1()C3.M1()(这叫做C2.M1()).

因此,此实现允许重新实现静态方法,但仅作为不同的方法而不是重写(或替换)方法.

因此,这通常没有什么不同,比如说:C1_M()C2_M().

所以你可能会问,为什么还要这个功能呢?我真的不知道.也许允许更灵活的命名方法.

但是我使用的用法(可能会或可能不会有意图)是通过反射的多态性.

由于您可以使用反射按名称获取和调用方法,因此允许它们具有相同的名称将通过反射启用多态.

例如(rought代码,可能无法运行):

String aClsName = "C1"; // "C2";
Class aCls = Class.forName(aClsName);
Method   aMth = aCls.getMethod("M1");   // M1 of C1 or C2 depends on the class name.
aMth.invoke(null);
Run Code Online (Sandbox Code Playgroud)

要么

Object aObj = new C1(); // new C2();
Class aCls = aObj.getClass();
Method   aMth = aCls.getMethod("M1");   // M1 of C1 or C2 depends on the class of the object.
aMth.invoke(null);
Run Code Online (Sandbox Code Playgroud)

想一想,我认为Java也使用它(比如,writeObject(...)用于序列化)所以它可能是有意的.

总而言之,隐藏静态方法并不是一个好的编程实践(Eclipse也建议不要这样做)但它在两种情况下很有用,(1)命名方法完全符合它的预期,(2)使用它来变形它反射.

希望这可以帮助.


Ste*_*n C 5

我不太明白为什么静态方法可以在Java中继承?

简短的回答是静态不是用Java继承的.相反,在类中声明的静态成员(受"访问"限制)在派生类的名称空间中直接可见,除非它们在派生类中被声明"隐藏".

因此,如果静态属于类只有为什么它会逐渐渗透到派生类?它不应该只停留在定义它的类中吗?

涓滴不是一个技术术语.但这不是正在发生的事情.类的静态成员不是派生类的成员.

继承静态方法是一种很好的编程习惯吗?

你不能阻止它发生!

仅供参考,这里有一些与静力相关的"良好实践"问题:

  • 可变静态属性应该是私有的,最好重新命名为Singleton对象.

  • 许多静态成员(方法或属性)甚至单身人士都可能是糟糕设计的标志.它肯定不是"面向对象的方式".

  • 在某些类型的应用程序(例如Web应用程序)中,即使是Singleton对象也存在问题.

  • 引用静态方法a obj.someStaticMethod()或者是不好的做法this.someStaticMethod().要么使用类名限定静态名称,要么无限制地引用它.

  • (可以说)更好地限定对超类中静态的引用; 例如,在SubClass中,请参考SuperClass.someStaticMethod()而不是someStaticMethod().(但缺点是代码更冗长.这与导入的利弊相同.)

  • static final 应使用全大写字母声明常量.