据我了解,实现接口的类可以使用接口中定义的类的子类,而不仅仅是能够使用此特定类。
这是我的意思的一个例子:假设以下代码
public abstract class TestRootAbstractClass implements TestInterface {}
和
public abstract class TestChildAbstractClass extends TestRootAbstractClass {}
TestInterface
中定义的TestRootAbstractClass
看起来像这样
public interface TestInterface<T extends TestRootClass> {
void test(T extendedTestClass) throws Exception;
}
TestRootClass
中引用的TestInterface
看起来像这样
public abstract class TestRootClass {}
此类还有一个看起来像这样的子类
public class TestChildClass extends TestRootClass {}
我认为由于TestInterface
public class TestImplementation extends TestChildAbstractClass {
public void test(TestChildClass top) {
System.out.println("tested");
}
}
但是Java抱怨
test(T)
中定义的抽象方法TestInterface
未实现。
这个有效的OOP不适用吗?
答案 0 :(得分:3)
您缺少指定T
中public abstract class TestRootAbstractClass implements TestInterface {}
的内容。因此T
默认为TestRootClass
,这意味着TestImplementation
无法正确实现接口TestChildAbstractClass
,因为仅允许TestChildClass
个参数,但没有TestRootClass
的其他子类。
您应该指定它或让TestRootAbstractClass
的子类执行此操作。以下是后者,编译得很好:
abstract class TestRootAbstractClass<T extends TestRootClass> implements TestInterface<T> {}
abstract class TestChildAbstractClass<T extends TestRootClass> extends TestRootAbstractClass<T> {}
interface TestInterface<T extends TestRootClass> {
void test(T extendedTestClass) throws Exception;
}
abstract class TestRootClass {}
class TestChildClass extends TestRootClass {}
class TestImplementation extends TestChildAbstractClass<TestChildClass> {
public void test(TestChildClass top) {
System.out.println("tested");
}
}
或者您更改TestImplementation
中的方法以接受所有TestRootClass
es。
abstract class TestRootAbstractClass implements TestInterface {}
abstract class TestChildAbstractClass extends TestRootAbstractClass{}
interface TestInterface<T extends TestRootClass> {
void test(T extendedTestClass) throws Exception;
}
abstract class TestRootClass {}
class TestChildClass extends TestRootClass {}
class TestImplementation extends TestChildAbstractClass {
public void test(TestRootClass top) {
System.out.println("tested");
}
}
但现在你可以将所有的泛型放在一起,只需使用:
interface TestInterface {
void test(TestRootClass extendedTestClass) throws Exception;
}
答案 1 :(得分:0)
public abstract class TestRootAbstractClass implements TestInterface {}
由于您尚未为TestInterface
指定类型参数,因此TestRootAbstractClass
中的方法将具有以下签名:
public abstract void test(TestRootClass extendedTestClass) throws Exception;
因为没有覆盖此方法签名,所以它会抱怨。
看起来您需要将类型参数添加到层次结构中的所有相关类,以便它可以按照您的意愿执行。
答案 2 :(得分:0)
您的界面TestInterface是通用的;使用泛型类型T扩展TestRootClass。当你让一个类实现它们时,你有3个选择。
1)失去通用性:java会将默认值解析为Object
public abstract class TestChildAbstractClass implements TestInterface {}
2)保持Généricity。所以实现接口的新类应该是généric。
public abstract class TestChildAbstractClass<P extends TestRootClass> implements TestInterface<P> {}
3)Spécifygénéric类型。所以你的新班级有明确定义的généric类型:
public abstract class TestChildAbstractClass implements TestInterface<TestChildClass> {}