问题是在Java中为什么我不能定义一个抽象的静态方法?例如
abstract class foo {
abstract void bar( ); // <-- this is ok
abstract static void bar2(); //<-- this isn't why?
}
Run Code Online (Sandbox Code Playgroud) Java 8最有用的功能之一是default接口上的新方法.基本上有两个原因(可能还有其他原因)为什么会被引入:
Iterator.remove()Iterable.forEach()从API设计者的角度来看,我希望能够在接口方法上使用其他修饰符,例如final.在添加便捷方法时,这将非常有用,可防止在实现类时出现"意外"覆盖:
interface Sender {
// Convenience method to send an empty message
default final void send() {
send(null);
}
// Implementations should only implement this method
void send(String message);
}
Run Code Online (Sandbox Code Playgroud)
如果Sender是一个类,上面已经是常见的做法:
abstract class Sender {
// Convenience method to send an empty message
final void send() {
send(null);
}
// Implementations should only implement this method
abstract void send(String message);
}
Run Code Online (Sandbox Code Playgroud)
现在,default并final有明显矛盾的关键字,但默认关键字本身不会一直严格要求 …
该主题大部分都说明了 - 静态方法无法在接口中声明的原因是什么?
public interface ITest {
public static String test();
}
Run Code Online (Sandbox Code Playgroud)
上面的代码给出了以下错误(至少在Eclipse中):"接口方法ITest.test()的非法修饰符;只允许使用public和abstract".
这里提出了一些问题,为什么你不能在接口中定义静态方法,但它们都没有解决基本的不一致性:为什么你可以在接口中定义静态字段和静态内部类型,而不是静态方法?
静态内部类型可能不是一个公平的比较,因为这只是产生一个新类的语法糖,但为什么是字段而不是方法?
接口中的静态方法的一个参数是它破坏了JVM使用的虚拟表解析策略,但是不应该同样适用于静态字段,即编译器可以内联它吗?
一致性是我想要的,Java应该支持接口中没有任何形式的静态,或者它应该是一致的并允许它们.
我知道在Java中,静态方法就像实例方法一样继承,不同之处在于,当重新声明它们时,父实现被隐藏而不是被覆盖.好吧,这很有道理.但是,Java教程指出了这一点
接口中的静态方法永远不会被继承.
为什么?常规和接口静态方法有什么区别?
当我说静态方法可以继承时,让我澄清一下我的意思:
class Animal {
public static void identify() {
System.out.println("This is an animal");
}
}
class Cat extends Animal {}
public static void main(String[] args) {
Animal.identify();
Cat.identify(); // This compiles, even though it is not redefined in Cat.
}
Run Code Online (Sandbox Code Playgroud)
然而,
interface Animal {
public static void identify() {
System.out.println("This is an animal");
}
}
class Cat implements Animal {}
public static void main(String[] args) {
Animal.identify();
Cat.identify(); // This does not compile, because interface …Run Code Online (Sandbox Code Playgroud) 在Java中,我希望能够定义标记接口,强制实现提供静态方法.例如,对于简单的文本序列化/反序列化,我希望能够定义一个看起来像这样的接口:
public interface TextTransformable<T>{
public static T fromText(String text);
public String toText();
Run Code Online (Sandbox Code Playgroud)
由于Java中的接口不能包含静态方法(如许多其他帖子/线程中所述:此处,此处,此处此代码不起作用.
然而,我正在寻找的是表达相同意图的一些合理范例,即对称方法,其中一个是静态的,并由编译器强制执行.现在我们能想到的最好的是某种静态工厂对象或通用工厂,这两者都不是真正令人满意的.
注意:在我们的例子中,我们的主要用例是我们有许多很多"值对象"类型 - 枚举或其他具有有限数量值的对象,通常不会超出其值,并且我们解析/ de -parse数秒钟的时间,所以实际上关心重用实例(如Float,Integer等)及其对内存消耗的影响/ gc
有什么想法吗?
编辑1:为了消除一些混乱 - 我们有许多不同的对象适合这种模式 - 实际上我们正试图为具有2个语义的调用者提出一些优雅的东西:
就我们对Flyweight,Factories的看法而言 - 它们都是我们考虑过的选项,我们真的试图看看我们是否能找到更优雅的东西,而不是依靠JavaDoc说"实现工厂并委托调用它,或按惯例在XXX地点公开"
首先,我阅读了erickson对"为什么我不能在Java接口中定义静态方法?"的有用回复..这个问题不是关于"为什么"而是关于"当时如何?".
虽然我现在确信在大多数情况下我想做的事情是矫枉过正,但有一种情况可能需要:
我再举一个ParametricFunction例子.现在让我们来看一个复杂的函数,比如Bessel函数,其中查找表是合适的.这必须初始化,因此两个选项是将参数直接传递给构造函数或提供init(double[] parameters).后者的缺点是getValue(double x)必须检查每次调用的初始化(或者ArrayIndexOutOfBoundsException必须考虑初始化检查),因此对于时间要求严格的应用程序,我更喜欢构造函数方法:
interface ParametricFunction {
public double getValue(double x);
}
class BesselFunction implements ParametricFunction {
public BesselFunction(double[] parameters) { ... }
public double getValue(double x) { ... }
}
Run Code Online (Sandbox Code Playgroud)
这涉及另一个问题,接口中构造函数的不可能性.那里有什么好的解决方案?我当然可以使用这种init(double[] parameters)方法,但我之所以提到我的原因.
(编辑:好的,这里实现接口的抽象类会这样做)
现在让我们假设ParametricFunction只允许某些参数,例如正整数.如何检查传递给构造函数的参数的真实性?抛出一个IllegalArgument例外是可能的,但checkParametersValidity(double[] parameters)似乎更方便.但是在构造之前需要检查参数,因此它必须是静态方法.这就是我真正想知道的方法,以确保实现ParametricFunction接口的每个类都定义了这个静态方法.
我知道这个例子是相当人为的,不仅仅是init通过接口使用方法的原因值得商榷,我仍然想知道答案.如果您不喜欢它,请将其视为学术问题.
(原例)
所以基本上我希望一个接口提供常用方法和例如getSimilarObject方法.对于(一个组成的)例子
public interface ParametricFunction {
/** @return f(x) using the parameters */ …Run Code Online (Sandbox Code Playgroud) 关于为什么没有抽象的静态方法/字段,已经有几个SO问题,但我想知道如何实现以下伪代码:
class Animal {
abstract static int getNumberOfLegs(); // not possible
}
class Chicken inherits Animal {
static int getNumberOfLegs() { return 2; }
class Dog inherits Animal {
static int getNumberOfLegs() { return 4; }
Run Code Online (Sandbox Code Playgroud)
这是问题:假设我想确保每个继承的类Animal都包含getNumberOfLegs()方法(即几乎像一个接口,除了我确实希望抽象类实现所有子类共有的几个方法,因此纯接口不会在这里工作).getNumberOfLegs()显然应该是一个静态的方法(假设在一个完美的世界中,我们不会使鸡和狗瘫痪,因此getNumberOfLegs不依赖于实例).
如果没有"抽象静态"方法/字段,可以将方法从Animal类中删除,然后存在某些子类没有该方法的风险.或者可以制作getNumberOfLegs一个实例方法,但是必须实例化一个类以找出动物有多少腿 - 即使它没有必要.
人们通常如何实施这种情况?
编辑:我在这里如何使用它.假设(现在这很荒谬,但无论如何......)每只动物的腿数是独一无二的,所以我可能有类似的东西:
Animal getModelAnimal(int numberOfLegs) {
if (numberOfLegs == Chicken.getNumberOfLegs()) return new Chicken();
else if (numberOfLegs == Dog.getNumberOfLegs()) return new Dog();
}
Run Code Online (Sandbox Code Playgroud) 如何声明实现类的java接口字段应该优化该字段?
例如
public interface IWorkflow{
public static final String EXAMPLE;// interface field
public void reject();
}
// and implement class
public class AbstWorkflow implements IWorkflow
{
public static final String EXAMPLE = "ABCD"; /*MUST HAVE*/
public void reject(){}
...
}
Run Code Online (Sandbox Code Playgroud)
谢谢.