问题是,在Java中为什么不能定义抽象静态方法?例如
abstract class foo {
abstract void bar( ); // <-- this is ok
abstract static void bar2(); //<-- this isn't why?
}
问题是,在Java中为什么不能定义抽象静态方法?例如
abstract class foo {
abstract void bar( ); // <-- this is ok
abstract static void bar2(); //<-- this isn't why?
}
当前回答
有一种情况是静态和抽象可以一起使用,那就是当这两个修饰符都放在嵌套类的前面时。
其他回答
你不能重写静态方法,所以使它抽象是没有意义的。此外,抽象类中的静态方法将属于该类,而不是覆盖类,因此无论如何都不能使用。
方法的抽象注释表明该方法必须在子类中重写。
在Java中,静态成员(方法或字段)不能被子类覆盖(在其他面向对象语言中不一定是这样,请参阅SmallTalk)。静态成员可能被隐藏,但这与被覆盖有本质区别。
由于静态成员不能在子类中被重写,因此抽象注释不能应用于它们。
顺便说一句,其他语言确实支持静态继承,就像实例继承一样。从语法的角度来看,这些语言通常要求在语句中包含类名。例如,在Java中,假设你在ClassA中编写代码,这是等价的语句(如果methodA()是一个静态方法,并且没有具有相同签名的实例方法):
ClassA.methodA();
and
methodA();
在SmallTalk中,类名不是可选的,所以语法是(注意,SmallTalk不使用。将“主语”和“动词”分开,而是将其用作语句结束符):
ClassA methodA.
因为总是需要类名,所以总是可以通过遍历类层次结构来确定方法的正确“版本”。无论如何,我偶尔会错过静态继承,当我第一次开始使用Java时,我就被Java中缺乏静态继承所困扰。此外,SmallTalk是duck类型的(因此不支持契约式编程)。因此,类成员没有抽象修饰符。
假设有两个类,父类和子类。父母是抽象的。声明如下:
abstract class Parent {
abstract void run();
}
class Child extends Parent {
void run() {}
}
这意味着Parent的任何实例都必须指定如何执行run()。
但是,现在假设Parent不是抽象的。
class Parent {
static void run() {}
}
这意味着Parent.run()将执行静态方法。
抽象方法的定义是“声明但未实现的方法”,这意味着它本身不返回任何东西。
静态方法的定义是“对于相同的参数返回相同值的方法,而不管调用它的实例是什么”。
抽象方法的返回值会随着实例的改变而改变。静态方法则不会。静态抽象方法基本上是这样一种方法,它的返回值是常量,但不返回任何东西。这是一个逻辑矛盾。
同样,使用静态抽象方法的理由也不多。
因为“抽象”的意思是:“不实现任何功能”,而“静态”的意思是:“即使你没有对象实例,也有功能”。这是一个逻辑矛盾。
糟糕的语言设计。直接调用静态抽象方法要比为使用该抽象方法而创建实例有效得多。当使用抽象类作为枚举无法扩展的变通方法时尤其如此,这是另一个糟糕的设计示例。希望他们能在下一个版本中解决这些限制。