问题是,在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的内存区域中,每个对象都从这里共享它们。 抽象类中的方法动态地绑定到它们的功能上。
其他回答
抽象类不能有静态方法,因为抽象是为了实现DYNAMIC BINDING,而静态方法是静态绑定到它们的功能上的。静态方法的意思是 行为不依赖于实例变量,因此没有实例/对象 是必需的。只是上课而已。静态方法属于类而不是对象。 它们存储在一个称为PERMGEN的内存区域中,每个对象都从这里共享它们。 抽象类中的方法动态地绑定到它们的功能上。
使用抽象静态方法的想法是,您不能直接为该方法使用特定的抽象类,但只允许一阶导数实现该静态方法(或者对于泛型:您使用的泛型的实际类)。
通过这种方式,您可以创建sortableObject抽象类甚至接口 使用(auto-)抽象静态方法,定义排序选项的参数:
public interface SortableObject {
public [abstract] static String [] getSortableTypes();
public String getSortableValueByType(String type);
}
现在你可以定义一个可排序对象,它可以根据所有这些对象的主要类型进行排序:
public class MyDataObject implements SortableObject {
final static String [] SORT_TYPES = {
"Name","Date of Birth"
}
static long newDataIndex = 0L ;
String fullName ;
String sortableDate ;
long dataIndex = -1L ;
public MyDataObject(String name, int year, int month, int day) {
if(name == null || name.length() == 0) throw new IllegalArgumentException("Null/empty name not allowed.");
if(!validateDate(year,month,day)) throw new IllegalArgumentException("Date parameters do not compose a legal date.");
this.fullName = name ;
this.sortableDate = MyUtils.createSortableDate(year,month,day);
this.dataIndex = MyDataObject.newDataIndex++ ;
}
public String toString() {
return ""+this.dataIndex+". "this.fullName+" ("+this.sortableDate+")";
}
// override SortableObject
public static String [] getSortableTypes() { return SORT_TYPES ; }
public String getSortableValueByType(String type) {
int index = MyUtils.getStringArrayIndex(SORT_TYPES, type);
switch(index) {
case 0: return this.name ;
case 1: return this.sortableDate ;
}
return toString(); // in the order they were created when compared
}
}
现在您可以创建一个
public class SortableList<T extends SortableObject>
它可以检索类型,构建一个弹出菜单来选择要排序的类型,并通过从该类型获取数据来返回列表,以及hainv一个add函数,当选择了排序类型时,可以自动对新项进行排序。 注意SortableList实例可以直接访问“T”的静态方法:
String [] MenuItems = T.getSortableTypes();
必须使用实例的问题是SortableList可能还没有项目,但已经需要提供首选排序。
再见 奥拉夫。
静态方法可以在没有类实例的情况下调用。在你的例子中,你可以调用foo.bar2(),但不能调用foo.bar(),因为bar需要一个实例。 以下代码将工作:
foo var = new ImplementsFoo();
var.bar();
如果您调用一个静态方法,它将始终执行相同的代码。在上面的例子中,即使你在ImplementsFoo中重新定义了bar2,调用var.bar2()也会执行foo.bar2()。
如果bar2现在没有实现(这就是抽象的意思),您可以调用没有实现的方法。这是非常有害的。
糟糕的语言设计。直接调用静态抽象方法要比为使用该抽象方法而创建实例有效得多。当使用抽象类作为枚举无法扩展的变通方法时尤其如此,这是另一个糟糕的设计示例。希望他们能在下一个版本中解决这些限制。
根据定义,静态方法不需要知道这些。因此,它不能是一个虚方法(根据通过this获得的动态子类信息重载);相反,静态方法重载仅基于编译时可用的信息(这意味着:一旦引用了父类的静态方法,就调用父类方法,而不调用子类方法)。
根据这一点,抽象静态方法将是非常无用的,因为您永远不会用一些已定义的对象来代替它的引用。