我不太明白为什么可以在Java中继承静态方法?
继承就像从基类继承,而Static属于Class而不是Object。
那么,如果静态仅属于该类,为什么它会滴入派生类呢?它不应该只与定义它的类一起使用吗?
继承静态方法是一种好的编程习惯吗?
在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);
}
}
运行时C2.main(null)
,您将获得:
C2.M1().
C1.M1().
如你看到的,
调用M1()
C1.main(…)引用C1的M1并
M1()
在C2.main(…)中调用是指C2的M1。
对M1的调用(不带任何前缀,请参见的第一行main()
)不会受到多态性的影响,因为C1中的M1不会被C2覆盖。
但是从C2调用将C2的M1称为C2的M1 隐藏 了C1中的那个。
在这里阅读更多。
编辑: 我只是重新阅读了您的问题,并且只看到了有关“良好编程实践”的部分。
如我所说,静态方法不是继承而是隐藏的,因此它们与其他方法一样好。
从代码的角度来看,它们是完全不同的方法。
说吧
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()。//派生且没有隐藏
要指定哪一种方法,使用类名状C1.M1()
,C2.M1()
和C3.M1()
(这将称为C2.M1()
)。
因此,此实现允许重新实现静态方法,但只能作为不同的方法来实现,而不能作为重写(或替换)方法。
因此,这通常与让它们像这样命名不同没有什么不同:C1_M()
和C2_M()
。
所以您可能会问,为什么要麻烦使用此功能?我真的不知道 也许允许对方法进行更灵活的命名。
但是我使用的用法(可能意图也可能不会意图)是通过反射实现的多态性。
由于您可以使用反射按名称获取和调用方法,因此允许它们使用相同的名称将在通过反射进行操作时启用多态。
例如(正常代码,可能无法运行):
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);
要么
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(...)
用于序列化),因此可能是有目的的。
因此,可以得出结论,隐藏静态方法不是一种好的编程习惯(Eclipse也建议不要这样做),但是在两种情况下它很有用:(1)准确地命名该方法应该执行的操作,以及(2)使用该方法对它进行多态化反射。
希望这可以帮助。
问题内容: 假设Java具有以下层次结构类: 这是C#中相同代码的(盲)重复: 当我执行Java代码时,我得到了C#返回的信息。 对我来说,C#的结果更有意义,因为引用B调用了它自己的方法。 Java设计者决定打印而不是打印的逻辑是什么?我的意思是,为什么引用B在C中使用覆盖方法?这种方法的优势是什么? 如何更改Java代码以像C#一样打印出来?我的意思是,我怎么教Java调用它使用的完全引用的方
问题内容: 我想要以下设置: 这在Java中可能吗?怎么样?如果可以避免的话,我宁愿不使用实例变量/方法。 谢谢! 编辑: 常量是数据库表的名称。每个子对象都是一个微型ORM。 问题答案: 您无法完全按照自己的意愿去做。也许可以接受的折衷方案是:
问题内容: 假设我有以下课程: 以及这两个子类: 和 我的问题是这两个子类从父类共享相同的静态curID成员,而不是拥有不同的成员。 所以,如果我这样做: r1,r2,r3的ID为0,1,2,而t1,t2,t3的ID为3,4,5。除了这些,我希望t1,t2,t3的值分别为0、1、2,即使用curID静态变量的另一个副本。 这可能吗?如何? 问题答案: 正如其他人已经写过的,静态成员已绑定到该类,因
我正在用Java建模,并使用构建器模式。在许多情况下,一些共同成员是在父级中定义的,而其他成员则是在从父级继承的子级上定义的。一个例子如下: 如果删除,则在上得到相同的错误。看来我对静态嵌套类的继承有一个根本的误解。 为什么当返回时,编译器会抱怨方法不在中?有没有一种方法可以像我所尝试的那样,利用继承和这个构建器模式,允许在父级中定义公共成员,在子级中定义其他成员?
问题内容: 继承和多态都构成IS- A关系吗?在运行时发生继承和“重写”多态性而在编译时发生“过载”多态性是真的吗?我之所以这样问,是因为许多论坛似乎给出了相互矛盾且常常令人困惑的答案。 谢谢! 问题答案: 对于问题的第一部分,我认为维基百科提供了一个很好的定义: 在面向对象的程序设计中,子类型多态或包含多态是类型理论中的一个概念,其中名称可以表示许多不同类的实例,只要它们与某个公共超类相关即可。
假设我有以下课程: 这两个子类: 和 我的问题是,这两个子类共享来自父类的同一个静态curID成员,而不是拥有不同的成员。 因此,如果我这样做: r1,r2,r3的ID是0,1,2,t1,t2,t3的ID是3,4,5。而不是这些我希望t1,t2,t3有值0,1,2,即使用另一个复制的curID静态变量。 这有可能吗?怎么做?