问题描述
我不太明白为什么静态方法可以在Java中继承?
I dont quite understand why Static methods can be inherited in Java ?
继承就像从基类继承而静态属于Class而不是Object。
Inheritance is like inheriting from the base class AND Static belongs to the Class and not Object.
因此,如果Static只属于Class,为什么它会逐渐渗透到派生类?
它不应该只停留在定义它的类中吗?
So if the Static belongs to the Class only why does it trickle down to the derived class ?Shouldn't it just stay with the Class in which it was defined ?
继承静态方法是一种很好的编程习惯吗?
Is Inheriting Static methods a good programming practise ?
推荐答案
在java中静态方法不是继承(或者右边的词是重写)但它们可以隐藏。
In java static methods are not inherited (or the right word is overridden) but they can be hidden.
这里最大的不同之处在于它们不像对象方法那样受多态性影响。
The big different here is that they are not subjected to polymorphism as object method are.
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);
}
}
运行时 C2.main (null)
,您将得到:
C2.M1().
C1.M1().
如你所见,
在C1.main(...)中调用 M1()
参考C1的M1和
calling M1()
in C1.main(...) refer to M1 of C1 and
在C2.main(...)中调用 M1()
引用C2的M1。
calling M1()
in C2.main(...) refer to M1 of C2.
调用M1(没有任何前缀,参见每个 main()
的第一行),不会受到多态性的影响,因为C1中的M1不会被C2覆盖。
The invocation of M1 (with out any prefix, see the first line of each main()
), are not subjected to polymorphism as M1 in C1 does not get overrided by C2.
但是从C2调用是指C2的M1,因为C2的M1是隐藏 C1中的那个。
But calling from C2 refer to M1 of C2 as M1 of C2 is hide the one in C1.
阅读更多。
编辑:我刚刚重新阅读了您的问题,只看到有关良好编程习惯的部分。
I've just re-read your question and just see the part about "good programming practise".
正如我所说,静态方法不是继承的,而是隐藏的,因此它们与不同的方法一样好。
As I said, static method are not inherited but hidden so they are as good as different method.
从代码的角度来看,它们是完全不同的方法。
From a code's point of view, they are completely different methods.
让我们说。
C1 has static method M1.
C2 extends C1 and has static method M1.
C3 extends C2.
当从C1调用M1(无前缀)时,调用C1.M1() 。
从C2调用M1(无前缀)时,调用C2.M1()。 //派生但隐藏
当从C3调用M1(无前缀)时,调用C3.M1()。 //导出并且没有隐藏
When call M1 (without prefix) from C1, you call C1.M1().When call M1 (without prefix) from C2, you call C2.M1(). // derive but get hiddenWhen call M1 (without prefix) from C3, you call C3.M1(). // derive and no hidden
要指定哪个方法,请使用类名称,如 C1.M1()
, C2.M1()
和 C3.M1()
(这将称为 C2.M1( )
)。
To specify which method, use class name like C1.M1()
, C2.M1()
and C3.M1()
(this will called C2.M1()
).
因此,此实现允许重新实现静态方法,但仅作为不同的方法而不是重写(或替换)方法。
So this implementation allows static method to be reimplemented but only as a different method not as an overridden (or replacement) method.
因此,这通常没有区别,比如说: C1_M()
和 C2_M()
。
Therefore, this usually no different from let say naming them differently like: C1_M()
and C2_M()
.
所以你可能会问,为什么还要打扰这个功能呢?我真的不知道。也许允许更灵活的命名方法。
So you may ask, why bother having this feature? I don't really know. Perhaps allows a more flexible naming to method.
但是我使用的用法(可能是也可能不是用途)是通过反射的多态性。
But there is usage (that might or might not be intented) that I used is polymorphism via reflection.
由于您可以使用反射按名称获取和调用方法,因此允许它们具有相同的名称将通过反射启用多态性。
Since you can get and call a method by name using reflection, allowsing them to have a same name will enable polymorphism when do via reflection.
例如(rought代码,可能无法运行):
For example (rought code, may not run):
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);
OR
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);
当想到它时,我认为Java也使用它(比如, writeObject(...)
用于序列化)所以它可能是有意的。
When think about it, I think Java has use this too (like, writeObject(...)
for serialization) so it may be intented.
所以总结一下,隐藏静态方法不是一个好的编程习惯(Eclipse也建议不要这样做)但它在两种情况下很有用,(1)命名方法完全符合它的预期,(2)使用反射对其进行多态化。
So to conclude, hiding static method is not a good programming practice (Eclipse also recommend against it) but it can be useful in two cases, (1) to name the method exact what it suppose to do and (2) to polymorph it using reflection.
希望这会有所帮助。
这篇关于Java中的继承与静态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!