使用子类异常

时间:2017-01-29 10:34:58

标签: java oop generics polymorphism

据我了解,实现接口的类可以使用接口中定义的类的子类,而不仅仅是能够使用此特定类。

这是我的意思的一个例子:假设以下代码

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

中使用的泛型,以下Java代码是有效的
public class TestImplementation extends TestChildAbstractClass {

    public void test(TestChildClass top) {
        System.out.println("tested");
    }
}

但是Java抱怨

  

test(T)中定义的抽象方法TestInterface未实现。

这个有效的OOP不适用吗?

3 个答案:

答案 0 :(得分:3)

您缺少指定Tpublic 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> {}