2

I am only learning about polymorphism so be easy on me (literally copying from the book). I try to pass a class as an argument to a method. When I do that I can call the superclass methods, but not the actual subclass. Using the start() method, I try to make the wolf howl:

 public class experiment {
    public static void main(String[] args) {
        PetOwner own = new PetOwner();
        own.start();

    }
}

//Trying polymorphic arguments
class Vet {
    public void giveShot(Animal a) {
        a.howl();
    }
}
class PetOwner {
    public void start() {
        Vet v = new Vet();
        Wolf w = new Wolf();

        v.giveShot(w);
    }
}
//Inheritance//
//Kingdom - Animal
class Animal {
    public void move() {
        System.out.println("*motions softly*");
    }
}
//Family - canine
class Canine extends Animal {
    public void bark() {
        System.out.println("Woof!");
    }
}
//Species - wolf
class Wolf extends Canine {
    public void howl() {
        System.out.println("Howl! Howl!");
    }
}

If I pass the howl method to the superclass (Animal) it works fine. If I call it directly from the Wolf class - it works fine. The only instance where it doesn't work is if I try to pass the wolf class as an argument and call it from there.

Here is why I try it that way, quoted from Head First Java pg 187:

The Vet's giveShot() method can take any Animal you give it. As long as the object you in as the argument is a subclass of Animal, it will work

I am getting a "cannot find symbol symbol: method howl(), Location variable of type animal" error.

Bar Akiva
  • 1,089
  • 1
  • 11
  • 23
  • Right from the first answer: *For identifiers that should be method names:* `Perhaps you are trying to refer to an inherited method that wasn't declared in the parent / ancestor classes or interfaces.` – GhostCat Aug 21 '17 at 11:21
  • @GhostCat I have added the quote from the book where it specifically claims - The Vet's giveShot() method can take any Animal you give it. As long as the object you in as the argument is a *subclass* of Animal, it will work – Bar Akiva Aug 21 '17 at 11:30

3 Answers3

2

You're calling a.howl() while a is an instance of Animal class. Animal does not know how to howl. The only Wolf does.

You can defin a method say react() and then override it for any particular subclass of Animal;

Alexey R.
  • 8,057
  • 2
  • 11
  • 27
  • Quoting my book: The Vet's giveShot() method can take any Animal you give it. As long as the object you in as the argument is a *subclass* of Animal, it will work – Bar Akiva Aug 21 '17 at 11:27
  • 1
    @BarAkiva You should try to apply your conception to a real world considering them as objects. If you have a Person you might want to make it speak English, since you know the Person can speak. But if it make sense to tell someone just "hey, speak", if you know that the Person can start speaking some specific language (your method does not know which Person would come the next time) and you have no Idea which exactly? Your problem can be resolved by either all override the same method, or all implement the same method (however this is not about the inheritance). – Alexey R. Aug 21 '17 at 11:32
  • 1
    @BarAkiva from a common class you can call only a common method since a common class knows nothing about the possible specific classes which inherit that common one. and about the methods they have. – Alexey R. Aug 21 '17 at 11:36
  • 1
    @BarAkiva another option is to check if an Animal that is passed to your giveShot method is instanceof Wolf, and then cast it to Wolf and call howl(). But this is not a good pattern.. – Alexey R. Aug 21 '17 at 11:38
0

You are calling the howl-Method inside the giveShot-Method. Animal doesn't have a howl method.

EDIT: If you cast animal to wolf inside the giveShot-Method it should work.

LaaKii
  • 95
  • 11
0

Yes, you could do something like:

class Vet {
    public void giveShot(Animal a) {
        a.makeNoise();
    }
}
class Animal {
    public void move() {
        System.out.println("*motions softly*");
    }
    public void makeNoise() {
    }
}
//Family - canine
class Canine extends Animal {
    @Override
    public void makeNoise() {
        System.out.println("Woof!");
    }
}
//Species - wolf
class Wolf extends Canine {
    @Override
    public void makeNoise() {
        System.out.println("Howl! Howl!");
    }
}
Maurice Perry
  • 9,261
  • 2
  • 12
  • 24