When declaring a method for chained calls usually it returns this
at the end of the method.
So I declare:
public class Foo {
public Foo setTitle(String title){
...
return this;
}
}
And:
public class Bar extends Foo{
/* OTHER STUFF */
}
If you call new Bar().setTitle("Test")
it returns a Foo
's reference.
Is possible to declare the method in order to return automatically a Bar
's reference without override the method in Bar for clarity, brevity and maintainability?
Thanks
Is possible to declare the method in order to return automatically a Bar's reference without override the method in Bar for clarity, brevity and maintainability?
No. You could hook up some weird generics - Foo<T extends Foo>
or the like - but it wouldn't be very satisfactory.
Basically there's need to be some language support for "this type", where the only valid expressions of that type were null
and this
. That doesn't exist, so you're left with overriding:
public Bar setTitle(String title) {
super.setTitle(title);
return this;
}
Or:
public Bar setTitle(String title) {
return (Bar) super.setTitle(title);
}
It's just one of those cases where inheritance ends up being a pain :(
I did try with generics...
public class Foo<T extends Foo> {
public T setTitle(String title){
.....
return (T) this;
}
}
public class Bar extends Foo<Bar>{
/* OTHER STUFF */
}
Seems to work.
I think its actullay returning Bar
Only. Just do the type casting to reference the object as Bar
as below:
Bar bar = (Bar)(new Bar().setTitle("Foo Title"));
System.out.println(bar.getTitle());//prints Foo Title
Assuming getTitle()
method present in Foo
returning the title.
If you add another method eg getBarTitle
in Bar
class:
public String getBarTitle(){
return getTitle()+" of Bar";
}
then
System.out.println(bar.getBarTitle());//prints Foo Title of Bar
Explanation: When you are calling setTitle
on new Bar()
, the method is called on Bar
Object and this
is representing Bar
object not Foo
, hence it returns Bar
onject only with class type as Foo
, which is super class. In this process, it doesn't change the original class type, which is bar at all, hence the type casting should serve the purpose for you.
You can use generics with upper bounds:
public class Foo<T extends Foo<T>> {
public T setTitle() {
...
return (T) this;
}
}
public class Bar extends Foo<Bar> {
....
}
To be precide, it does not return a Foo reference, it returns a Bar reference, you can check by using System.out.println(reference.getClass().getName()).
In the same way when you write,
List l=new ArrayList();
(forget about LIst being an interface, it is beside the point)
l
is actually a reference to ArrayList even if this information is "hidden", but calling l.someMathod() calls ArrayList methods, not List methods - that's how Object Orientation works!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.