我一直认为具有相同方法的两个接口不能被一个类继承,正如很多问题所述。
Java jre 7,jdk 1.7
但这里的代码正在运作。
示例:
接口
public interface IObject
{
public Object create(Object object) throws ExceptionInherit;
}
public interface IGeneric<T>
{
public T create(T t) throws ExceptionSuper;
}
实施课程:
public class Test implements IGeneric<Object>, IObject
{
@Override
public Object create(final Object object) throws ExceptionInherit
{
return object;
}
}
这两个方法声明是否具有相同的主体?
例外:
例外只是这个结构的附加物,使其更加复杂。
public class ExceptionSuper extends Exception {}
public class ExceptionInherit extends ExceptionSuper {}
它也没有任何抛出异常。
进一步:如果两个方法接口抛出不同的继承异常,我可以将UserLogic
强制转换为两个接口中的任何一个,并检索异常的不同子集!
为什么这有效?
修改
The generic implementation is not even necessary:
public interface IA
{
public void print(String arg);
}
public interface IB
{
public void print(String arg);
}
public class Test implements IA, IB
{
@Override
public void print(String arg);
{
// print arg
}
}
答案 0 :(得分:3)
不,你不能。请参阅Joshua Bloch和Neal Gafter撰写的“Java Puzzlers:陷阱,陷阱和角落案例”,Puzzle 37 Exceptionally Arcane:现在我可以将UserLogic转换为两个接口中的任何一个并检索一个 不同的例外情况!
每个接口都限制方法可以执行的已检查异常集 扔。方法可以抛出的一组已检查异常是 声明它的已检查异常集的交集 扔掉所有适用的类型,而不是工会。
所以在你的案例实现中
create(用户用户)抛出ExceptionInherit
是对的。但
create(用户用户)抛出ExceptionSuper
不会编译
答案 1 :(得分:2)
由于ExceptionInherit
扩展ExceptionSuper
,您不会收到不同的例外情况。但请考虑一下:
interface X {
public void foo() throws ExceptionA;
}
interface Y {
public void foo() throws ExceptionB;
}
class ExceptionA extends Exception {}
class ExceptionB extends Exception {}
class Z implements X, Y {
public void foo() throws ExceptionA {
}
}
请注意ExceptionA
和ExceptionB
未通过继承进行连接。在这种情况下,您将收到编译错误,因为ExceptionA
与throws
中的Y
子句不兼容。
答案 2 :(得分:1)
没有通用,它也可以工作,没有例外。甚至可以追溯到Java 1.4,也可能在之前。
我一直认为具有相同方法的两个接口不能被一个类继承,正如很多问题所述。
实际上这不是真的,我不确定你指的是什么问题。
当然有理由不使用具有相同方法签名的两个接口,最重要的一个是实现只能做一件事,所以如果两个接口都期望从方法得到不同的结果,你将无法满足两个接口,但这不会是编译错误。
还有一些原因使得具有相同方法的2个接口完全有效。如果2个接口相互扩展,则实现可以很好地实现两个接口。即使在接口只是共享名称的简单情况下,也没有技术限制。
接口只请求某些方法可用,它不要求其他接口不存在。
有效代码:
public interface IDo {
public void does();
}
public interface ITwo {
public void does();
}
public class Test implements IDo, ITwo {
public void does() {
}
}
答案 3 :(得分:1)
I always thought that two interfaces with the same method cannot
be inherited by one class, as stated in many so questions.
如果你想更精确,你应该用“具有覆盖等效签名的方法”替换“相同方法”。签名是“方法名称”+“参数列表”(某些规则也适用于返回类型和throws子句)。你需要知道覆盖等价的确切含义。
如果一个类使用这样的方法实现两个或更多接口,那就完全没问题了:
1-它们都具有相同的返回类型,或者其中一个方法的返回类型是所有其他方法的子类型。这是您应该在实现中使用的返回类型。
例如:
interface A {
Integer x();
}
interface B {
Number x();
}
interface C {
Object x();
}
class Foo implements A, B, C
{
Integer x() {
//...
}
}
和
2-实现必须满足每个超级接口声明的所有此类方法的throws子句。
所以你给出的例子都遵循这些规则,并且完全没问题。
答案 4 :(得分:0)
你绝对可以“实现”两个具有相同签名方法的接口。您在尝试“扩展”具有相同方法实现的两个类时遇到了麻烦。多接口继承是好的;多实现继承是TRICKY。
可以使用“ExceptionInherit”对象代替“ExceptionSuper”对象,因为它继承了它。 “ExceptionInherit”对象具有“ExceptionSuper”对象所具有的所有信息(以及更多)。反之亦然。您不能使用“ExceptionSuper”对象代替“ExceptionInherit”对象,因为“ExceptionInherit”代码需要的内容多于您的基础对象(嗯,可能但不是您的情况)。
你的“create”方法的实现填充了ICreateUser“create”签名,因为它抛出了一个“ExceptionInherit”,可以抛出“ExceptionInherit”和“ExceptionSuper”的捕获者获取他们需要的所有信息(只是基础)来自对象的。)
你无法改变你的实现以抛出“ExceptionSuper”,因为捕获者期望“ExceptionInherit”会得到一个信息不足的对象。