简体   繁体   English

方法声明中的通用

[英]Generic within method declaration

Let's say I have an abstract class called which has this abstract method 假设我有一个抽象类,它有这个抽象方法

removeItem(GeneralItem item, String reason);

but then in a subclass I have 但后来我在一个子类中

removeItem(SpecificItemThatExtendsGeneralItem item, String reason){ //code }

How do I make it so the second removeItem counts as an implementation of the first? 我该怎么做才能使第二个removeItem算作第一个的实现? eg 例如

removeItem(<? extends GeneralItem> item, String reason);

A method having signature ... 一种有签名的方法......

removeItem(SpecificItemThatExtendsGeneralItem item, String reason)

... does not implement ... ...... 没有实施......

removeItem(GeneralItem item, String reason)

... because the latter can accept any GeneralItem , including those that are not SpecificItemThatExtendsGeneralItem . ...因为后者可以接受任何GeneralItem ,包括那些不是SpecificItemThatExtendsGeneralItem

If you can alter the abstract class, however, then you can make it possible: 但是,如果您可以更改抽象类,那么您可以使其成为可能:

abstract class MyAbstractClass <T extends GeneralItem> {
    abstract public void removeItem(T item, String reason);
}

class MySubclass extends MyAbstractClass<SpecificItemThatExtendsGeneralItem> {
    @Override
    public void removeItem(SpecificItemThatExtendsGeneralItem item,
            String reason) {
        // ...
    }
}

In that case, however, note that type MySubclass is then still incompatible with MyAbstractClass<GeneralItem> : 但是,在这种情况下,请注意MySubclass类型仍然与MyAbstractClass<GeneralItem>不兼容:

MyAbstractClass<GeneralItem> = new MySubclass();  // ERROR

though it is compatible with MyAbstractClass<?> and MyAbstractClass<SpecificItemThatExtendsGeneralItem> : 虽然它与MyAbstractClass<?>MyAbstractClass<SpecificItemThatExtendsGeneralItem>兼容:

MyAbstractClass<?> c = new MySubclass();  // ok
MyAbstractClass<SpecificItemThatExtendsGeneralItem> = new MySubclass(); // ok

If you can change base class, you can generalize the first parameter: 如果可以更改基类,则可以概括第一个参数:

class BaseClass<T extends GeneralItem> {
    void removeItem(T item, String reason) {
    }
}

class SubClass extends BaseClass<SpecificItemThatExtendsGeneralItem> {
    @Override
    void removeItem(SpecificItemThatExtendsGeneralItem item, String reason) {
    }
}

Subclasses cannot change the type they accept in methods. 子类不能更改它们在方法中接受的类型。 But you can definitely check if the type is what you expect: 但你绝对可以检查类型是否符合预期:

removeItem(GeneralItem item, String reason)
{
    if (!(item instanceof SpecificItemThatExtendsGeneralItem))
        throw InvalidArgumentException("Only SpecificItemThatExtendsGeneralItem accepted");
}

However, this would not be checked during compilation time, simply because when someone would call 但是,在编译期间不会检查这一点,只是因为当有人打电话时

abstractClassInstance.removeItem(OtherSpecificItemThatExtendsGeneralItem)

the compiler has no way of knowing that this should fail, it does not know which implementation abstractClassInstance is actually of. 编译器无法知道这应该失败,它不知道abstractClassInstance实际上是哪个实现。

It's not possible. 这是不可能的。

The method: 方法:

removeItem(SpecificItemThatExtendsGeneralItem item, String reason){ //code }

does not cover all valid ways of calling the method that you're hoping it overrides. 并未涵盖调用您希望覆盖的方法的所有有效方法。 Therefore having a class that (just) implements this method does not fulfil the contract of the parent class. 因此,拥有一个(只)实现此方法的类不符合父类的约定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM