Page 1 of 2 12 LastLast
Results 1 to 20 of 25
Like Tree2Likes

Thread: Implementation advice (instanceof and interaction between subclasses)

  1. #1
    Diargg is offline Senior Member
    Join Date
    Feb 2012
    Posts
    117
    Rep Power
    0

    Default Implementation advice (instanceof and interaction between subclasses)

    I always see people railing on using instanceof as an example of poor OOP. I completely understand the argument, but the examples used are typically ones involving fairly shallow polymorphism (Animal.go(), animal.talk(), etc.)

    When it comes to cases of interaction between the various subclasses, can instanceof be considered more acceptable? To continue the animal analogy, let's look at

    Animal_A.eat(Animal_B);

    If we say that dogs eat cats, cats eat rats, and rats eat dogs (they're huge), is there a good implementation that doesn't say

    if(Animal_B instanceof Cat) Animal_B.die();?

    I could use some kind of enum Type{CAT, RAT, DOG}, but that seems to just be duplicating instanceof in more lines of code.

    Any advice?

  2. #2
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,452
    Rep Power
    20

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    Method overloading? Maybe something like
    Java Code:
    //Animal, abstract class
       public boolean eat(Animal other) {
          die();
          return false;
       }
    
    // Dog extends Animal
       public boolean eat(Cat other) {
          System.out.println("yum!"); // poor Cat
          return true;
       }
    
    // Cat extends Animal
       public boolean eat(Rat other) {
          System.out.println("yum!"); // good riddance
          return true;
       }
    
    // Rat extends Animal
       public boolean eat(Dog other) {
          System.out.println("yum!"); // BURP
          return true;
       }
    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  3. #3
    Diargg is offline Senior Member
    Join Date
    Feb 2012
    Posts
    117
    Rep Power
    0

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    That looks like exactly what I was thinking of - I didn't think to check if Java could overload with more specific sub classes, I figured it would only overload eat(Animal a);. I presume then that in your example, Cat_C.eat(Dog_D); would trigger die(); and return false? Thank you very much!

  4. #4
    Diargg is offline Senior Member
    Join Date
    Feb 2012
    Posts
    117
    Rep Power
    0

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    Db -

    So I finished up the testing portions of my program. As far as I can tell, Java does not selectively choose between "better" and "worse" overloads. I appreciate the help though.

  5. #5
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,452
    Rep Power
    20

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    Quote Originally Posted by Diargg View Post
    Db -

    So I finished up the testing portions of my program. As far as I can tell, Java does not selectively choose between "better" and "worse" overloads. I appreciate the help though.
    What exactly do you mean by "better" and "worse" overloads? It's not any terminology I've heard before.

    Read the rules of method overloading here: Chapter*8.*Classes

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  6. #6
    Diargg is offline Senior Member
    Join Date
    Feb 2012
    Posts
    117
    Rep Power
    0

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    Sorry, I wan't specific. What you suggested does not work - you cannot overload with different class types, even if they subclass. At least, Eclipse doesn't do it in JRE1.7

  7. #7
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,452
    Rep Power
    20

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    you cannot overload with different class types, even if they subclass.
    Rubbish. You're doing something else wrong. Copy this and save it as Animal.java, then compile and execute it.
    Java Code:
    public abstract class Animal {
    
      public boolean eat(Animal other) {
        die();
        return false;
      }
    
      private void die() {
        System.out.println("RIP");
      }
    
      protected void yum() {
        System.out.println("YUM");
      }
    
      public static void main(String[] args) {
        Dog dog = new Dog();
        Cat cat = new Cat();
        Rat rat = new Rat();
    
        System.out.print("Dog eat Cat: ");
        dog.eat(cat);
        System.out.print("Dog eat Rat: ");
        dog.eat(rat);
    
        System.out.print("Cat eat Rat: ");
        cat.eat(rat);
        System.out.print("Cat eat Dog: ");
        cat.eat(dog);
    
        System.out.print("Rat eat Dog: ");
        rat.eat(dog);
        System.out.print("Rat eat Cat: ");
        rat.eat(cat);
    
      }
    }
    
    class Dog extends Animal {
    
      public boolean eat(Cat other) {
        yum();
        return true;
      }
    }
    
    class Cat extends Animal {
    
      public boolean eat(Rat other) {
        yum();
        return true;
      }
    }
    
    class Rat extends Animal {
    
      public boolean eat(Dog other) {
        yum();
        return true;
      }
    }
    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  8. #8
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,732
    Blog Entries
    7
    Rep Power
    21

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    Yes, that works because the compiler 'knows' that a dog is a Dog and a cat is a Cat etc. If that dog, cat etc. would've been of class Animal the compiler would generate a call to the superclass method instead for all cases. Method overloading is compiler thing.

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  9. #9
    Diargg is offline Senior Member
    Join Date
    Feb 2012
    Posts
    117
    Rep Power
    0

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    Quote Originally Posted by JosAH View Post
    Yes, that works because the compiler 'knows' that a dog is a Dog and a cat is a Cat etc. If that dog, cat etc. would've been of class Animal the compiler would generate a call to the superclass method instead for all cases. Method overloading is compiler thing.

    kind regards,

    Jos
    Which would explain why

    Java Code:
    Dog dog = new Dog();
    		Cat cat = new Cat();
    		Rat rat = new Rat();
    		
    		Animal[] ark = {new Dog(), new Cat(), new Rat()};
    		ark[0].eat(ark[1]);
    		ark[0].eat(cat);
    results in RIP RIP. Makes sense I suppose. So in the above example, would you suggest using instanceof?

  10. #10
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,732
    Blog Entries
    7
    Rep Power
    21

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    Quote Originally Posted by Diargg View Post
    Which would explain why

    Java Code:
    Dog dog = new Dog();
    		Cat cat = new Cat();
    		Rat rat = new Rat();
    		
    		Animal[] ark = {new Dog(), new Cat(), new Rat()};
    		ark[0].eat(ark[1]);
    		ark[0].eat(cat);
    results in RIP RIP. Makes sense I suppose. So in the above example, would you suggest using instanceof?
    Probably; but I'd do it in the Dog, Cat, Rat classes themselves; e.g. the eat(Animal victim) method in the Dog class could look like this:

    Java Code:
    public boolean eat(Animal victim) {
       boolean edible= victim instanceof Cat;
       if (edible)
          yum();
       else
          die();
       return edible;
    }
    the inherited methods in the other classes are similar.

    kind regards,

    Jos
    Diargg likes this.
    cenosillicaphobia: the fear for an empty beer glass

  11. #11
    Diargg is offline Senior Member
    Join Date
    Feb 2012
    Posts
    117
    Rep Power
    0

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    Ok, that's how I've been doing it. Guess that's something of an affirmation! You've been a great help, thanks.

  12. #12
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,185
    Rep Power
    20

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    Java Code:
    public abstract class Animal {
       protected Set<Class> edible = new HashSet<Class>();
    
       public boolean eat(Animal other) {
          if (edible.contains(other.getClass())) {
             yum();
             return true;
          }
          die();
          return false;
       }
    
       private void die() {
          System.out.println("RIP");
       }
    
       protected void yum() {
          System.out.println("YUM");
       }
    
       public static void main(String[] args) {
          Dog dog = new Dog();
          Cat cat = new Cat();
          Rat rat = new Rat();
          System.out.print("Dog eat Cat: ");
          dog.eat(cat);
          System.out.print("Dog eat Rat: ");
          dog.eat(rat);
          System.out.print("Cat eat Rat: ");
          cat.eat(rat);
          System.out.print("Cat eat Dog: ");
          cat.eat(dog);
          System.out.print("Rat eat Dog: ");
          rat.eat(dog);
          System.out.print("Rat eat Cat: ");
          rat.eat(cat);
       }
    }
    
    class Dog extends Animal {
       public Dog() {
          this.edible.add(Cat.class);
       }
    }
    
    class Cat extends Animal {
       public Cat() {
          this.edible.add(Rat.class);
       }
    }
    
    class Rat extends Animal {
       public Rat() {
          this.edible.add(Dog.class);
       }
    }
    :)
    Diargg likes this.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  13. #13
    Diargg is offline Senior Member
    Join Date
    Feb 2012
    Posts
    117
    Rep Power
    0

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    Very nice. Did not even think of that one. Thanks!

  14. #14
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,732
    Blog Entries
    7
    Rep Power
    21

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    Cool; instead of doing an instanceof test we do a set presence test ... plus an entire set per class. ;-)

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  15. #15
    Diargg is offline Senior Member
    Join Date
    Feb 2012
    Posts
    117
    Rep Power
    0

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    Quote Originally Posted by JosAH View Post
    Cool; instead of doing an instanceof test we do a set presence test ... plus an entire set per class. ;-)

    kind regards,

    Jos
    Indeed - from a performance standpoint it does not strike me as the most efficient solution. However, it could have merits - let's say there was a Animal.Hunt() method that searched out it's prey? The set could certainly be used elsewhere.

  16. #16
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,185
    Rep Power
    20

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    Quote Originally Posted by JosAH View Post
    Cool; instead of doing an instanceof test we do a set presence test ... plus an entire set per class. ;-)

    kind regards,

    Jos
    Actually, it's an entire Set per instance of a class...:)
    Never do things by halves, that's what I say.

    It's not actually intended as a serious answer, but more to highlight the inheritance here.
    As in, the inheritance is an illusion largely due to the simplicity of the problem, hence the problem surrounding how to get animal A to eat animal B without doing instanceof or class comparisons. And the answer is to provide data (attributes) to Animal that allow it to identify predator/prey. Not to subclass Animal.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  17. #17
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,185
    Rep Power
    20

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    Hit Reply too soon!

    Then end result would be something akin to an AnimalSpecies.
    Individual Animals would have an AnimalSpecies.
    The Species defines what other Species it can eat or be eaten by.

    Composition.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  18. #18
    Diargg is offline Senior Member
    Join Date
    Feb 2012
    Posts
    117
    Rep Power
    0

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    So Tolls, you would suggest having
    Java Code:
    Animal dog = new Animal(new AnimalSpecies(AnimalSpecies.DOG));
    //DOG is enum in Species, Animal declaration takes a type of species and works with it
    I'm not entirely sure though where down the rabbit's hole you escape doing set- or instanceof-based class comparisons

  19. #19
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,185
    Rep Power
    20

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    Not Enums (unless you really know this is a fixed set of Species).
    You'd have 3 instances (in your case) of an AnimalSpecies class.
    Each instance would hold references to the species it could eat.

    You would then have any number of instances of Animal class, each of which would hold a reference to one of the AnimalSpecies objects.

    Figuring who could eat who then would be easy:
    Java Code:
    public boolean eat(Animal other) {
        if (this.animalSpecies.canEat(other.getAnimalSpecies())) {
            yum();
            return true;
        } else {
            die();
            return false;
        }
    }
    canEat(AnimalSpecies) simply does a check on the Set<AnimalSpecies> of things that species can eat, similar to the one I have above involving Class.

    That shoudl strip out the need to know Classes, and makes (in my mind) a neater model.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  20. #20
    Diargg is offline Senior Member
    Join Date
    Feb 2012
    Posts
    117
    Rep Power
    0

    Default Re: Implementation advice (instanceof and interaction between subclasses)

    Tolls,
    At what point does this simplicity break down though? What separates this from just being a fancier implementation of instanceof? Outside of some scalability benefits, I'm somewhat lost.

Page 1 of 2 12 LastLast

Similar Threads

  1. need help with subclasses
    By thorobred in forum New To Java
    Replies: 6
    Last Post: 02-19-2011, 06:34 AM
  2. instanceof
    By AedonetLIRA in forum New To Java
    Replies: 3
    Last Post: 12-01-2010, 01:34 AM
  3. Class, SubClass type (InstanceOf) Question
    By indyjoel in forum New To Java
    Replies: 6
    Last Post: 11-07-2010, 04:55 AM
  4. Use of keyword instanceof
    By darek9576 in forum New To Java
    Replies: 3
    Last Post: 03-14-2010, 11:35 PM
  5. super instanceof Class?
    By mikeiz404 in forum New To Java
    Replies: 11
    Last Post: 01-23-2009, 08:23 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •