Reassigning non-generic methods with a generic method

I want to do auto-casting views in my android project. So, I want to override

View findViewById(int id) {...}

      

method

<T extends View> findViewById(int id) {...}

      

method. But java compilation does not allow this, however the overridden method does not conflict with the parent and always returns the view object or its children. I found some information that java does not allow overriding non-generic methods with generic methods, but I cannot find an explanation as to why this is the case.

http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ824 This FAQ says it's not possible, but I can't figure out why. As an example, we have the following classes:

class Super { 
  public void set( Object arg) { ... } 
  public Object get() { ... } 
} 
class Sub extends Super {  
  public <S extends Number> void set( S arg) { ... } // overloads 
  public <S extends Number> S get() { ... } // overloads 
}

      

The FAQ says they should compile with overload, but I have a strange thing: getter returns the same error as my findViewById, but the collector compiles without errors.

Can anyone explain this thing to me? Why does java not allow overrides not common to common and why is setter compiled, getter is no?

I know that I can use some other method like

<T extends View> findView(int id){
  return (T) findViewById(id);
}

      

or

<T extends View> findView(int id, Class<T> clazz) {
  return clazz.cast(findViewById(id));
}

      

But I want to understand why I should use a new method instead of overriding?

//1
@Override
public View findViewById(int id) {
    return (View) super.findViewById(id);
}
//2
@Override
public <T extends View> T findViewById(int id) {
    return (T) super.findViewById(id);
}

      

So, at compile time, what is the difference between 1 and 2? Even method 1 is more general than method 2.

//3
@Override
public <T extends View> View findViewById(int id) {
    return (View) super.findViewById(id);
}

      

After adding the method as described above, I finally realized that "T extends View" tells the compiler that this is not the same method as without "T extends View". So, actually, I created a new method, but with the same name and parameters, so it can't compile. Maybe this is not entirely correct, but, as I understand it, something similar to the truth.

Thanks to everyone who is trying to help me.

+3


source to share


1 answer


The method set

in is Sub

compiled because you declare a method called newset

that can take any arguments S that extends Number

.. Note that you are not overriding the set method from the Super class in the Sub class, you have overloaded the set method
With the method get

you do the same, for example overload the get method, but this time the compiler is complaining because it is invalid because you only changed the return type of the method. Ex.

public Object get() {
    return null;
}

      

and you are declaring another method in the same or child class, changing only the return type of the method like this

    public Number get() {
        return null;
    }

      

then the compiler will complain "get () method is already defined" because in java the return type is not part of the method signature.
You can replicate the same problem for a method set

if you declare



public <S extends Number> void set( Object arg) {  }

      

In this case again, we just change the return type of the method, but in order to be a valid parameter of the overload method, it must be different, so

public <S extends Number> void set( String arg) {  } // overloads

      

will be a valid overload

+1


source







All Articles