在Java和类似语言中,必须明确表示类实现接口的真正原因是什么?
想象一下隐式实现:
interface Flyer { void fly(); }
public class Duck { public void fly() {...} }
public class Plane { public void fly() {...} }
public class Hoe { void hangAround() {...} }
void startFlying(Flyer flyer) {...}
void race() {
...
startFlying(duck); // OK
startFlying(plane); // OK
startFlying(hoe); // Compilation error.
}
Run Code Online (Sandbox Code Playgroud)
编译器知道方法的签名,返回类型(当然还有修饰符).在这一点上,似乎很清楚,没有必要明确指定Duck和Plane实现Flyer.
我会说可以从Java中删除"实现XYZ"而不用担心.
没有区别,请在编译时检查,这样就可以了.
另一方面:@JBNizet提到了具有相同签名和返回类型的方法的不同含义.
我会用他的例子:
interface Runner { void run(); }
public class Guy { public void run(); }
public class Gal { public void run(); }
void startRunning(Runner r) {...}
void race() {
startRunning(guy); // OK
startRunning(gal); // OK
startRunning(runnableThread); // OK
}
Run Code Online (Sandbox Code Playgroud)
好的编译器,确定startRunning()(对我来说没问题).如果这对你好或没有,那取决于你的理念.
明确:
public class Guy **implements Runner **{ public void run(); }
public class Gal **implements Runner **{ public void run(); }
Run Code Online (Sandbox Code Playgroud)
粗体(或**和**之间的文字)是您必须支付的价格
void race() {
startRunning(guy); // OK
startRunning(gal); // OK
startRunning(runnableThread); // Compilation error!
}
Run Code Online (Sandbox Code Playgroud)
请注意编译错误,以便在测试之前查看问题.
如果它打算在startRunning()中使用runnableThread,你必须更明确地执行它(有足够的时间来实现你正在做的事情).
"我想知道通过解决与隐式实现的接口问题浪费的时间相比,通过解决与输入"实现XYZ"相关的问题浪费了多少时间.如果对于隐式实现的接口更好,那么我讨厌Java设计者的决定和那个他们迫使我们相信它更好:-)"
瓢虫和空中客车(和鸭子)
我认为隐式实现接口的问题只是理论上的,实际上很少见.
public class Airbus {
void takeOff() {...}
void land() {...}
Passenger[] getPassengers() {...}
}
public class Ladybug {
void takeOff() {...}
void land() {...}
}
public class Duck {
void takeOff() {...}
void land() {...}
Passenger[] getPassengers() {...}
}
public interface Aircraft {
void takeOff();
void land();
Passenger[] getPassengers();
}
public void fly(Aircraft aircraft) {
aircraft.takeOff();
for (Passenger p : aircraft.getPassengers()) {...}
aircraft.land();
}
public void airport() {
fly(airbus_a380); // OK
fly(ladybug); // Compilation error, does not match Aircraft requirements.
fly(duck); // OK
}
public interface Lander {
void land();
}
public void landAtMeadow(Lander lander) {...}
public void meadow() {
landAtMeadow(airbus_a380); // OK
landAtMeadow(duck); // OK
landAtMeadow(ladybug); // OK
}
Run Code Online (Sandbox Code Playgroud)
所有这些都符合landAtMeadow的要求,因此它们可以在这种情况下使用.即使有可能无法在草地上降落airbus_a380(在其他方面需要测试),你需要在紧急情况下降落在那里.
不要忘记landAtMeadow()可能有更具体的要求
public interface Lander { void landAtLimitedArea(int size); }
Run Code Online (Sandbox Code Playgroud)
要说空间有限,所以如果airbus_a380不支持这种方法,那么你在这里有编译错误.
| 归档时间: |
|
| 查看次数: |
172 次 |
| 最近记录: |