我想出了编写特定代码的问题,但我会尽量将问题保持为通用。
其他类似的问题是指C#,它似乎对此有一些特定于语言的处理,下面的代码是Java,但是我们再试着让它保持通用。
假设我有一个实现接口I的A类。
这对我有用,因为我可以实现仅将A用作I类型并抽象实现的方法。
我们现在说,我有B类实现了接口I中的所有方法,但它从未被称为只有我。
现在我们说,我有B类,它实现的方法与接口I中的方法具有相同的名称/签名,但它没有实现接口。
我应该一直明确地实施吗? 即使我不使用它(虽然我可能在将来)进行类型抽象?
更有意义的,即使可能不现实,例如:
interface Printable {
String print()
class A implements Printable {
//code...
String print(){return "A";}
//code...
}
class B {
//code...
String print(){return "B";}
void otherMethod(){/*code*/}
//code...
}
class Test {
Printable a = new A();
System.out.println(a.print());
B b = new B();
b.otherMethod();
System.out.println(b.print());
}
显式实现或不支持Printable接口有什么缺点吗?
我唯一能想到的是第二种情况的可扩展性。 从某种意义上说,如果有一天我会明确地将其用作Printable,我将能够毫不费力地这样做。
但还有什么(模式,优化,良好的编程,风格......)我应该考虑吗?
答案 0 :(得分:0)
在某些情况下,由于不能很好地使用JIT方法内联,因此类型层次结构会影响方法调用成本。可以在Guava ImmutableList (and others) offer awful performance in some cases due to size-optmized specializations #1268 bug中找到一个例子:
许多番石榴不可变集合都有一个可爱的技巧,它们具有零(EmptyImmutableList)和一个(SingletonImmutableList)元素集合的特化。这些特化采用ImmutableList的子类形式,与“常规”实现一起使用,还有一些其他特殊化,如ReverseImmutable,SubList等。
不幸的是,结果是当这些子类在某个调用站点混合时,调用是变形的,与没有这些特化的类相比,性能很差(更糟的是20倍或更多)。
答案 1 :(得分:0)
我不认为这个问题有一个简单的正确答案。
但是,如果您没有实现该方法,则应该这样做:
public void unusedBlahMethod() {
throw new UnsupportedOperationException("operation blah not supported");
}
省略未使用方法的优点是:
省略该方法的缺点是:
UnsupportedOperationException
可能会导致将来出现错误(虽然良好的测试覆盖范围应该可以防止错误)。答案 2 :(得分:0)
如果您正在编写一次性代码,则不需要编写界面,但有一天您可能会注意到,您应该花时间编写界面。
接口的主要优点和目的是使用不同实现的灵活性。我可以放一些东西,它在方法中提供相同的功能,我可以为测试目的创建一个假的,我可以创建一个行为与原始对象一样的装饰器,但可以记录这些东西。
示例:
public interface A {
void someMethod();
}
public class AImplementation {
@Override
public void someMethod() {
// implementation
}
}
public class ADecorator {
private final A a;
public ADecorator(A a) {
this.a = a;
}
@Override
public void someMethod() {
System.out.println("Before method call");
a.someMethod();
System.out.println("After method call");
}
}
好的副作用:ADecorator适用于A的每个实现。 这种灵活性的成本并不高,如果您的代码存活时间稍长,您应该接受它。