问题是,在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?
}
当前回答
因为“抽象”意味着方法是要被重写的,而不能重写“静态”方法。
其他回答
An abstract method is defined only so that it can be overridden in a subclass. However, static methods can not be overridden. Therefore, it is a compile-time error to have an abstract, static method. Now the next question is why static methods can not be overridden?? It's because static methods belongs to a particular class and not to its instance. If you try to override a static method you will not get any compilation or runtime error but compiler would just hide the static method of superclass.
因为如果一个类扩展了一个抽象类,那么它必须重写抽象方法,这是强制性的。由于静态方法是在编译时解析的类方法,而覆盖方法是在运行时解析的实例方法,并遵循动态多态性。
我相信我已经找到了这个问题的答案,即为什么接口的方法(就像父类中的抽象方法一样工作)不能是静态的。以下是完整的答案(不是我的)
基本上静态方法可以在编译时绑定,因为要调用它们你需要指定一个类。这与实例方法不同,对于实例方法,在编译时调用方法的引用的类可能是未知的(因此只能在运行时确定调用哪个代码块)。
如果您正在调用一个静态方法,那么您已经知道实现它的类,或者它的任何直接子类。如果你定义
abstract class Foo {
abstract static void bar();
}
class Foo2 {
@Override
static void bar() {}
}
然后任意Foo.bar();调用显然是非法的,您将始终使用Foo2.bar();。
考虑到这一点,静态抽象方法的唯一目的是强制子类实现这样的方法。你可能最初认为这是非常错误的,但如果你有一个泛型类型参数<E扩展MySuperClass>,它将很好地通过接口保证E可以. dosomething()。请记住,由于类型擦除,泛型只存在于编译时。
那么,它有用吗?是的,也许这就是为什么Java 8允许在接口中使用静态方法(尽管只有默认实现)。为什么不在类中使用默认实现抽象静态方法呢?很简单,因为具有默认实现的抽象方法实际上是一个具体方法。
为什么不使用没有默认实现的抽象/接口静态方法?显然,这仅仅是因为Java识别它必须执行哪个代码块的方式(我回答的第一部分)。
因为抽象类是一个OOPS概念,静态成员不是OOPS....的一部分 现在我们可以在接口中声明静态完整方法,我们可以通过在接口中声明主方法来执行接口
interface Demo
{
public static void main(String [] args) {
System.out.println("I am from interface");
}
}
在一行中,这种危险的组合(抽象+静态)违反了面向对象的原则,即多态性。
在继承情况下,JVM将在运行时根据实现决定实例的类型(运行时多态性),而不是根据引用变量的类型(编译时多态性)。
@Overriding:
静态方法不支持@ override(运行时多态性),而只支持方法隐藏(编译时多态性)。
@Hiding:
但是在抽象静态方法的情况下,父(抽象)类没有方法的实现。因此,子类型引用是唯一可用的,而且它不是多态性。
子引用是唯一可用的:
出于这个原因(抑制oop特性),Java语言认为抽象+静态是非法(危险)的方法组合。