2

I'm sure this is incredibly common with as OOP centered as Java is. In java is there a way to make a base type variable that accepts all inherited subtypes? Like if I have;

class Mammal {...}
class Dog extends Mammal {...}
class Cat extends Mammal {...}

class ABC {
    private Mammal x;

    ABC() {
        this.x = new Dog();
        -or-
        this.x = new Cat();
    }
}

I need the variable to be able to accept any extended version too, but not in specific one extended kind.

There are some ways that I know, but don't want to use. I could make an attribute for each subtype, then only have the one attribute actually used. Make an array and shove it in there.

Any other ideas or a way to get a "base class" type variable?


Ok since I know using polymorphic duck typing isn't a great idea in Java, but since I don't think I can avoid it. Is the only way to use subclass methods dynamically to re assign a casted version of the varible ie, I get an error with this;

Mammal x;
x = new Dog();
System.out.println(x.getClass());
x.breath();
if (x instanceof Dog) {
  x.bark();
} else if (x instanceof Cat) {
  x.meow();
}

Saying symbol not found, however this works;

Mammal x;
x = new Dog();
System.out.println(x.getClass());
x.breath();
if (x instanceof Dog) {
  Dog d = (Dog) x;
  d.bark();
} else if (x instanceof Cat) {
  Cat c = (Cat) x;
  c.meow();
}

That last one the only way to do it?

Axpen
  • 65
  • 1
  • 5
  • 1
    I don't really understand your problem, Mammal will accept any sub-class of Mammal de facto. – Colin Hebert Aug 22 '10 at 09:50
  • I haven't done statically typed OOP, so I didn't think that would work. I thought that you could only override types in methods. – Axpen Aug 22 '10 at 10:03
  • The cast implies that there is an error with your design. If you need to know what the type of something is, you should save it as that type of thing. – dash-tom-bang Aug 23 '10 at 19:22

1 Answers1

1

If you have the following:

class Mammal {...}
class Dog extends Mammal {...}
class Cat extends Mammal {...}

Then Dog is a subtype of Mammal. Cat is also a subtype of Mammal. This type polymorphism does in fact allow you to do the following:

Mammal x;
x = new Dog(); // fine!
x = new Cat(); // also fine!

If in fact later there's the following:

class Platypus extends Mammal {...} // yes it's true!

Then you can also do:

x = new Platypus(); // fine!

This polymorphic subtyping relationship is one of the basic tenets of object-oriented programming.

See also


On instanceof type comparison operator

Suppose we have the following:

class Mammal { void lactate(); }
class Dog extends Mammal { void bark(); }
class Cat extends Mammal { void meow(); }

Then you can use instanceof type comparison operator (§15.20.2) to do something like this:

Mammal x = ...;

if (x instanceof Dog) {
   Dog d = (Dog) x;
   d.bark();
} else if (x instanceof Cat) {
   Cat c = (Cat) x;
   c.meow();
}
if (x != null) {
   x.lactate();
}

There are also ways to do this without if-else; this is just given as a simple example.

Note that with appropriate design, you may be able to avoid some of these kinds of subtype differentiation logic. If Mammal has a makeSomeNoise() method, for example, you can simply call x.makeSomeNoise().

Related questions


On reflection

If you must deal with new types not known at compile-time, then you can resort to reflection. Note that for general applications, there are almost always much better alternatives than reflection.

See also

Community
  • 1
  • 1
polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
  • Ok thanks that's what I was wondering. But that does leave the question, how do you know if it has the bark or meow method? Just check the type and branch code with an if-then? Or does java do the Ruby/Javascript thing where it duck types? – Axpen Aug 22 '10 at 09:59
  • If you wanted to call a method on an object that extends a parent class, and adds a method that the parent class doesn't have, you would have to cast it as the object that it really is or something similar – Falmarri Aug 22 '10 at 10:03
  • Thanks I'll keep an eye on it. What I'm wanting to do is an RPG database thing. The method of obtaining the item has the same base principle, but there are differences it how it's obtained; mob drop (mob name), vendor bought (vendor name) or quest reward (quest starter, quest name). – Axpen Aug 22 '10 at 10:05
  • @Axpen: There was an RPG-flavored question asked a few months back. Basically it has an interaction method between a pair of objects, but since Java is single-dispatch, the code ended up being very messy. The nice solution was to use visitor pattern. I've since lost the link to this question, but maybe someone else can dig it up for you; it may be relevant to what you're doing. – polygenelubricants Aug 22 '10 at 10:40
  • @Axpen: you may also want to look up `enum`, which is _VERY_ powerful in Java. http://download-llnw.oracle.com/javase/1.5.0/docs/guide/language/enums.html ; http://stackoverflow.com/questions/3363120/enumerations-why-when/3363326#3363326 – polygenelubricants Aug 22 '10 at 10:42