2015-02-11 92 views
1

比方说,我已经叫一个抽象类,它有这个抽象方法方法声明中通用

removeItem(GeneralItem item, String reason); 

但随后在子类中我有

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

我如何使它所以第二的removeItem算作第一个的执行?例如

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

如果将它传递给OtherSpecificItemThatExtendsGeneralItem会发生什么? – immibis 2015-02-11 20:48:19

+0

这绝不会发生 – 2015-02-11 20:53:14

+0

但是,如果其他人编写该代码并实现它,该怎么办? – immibis 2015-02-11 20:53:53

回答

2

具有方法签名......

removeItem(SpecificItemThatExtendsGeneralItem item, String reason) 

... 实现...因为后者可以接受任何,包括那些不是SpecificItemThatExtendsGeneralItem

如果你可以改变抽象类,但是,那么你可以把它可能:

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) { 
     // ... 
    } 
} 

在这种情况下,但是,请注意,类型MySubclass然后仍然不符合MyAbstractClass<GeneralItem>

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

虽然它是MyAbstractClass<?>MyAbstractClass<SpecificItemThatExtendsGeneralItem>兼容:

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

很好的解释。 – StuPointerException 2015-02-11 21:15:39

0

子类不能改变它们在方法中接受的类型。但是你绝对可以检查类型是你所期望的:

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

然而,这不会在编译时检查,仅仅是因为当有人打电话

abstractClassInstance.removeItem(OtherSpecificItemThatExtendsGeneralItem) 

编译器没办法知道这应该失败,它不知道哪个实现abstractClassInstance实际上是。

0

这是不可能的。

的方法:

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

不包括打电话,你希望它覆盖的方法的所有有效途径。因此,有一个类(仅)实现此方法不会实现父类的合同。

1

如果你可以改变的基类,可以概括第一个参数:

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

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