0

I'm working on a project atm that requires me to use polimorphism concepts.

I have this question:

Imagine I have an interface that represents all mammals, then I create the following sub-classes: Human and Whale.

Imagine now I wanted to create some humans and some whales on my program, I would keep them in a array of mammals.

Thing is, the sub-class Human has the solveMathProblem() method, while the Whale class doesn't have it, therefore neither does the Mammals.

How could I use that method in the array?(For example: mammals[2].solveMathProblem();)

That won't work since the solveMathProblem() isn't specified in the Mammals Interface because only humans can do it)

What can I do to make that work?

Community
  • 1
  • 1
  • As you only have instances of type Mammal, you can't use any methods that are not defined in this type. If you want to use subtype methods, you need to cast your objects to Human, which will fail (by throwing an exception) if the object doesn't fit the new type. The `instanceof` operator might also be helpful. – Till Helge Apr 04 '15 at 12:53
  • You can use casting like `((Human)mammals[2]).solveMathProblem();` but to be sure that `mammals[2]` you need to check `if (mammals[2] instanceof Human)` first. Also having to use casting most often means that your project should be redesigned since *casting* is not polymorphism. – Pshemo Apr 04 '15 at 12:56
  • @Joao, while not mandatory, it wouldn't harm to accept one of the answers that helped you answer your question [as a token of appreciation to the person who spent their free time helping you for free :)] – Chetan Kinger Apr 24 '15 at 08:51

3 Answers3

0

A superclass reference to a subclass object can't access methods not defined in the super class.

You will need to explicitly cast your Mammal reference to a Human reference in order to be able to access the methods present in a Human as shown below :

((Human)mammals[2]).solveMathProblem();

That being said, you should take a look at the Strategy pattern on how to add behavior through composition. This answer does a pretty good job in explaining the concept. In your particular case, you can add different behaviors to different Mammal implementations by introducing a new Behavior hierarchy.

Community
  • 1
  • 1
Chetan Kinger
  • 15,069
  • 6
  • 45
  • 82
0

why don't you use the instanceof operator inside your loop, before calling the solveMathProblem method.

Saurabh Jhunjhunwala
  • 2,832
  • 3
  • 29
  • 57
0

There are two ways I can think of and both might be good:

  1. You can declare solveMathProblem for the Mammal interface:

    • declare the method for the interface
    • create a class, called MammalCore
    • implement the method of solveMathProblem in MammalCore in a way that it would throw an exception, which will state that the operation is unsupported (this way it will be a default behavior)
    • override solveMathProblem for Human This way, if you call solveMathProblem in your array, exception will be thrown for Whale instances and it will be accurately executed for Human instances
  2. You can use Reflection. In your loop you can check for each object, whether solveMathProblem exists (How To Check If A Method Exists At Runtime In Java?) and invoke the method if so.

Community
  • 1
  • 1
Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
  • I still feel the Strategy pattern is a better option. – Chetan Kinger Apr 04 '15 at 13:24
  • The basic idea is that you do not want to execute the method for whales. If the problem is 2+2 and you call the solveMathProblem, you should actually get an exception if it has to be handled by a Whale. Converting to Human and executing the method is bad, since the result will be that a Whale solved the problem, which is evidently not how this should work. – Lajos Arpad Apr 04 '15 at 13:40