I want to make automation casting of views in my android project. So, I want to override
View findViewById(int id) {...}
method by
<T extends View> findViewById(int id) {...}
method. But java compilation does not allow this, however overridden method does not conflict with parental and always will return object of view or its childs. I found some info, that java does not allow overriding non-generic methods by generic methods, but explanation why is is I can't find.
http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ824 This FAQ says that it is impossible, but I can't understand why. As example we have such 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
}
FAQ says that they should compile with overloading, but I have strange thing: getter returns the same error as my findViewById, but setter compile without errors.
Could someone explain me this thing? Why does java not allow to override non-generic by generic and why setter compiled, getter - no ?
I know, that I can use some another method, for example
<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 should I use 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, during the compilation time, what is the difference between 1 and 2 ? Even method 1 is more general, than 2.
//3
@Override
public <T extends View> View findViewById(int id) {
return (View) super.findViewById(id);
}
After I added method as above, I finally realised, that "T extends View" tells compiler, that it is not the same method as without "T extends View". So, in fact, I created new another method, but with the same name and parameters, so it can't compile. Maybe it is not exactly correct, but as I understood - something similar to true.
Thank you all, who try to help me.
The set method in Sub compiles because you are declaring a new method called set that can take any argument S that extends Number. .Note you are not overriding the set method from the Super class in Sub class you have overloaded the set method.
With get method your are doing exactly the same i.e. overloading get method but this time compiler complains because it is not valid because you changed just the return type of the method. For e.g.
public Integer get() {
return null;
}
and you declare another method in the same or child class by changing just the return type of the method like this
public Double get() {
return null;
}
then compiler will complain "attempting to use incompatible return type" because in java return type is not the part of the method signature.
You can replicate the same problem for set method 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 to be valid overload method parameters should be different so
public <S extends Number> void set(String arg) { } // overloads
will be a valid overload.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With