Lisa Anne
Lisa Anne

Reputation: 4595

Using subtype for parameter in method override

public abstract class SequenceItemHolder {

    public SequenceItemHolder(View itemView) {
    }

    public abstract void setData(SequenceRowElement.RowElement rowElement);


        public static class TesteItemHolder extends SequenceItemHolder {

        public TesteItemHolder(View itemView) {
        }

        @Override
        public void setData(SequenceRowElement.TestRowElement rowElement) {
        }
   }
}

Please can somebody explain me why do I get a compile error in the override?

Please how to fix it (without using an interface)?


NOTE: TestRowElement extends RowElement

Upvotes: 3

Views: 643

Answers (4)

something like this:

    public abstract class SequenceItemHolder {

    public SequenceItemHolder(View itemView) {
    }

    public abstract void setData(SequenceRowElement.RowElement rowElement);

    public static class TesteItemHolder extends SequenceItemHolder {

        public TesteItemHolder(View itemView) {
            super(itemView);
        }

        @Override
        public void setData(SequenceRowElement.RowElement rowElement) {          
        }
    }
}

Upvotes: 1

Jiri Tousek
Jiri Tousek

Reputation: 12440

This is about what's formally called covariance and contravariance.

Simply put, if you have a type hierarchy of Animal > Mammal > Dog, and the base method

Mammal foo(Mammal arg)

these are allowed as overrides:

  • Mammal foo(Mammal arg)
    
  • Mammal foo(Animal arg)
    
  • Dog    foo(Mammal arg)
    
  • Dog    foo(Animal arg)
    

That is, you can widen the parameter type (allowing more general input in the subclass' method) and narrow down the returned value (declaring that you will return a more specific type).

The reason is, the caller must be able to call the overriden method using the original signature - so the subclass method cannot have more specific parameters nor more general return value. In the example above, the caller must be able to call foo with parameter of type Mammal and the return value must be a Mammal - the parameter in subclass method therefore may be Mammal or Animal (both will accept an actual parameter of type Mammal), and may return a Mammal or a Dog (both can be stored in a variable of type Mammal).

Upvotes: 2

Jörn Buitink
Jörn Buitink

Reputation: 2916

You are not overwriting the method ( = same method signature), you are overloading it (= same method name, different parameters)

public abstract void setData(SequenceRowElement.RowElement rowElement) {}

@Override
public void setData(SequenceRowElement.TestRowElement rowElement) {
}

Your first function (in SequenceItemHolder) takes a SequenceRowElement.RowElementas parameter, your second function takes a SequenceRowElement.TestRowElement. Therefore, @Override is wrong.

Upvotes: 2

Stultuske
Stultuske

Reputation: 9437

Error 1

public SequenceItemHolder(View itemView) {
    super(itemView);
    }

Object doesn't have a constructor taking a View as parameter. Remove the super call.

Error 2

public abstract void setData(SequenceRowElement.RowElement rowElement) {}

abstract methods should not have a body. replace it with this:

public abstract void setData(SequenceRowElement.RowElement rowElement);

Error 3

Your overriden method should have the same parameter type as the abstract one.

Upvotes: 5

Related Questions