1

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? e.g

removeItem(<? extends GeneralItem> item, String reason);
4
  • 2
    What would happen if you pass it an OtherSpecificItemThatExtendsGeneralItem? Commented Feb 11, 2015 at 20:48
  • That would never happen Commented Feb 11, 2015 at 20:53
  • But what if someone else wrote that code and made it happen? Commented Feb 11, 2015 at 20:53
  • I'd slap them? No I don't think that's the corrrect answer... Commented Feb 11, 2015 at 21:04

4 Answers 4

2

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.

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>:

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

though it is compatible with MyAbstractClass<?> and MyAbstractClass<SpecificItemThatExtendsGeneralItem>:

MyAbstractClass<?> c = new MySubclass();  // ok
MyAbstractClass<SpecificItemThatExtendsGeneralItem> = new MySubclass(); // ok
Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

0

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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.