java - Method chaining + inheritance don’t play well together? -


this question has been asked in c++ context i'm curious java. concerns virtual methods don't apply (i think), if have situation:

abstract class pet {     private string name;     public pet setname(string name) { this.name = name; return this; }         }  class cat extends pet {     public cat catchmice() {          system.out.println("i caught mouse!");          return this;      } }  class dog extends pet {     public dog catchfrisbee() {          system.out.println("i caught frisbee!");          return this;      } }  class bird extends pet {     public bird layegg() {         ...         return this;     } }   {     cat c = new cat();     c.setname("morris").catchmice(); // error! setname returns pet, not cat     dog d = new dog();     d.setname("snoopy").catchfrisbee(); // error! setname returns pet, not dog     bird b = new bird();     b.setname("tweety").layegg(); // error! setname returns pet, not bird } 

in sort of class hierarchy, there way return this in way doesn't (effectively) upcast the object type?

if want avoid unchecked cast warnings compiler (and don't want @suppresswarnings("unchecked")), need little more:

first of all, definition of pet must self-referential, because pet generic type:

abstract class pet <t extends pet<t>> 

secondly, (t) this cast in setname unchecked. avoid this, use "getthis" technique in excellent generics faq angelika langer:

the "getthis" trick provides way recover exact type of reference.

this results in code below, compiles , runs without warnings. if want extend subclasses, technique still holds (though you'll need genericise intermediate classes).

the resulting code is:

public class testclass {    static abstract class pet <t extends pet<t>> {     private string name;      protected abstract t getthis();      public t setname(string name) {       this.name = name;       return getthis(); }     }    static class cat extends pet<cat> {     @override protected cat getthis() { return this; }      public cat catchmice() {       system.out.println("i caught mouse!");       return getthis();     }   }    static class dog extends pet<dog> {     @override protected dog getthis() { return this; }      public dog catchfrisbee() {       system.out.println("i caught frisbee!");       return getthis();     }   }    public static void main(string[] args) {     cat c = new cat();     c.setname("morris").catchmice();     dog d = new dog();     d.setname("snoopy").catchfrisbee();   } } 

Comments

Popular posts from this blog

qt - Using float or double for own QML classes -

Create Outlook appointment via C# .Net -

ios - Swift Array Resetting Itself -