问题是,在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?
}
当前回答
抽象类不能有静态方法,因为抽象是为了实现DYNAMIC BINDING,而静态方法是静态绑定到它们的功能上的。静态方法的意思是 行为不依赖于实例变量,因此没有实例/对象 是必需的。只是上课而已。静态方法属于类而不是对象。 它们存储在一个称为PERMGEN的内存区域中,每个对象都从这里共享它们。 抽象类中的方法动态地绑定到它们的功能上。
其他回答
因为abstract是应用于abstract方法上的关键字,所以abstract方法不指定主体。而静态关键字则属于类区域。
因为如果你在类中使用任何静态成员或静态变量,它将在类加载时加载。
我相信我已经找到了这个问题的答案,即为什么接口的方法(就像父类中的抽象方法一样工作)不能是静态的。以下是完整的答案(不是我的)
基本上静态方法可以在编译时绑定,因为要调用它们你需要指定一个类。这与实例方法不同,对于实例方法,在编译时调用方法的引用的类可能是未知的(因此只能在运行时确定调用哪个代码块)。
如果您正在调用一个静态方法,那么您已经知道实现它的类,或者它的任何直接子类。如果你定义
abstract class Foo {
abstract static void bar();
}
class Foo2 {
@Override
static void bar() {}
}
然后任意Foo.bar();调用显然是非法的,您将始终使用Foo2.bar();。
考虑到这一点,静态抽象方法的唯一目的是强制子类实现这样的方法。你可能最初认为这是非常错误的,但如果你有一个泛型类型参数<E扩展MySuperClass>,它将很好地通过接口保证E可以. dosomething()。请记住,由于类型擦除,泛型只存在于编译时。
那么,它有用吗?是的,也许这就是为什么Java 8允许在接口中使用静态方法(尽管只有默认实现)。为什么不在类中使用默认实现抽象静态方法呢?很简单,因为具有默认实现的抽象方法实际上是一个具体方法。
为什么不使用没有默认实现的抽象/接口静态方法?显然,这仅仅是因为Java识别它必须执行哪个代码块的方式(我回答的第一部分)。
假设有两个类,父类和子类。父母是抽象的。声明如下:
abstract class Parent {
abstract void run();
}
class Child extends Parent {
void run() {}
}
这意味着Parent的任何实例都必须指定如何执行run()。
但是,现在假设Parent不是抽象的。
class Parent {
static void run() {}
}
这意味着Parent.run()将执行静态方法。
抽象方法的定义是“声明但未实现的方法”,这意味着它本身不返回任何东西。
静态方法的定义是“对于相同的参数返回相同值的方法,而不管调用它的实例是什么”。
抽象方法的返回值会随着实例的改变而改变。静态方法则不会。静态抽象方法基本上是这样一种方法,它的返回值是常量,但不返回任何东西。这是一个逻辑矛盾。
同样,使用静态抽象方法的理由也不多。
当常规方法要被子类覆盖并提供功能时,它们可以是抽象的。 假设类Foo由Bar1, Bar2, Bar3等扩展。因此,每个人都将根据自己的需要拥有自己的抽象类版本。
静态方法根据定义属于类,它们与类的对象或类的子类的对象无关。它们甚至不需要它们存在,它们可以在不实例化类的情况下使用。因此,它们需要准备就绪,不能依赖于子类向它们添加功能。