Incorporating Polymorphism - java

I'm new to Java and need to employ polymorphism into the following lines:
horse.feed();
horse.wash();
horse.exercise();
How do I do this?
These are the first lines of the code in this exercise:
public class Main extends Object {
public static void main(String [] args) {
Horse horse = new horse();
}
}

Answering the question from your comment: "Could someone write out how it should look so I can better understand it."
Let's create an interface Animal
public interface Animal {
public void feed();
public void wash();
public void exercise();
}
And a class Horse:
public class Horse implements Animal {
#Override
public void feed() {
// Do something to feed the horse
}
#Override
public void wash() {
// Do something to wash the horse
}
#Override
public void exercise() {
// Do something to exercise the horse
}
}
Now in your main method, you can create a horse that is an Animal and call the methods:
Animal horse = new Horse();
horse.wash();
// Etcetera
Now if you would make a class Dog, which also implements Animal, you could make a List of Animals and add Horses and Dogs to one List!

Related

Casting & Inheritance in Java [duplicate]

How can I call the eat and drink method of the Animal class with the myAnimal instance in the code?
public class Animal {
public void eat() {
System.out.println("Animal Eats");
}
public void drink() {
System.out.println("Animal Drinks");
}
}
public class Cat extends Animal {
#Override
public void eat() {
System.out.println("Cat Eats");
}
#Override
public void drink() {
System.out.println("Cat Drinks");
}
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
Animal myAnimal = myCat;
myAnimal.eat();
myAnimal.drink();
}
}
Output that I am getting:
Cat Eats
Cat Drinks
Cat Eats
Cat Drinks
This is my expected output:
Cat Eats
Cat Drinks
Animal Eats
Animal Drinks
You cannot do what you want. The way polymorphism works is by doing what you are seeing.
Basically a cat always knows it is a cat and will always behave like a cat regardless of if you treat is as a Cat, Felis, Felinae, Felidae, Feliformia, Carnivora, Theria, Mammalia, Vertebrata, Chordata, Eumetazoa, Animalia, Animal, Object, or anything else :-)
Here you will have an option to choose which method do you want to invoke:
public class Cat extends Animal {
public void superEat() {
super.eat();
}
public void superDrink() {
super.drink();
}
#Override
public void eat() {
System.out.println("Cat Eats");
}
#Override
public void drink() {
System.out.println("Cat Drinks");
}
}
This line:
Animal myAnimal = myCat;
assigns the variable myAnimal to the object myCat, which you've created before. So when you call myAnimal.eat() after that, you're actually calling the method of the original myCat object, which outputs Cat Eats.
If you want to output Animal Eats, you'll have to assign an Animal instance to a variable. So if you would do this instead:
Animal myAnimal = new Animal()
the variable myAnimal will be an instance of Animal, and thus will overwrite the previous assignment to Cat.
If you will call myAnimal.eat() after this, you're actually calling the eat() method of the Animal instance you've created, which will output Animal Eats.
Concluding: your code should read:
public class Cat extends Animal {
#Override
public void eat() {
System.out.println("Cat Eats");
}
#Override
public void drink() {
System.out.println("Cat Drinks");
}
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
Animal myAnimal = new Animal();
myAnimal.eat();
myAnimal.drink();
}
}
Access to static fields, instance fields and static methods depends on the class of reference variable and not the actual object to which the variable points to.
Remember that member variables are shadowed, not overridden.
This is opposite of what happens in the case of instance methods.
In case of instance methods the method of the actual class of the object is called.
class ABCD {
int x = 10;
static int y = 20;
public String getName() {
return "ABCD";
}
}
class MNOP extends ABCD {
int x = 30;
static int y = 40;
public String getName() {
return "MNOP";
}
}
public static void main(String[] args) {
System.out.println(new MNOP().x + ", " + new MNOP().y);
ABCD a = new MNOP();
System.out.println(a.x); // 10
System.out.println(a.y); // 20
System.out.println(a.getName()); // MNOP
}
In this example although the the object myCat is assigned to an Animal object reference, (Animal myAnimal = myCat) the Actual object is of type Cat and it behaves as it's a cat.
Hope this helps.
You can create constructor for class Animal, that takes another Animas as parameter, and creates new instance based on provided one.
public class Animal {
//some common animal's properties
private int weight;
private int age;
public Animal() {
// empty.
}
public Animal(final Animal otherAnimal) {
this.weight = otherAnimal.getWeight();
this.age = otherAnimal.getAge();
}
public void eat() {
System.out.println("Animal Eats");
}
public void drink() {
System.out.println("Animal Drinks");
}
// setters and getters.
}
public class Cat extends Animal {
#Override
public void eat() {
System.out.println("Cat Eats");
}
#Override
public void drink() {
System.out.println("Cat Drinks");
}
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
// note: myAnimal is not a Cat, it's just an Animal.
Animal myAnimal = new Animal(myCat);
myAnimal.eat();
myAnimal.drink();
}
}
Few suggestions :
Don't pass child class reference to super class and except super class method has to be invoked for overridden method. Call super class methods from super class instance.
Animal myAnimal = new Animal();
myAnimal.eat();
If you want to call super class method from child class, explicitly call super class method name with super.methodName();
public void eat() {
super.eat();
System.out.println("Cat Eats");
}
Don't override super class method in child class. Always super class method is invoked.
If you make methods in each class static, it should work.
public class Animal {
public static void eat() {
System.out.println("Animal Eats");
}
public static void drink() {
System.out.println("Animal Drinks");
}
}
public class Cat extends Animal {
#Override
public static void eat() {
System.out.println("Cat Eats");
}
#Override
public static void drink() {
System.out.println("Cat Drinks");
}
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
Animal myAnimal = myCat;
myAnimal.eat();
myAnimal.drink();
}
}
The above code will give the following output
Cat Eats
Cat Drinks
Animal Eats
Animal Drinks
You can achieve what you want using the super keyword, which allows to access the overridden method.
public class Animal {
public void eat() {
System.out.println("Animal Eats");
}
public void drink() {
System.out.println("Animal Drinks");
}
}
public class Cat extends Animal {
public void eat() {
System.out.println("Cat Eats");
}
public void drink() {
System.out.println("Cat Drinks");
}
public void printMessage(){
super.eat();
super.drink();
}
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
myCat.printMessage();
}
}
Please don't vote on this answer... you can vote on the other one :-) This is a bad answer, but shows how you would do what you are trying to do... poorly.
public class Main
{
public static void main(final String[] argv)
{
Child child;
Parent parent;
child = new Child();
parent = child;
child.a();
parent.a();
child.otherA();
parent.otherA();
}
}
class Parent
{
public void a()
{
System.out.println("Parent.a()");
}
public void otherA()
{
// doesn't matter what goes here... really should be abstract
}
}
class Child
extends Parent
{
#Override
public void a()
{
System.out.println("Child.a()");
}
#Override
public void otherA()
{
super.a();
}
}
public class Main {
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
Animal myAnimal = new Animal();
myAnimal.eat();
myAnimal.drink();
}
}
public class Animal {
public void eat(){
System.out.println("Animal eat() called");
}
public void drink(){
System.out.println("Animal drink() called");
}
}
public class Cat extends Animal {
#Override
public void eat() {
System.out.println("Cat eat() called");
}
#Override
public void drink() {
System.out.println("cat drink() called");
}
}
OUTPUT:
Cat eat() called
cat drink() called
Animal eat() called
Animal drink() called
You need to create an object of the super class Animal OR another option is to use the keyword super in the child class methods e.g., super.eat() or super.drink()
Cat can't stop being a cat, even if it is an animal. Cat will eat and cat will drink in a cat's way. It might be similar to what an Animal does, which is why it overrides the method. If you want it to do what the animal does by default, don't override. You could probably do some weird stuff with reflection and make separate methods that access the parent methods such as:
public void superDrink() {
Animal.class.getMethod("drink").invoke();
}
but that might be overkill don't you think?
Of course that probably wouldn't work since it's not static.
You can do what you want with a few minor changes to your code. Naturally the methods of the Animal class have been overriden and you cannot simply access them by changing the reference type. Instead, you could slightly change the definition of the eat and drink functions as follows.
class Animal{
public void eat(boolean randomBoolean){
System.out.println("Animal eats");
}
public void drink(boolean randomBoolean){
System.out.println("Animal drinks");
}
}
class Cat extends Animal{
public void eat(boolean wantOverriden){
if(wantOverriden){
boolean randomBooleanValue=true|false;
super.eat(randomBooleanValue);
}
else{
System.out.println("Cat eats");
}
}
public void drink(boolean wantOverriden){
if(wantOverriden){
boolean randomBooleanValue=true|false;
super.drink(randomBooleanValue);
}
else{
System.out.println("Cat drinks");
}
}
}
Now you should be able to access the overriden methods of the Animal class through the Cat class object by simply passing in a boolean value indicating if you want to do so ex:
Cat c=new Cat();
c.eat(false); //Indicating that you dont want to access the overriden method
c.drink(false); //Indicating that you dont want to access the overriden method
c.eat(true); //Indicating that you want to access the overriden method
c.drink(true); //Indicating that you want to access the overriden method

Is there a way to use overridden function in base class? (In Java)

I tried to implement a function in a base class which using the function of the childs (defiend as a abstract function in the base class). I think an example will demonstrate the problem in the best way.
abstract class Animal{
public void doSomthing(){
this.sound();
}
protected abstract void sound();
}
class Dog extends Animal{
#Override
protected void sound(){
System.out.println("WAF");
}
}
now when I tried to get the element in run time (by factory method which looks like: Animal factory method("Dog);) and call to the doSomthing method I got exception because it goes to the abstract method, my question is if there is any way the bypass this or another solution for this problem.
class myMain
{
public static void main(String[]args)
{
Animal doggo = new Dog(); // create object for dog
doggo.animalSound(); // call the sound for dog
}
}
class Animal
{
public void animalSound()
{
System.out.println("The animal makes a sound");
}
}
class Dog extends Animal
{
public void animalSound()
{
System.out.println("The Dog Says bow wow! ");
}
}
I do not see any problem with the approach you have mentioned in the description of your question. Maybe you are doing some other mistake. Check the following working code:
abstract class Animal {
public void doSomthing() {
sound();
}
protected abstract void sound();
}
class Dog extends Animal {
#Override
protected void sound() {
System.out.println("WAF");
}
}
class AnimalFactory {
static Animal animal;
public static Animal factoryMethod(String animalName) {
if ("Dog".equals(animalName)) {
animal = new Dog();
}
return animal;
}
}
class Main {
public static void main(String[] args) {
Animal animal = AnimalFactory.factoryMethod("Dog");
animal.sound();
}
}
Output:
WAF
The call to child class method from super class can be done.
Refer code snippet mentioned in below link:
Can a Parent call Child Class methods?

List<Super Class> which contains objects of different subclasses

Now I have a class Animal, with three subclasses extending it: Dog, Cat, and Fish.
class Dog extends Animal {
public void bark(){}
}
class Cat extends Animal {
public void catchMouse(){}
}
class Fish extends Animal {
public void swim(){}
}
And I have a list:
List<Animal> listOfAnimals = new ArrayList<>();
Then I use a static method to add objects of Dog, Cat and Fish to the list:
public static void addAnimal(List<Animal> list, AnimalInfo info) {
Animal animal = new Animal();
switch (info) {
case 0:
animal = new Dog();
break;
case 1:
animal = new Cat();
break;
case 2:
animal = new Fish();
break;
}
list.add(animal);
}
I call this static method 3 times and add a Dog object, a Cat object and a Fish object to the list in order. Now the list should contain a Dog instance, a Cat instance and a Fish instance.
Now I want to call bark() on the Dog instance:
list.get(0).bark();
But this will not work obviously.
What is the best way to achieve this? Use:
(Dog)(list.get(0)).bark();
?
I think utilizing inheritance here could be a good approach in this case, but I thought I'd share an alternative.
Another approach here is to use the visitor pattern. This is especially good when you don't know what you need to do with an object when you declare its class, or if you have contextual behaviour (such as updating another object's state) that you want to keep separate from your Animal classes (Separation of Concerns)
abstract class Animal {
abstract void accept(AnimalVisitor visitor);
}
class Dog extends Animal {
void bark() { ... }
#Override
void accept(AnimalVisitor visitor) {
visitor.visit(this);
}
}
class Cat extends Animal {
void meow() { ... }
#Override
void accept(AnimalVisitor visitor) {
visitor.visit(this);
}
}
interface AnimalVisitor {
void visit(Dog dog);
void visit(Cat cat);
}
// Somewhere else...
AnimalVisitor voiceVisitor = new AnimalVisitor() {
#Override
void visit(Dog dog) {
dog.bark();
}
#Override
void visit(Cat cat) {
cat.meow();
}
}
animalList.get(0).accept(voiceVisitor);
What is the best way to achieve this?
If you use List of Animals you should use Animal-only methods further in program logick.
The idea of List is that you iterating over it any apply the same to items.
Make:
class Animal {
public void voice(){}
public void swim(){}
}
class Dog extends Animal {
public void voice(){
print('bark')}
}
class Cat extends Animal {
public void voice(){
print('meow')}
}
And if you do want to have a list of all animals, they just do noting, instead of calling is instance of what is more expencive
Another way of doing this is through interface
interface IAnimal {
public void Roar();
public void Swim();
}
class Animal implements IAnimal{
#Override
public void Roar() {
// TODO Auto-generated method stub
System.out.println("IROAR");
}
#Override
public void Swim() {
// TODO Auto-generated method stub
if (!(this instanceof Lion)) {
System.out.println("ISWIM");
}
else {
System.out.println("this animal cannot swim");
}
}
}
Notice that I added a check for Lion instance for Swim() method since not all animals can swim.
Client Code:
List<IAnimal> animals = new ArrayList<>();
animals.add(new Lion());
animals.add(new Dog());
animals.get(0).Swim();
animals.get(1).Roar();

how to pass more types arguments into method with one parameter

I have several classes with differently object type cat, dog and horse. I have
one root class where is method doSomethig with only one parameter which I want to call in rest of classes. How to write the method without type conflict. This is only example.
Cat cat;
Dog dog;
Horse horse;
protected void doSomething(one parameter){
cat.doMeow();
dog.doBark();
horse.run();
}
Why not to extend parent class Animal where there would be doSomething(one parameter) and then in subclasses call super() ?
If I understand you right, the signature is fixed for just one parameter. But you need to have access to cat, dog and horse? In that case, you need to adjust one to be a parameter object.
(Also, it should start with an upper case letter, as general accepted code style)
public class one
{
private Cat cat;
private Dog dog;
private Horse horse;
public one(Cat cat, Dog dog, Horse horse)
{
this.cat = cat;
this.dog = dog;
this.horse = horse;
}
public Cat getCat()
{
return this.cat
}
// getDog(), getHorse()
}
Then use the getter methods in the doSomething method
protected void doSomething(one parameter){
parameter.getCat().doMeow();
parameter.getDog().doBark();
parameter.getHorse().run();
}
Calling it like:
public void myMethod()
{
one animals = new one(new Cat(), new Dog(), new Horse());
doSomething(animals); // if same class or myInstance.doSomething(animals) if another class
}
A brute force solution would be to pass an Object, e.g. of type Animal and check the type in the method, and call the appropriate method based on the result of the type check:
protected void doSOmething(Animal an Animal) {
if( anAnimal instanceof Horse)
((Horse) anAnimal).run();
else if( anAnimal instanceof Dog )
((Dog) anAnimal).bark();
else ...
}
However, this is considered to be bad style, because the method has too much knowledge about Horses, Dogs, and such.
It would be better if Animal had an abstract method doDefaultAction() which is overwritten by the Horse as a call to run(), by the dog as a call to bark(), and so on.
abstract class Animal {
abstract void doDefaultAction(Animal anAnimal);
}
class Horse extends Animal {
#Override
void doDefaultAction(Animal anAnimal) {
((Horse) anAnimal).run();
}
void run() { /* do some running */ }
}
In your method doSomething() you would simply call anAnimal.doDefaultAction() without need to know what the default action for the animal might be.
If the abstract Animal class does not do something else you might also consider to use an interface Animal instead of a class.
You could create a common interface and call the interface method. For example:
public interface Animal {
public void act();
}
public class Cat implements Animal {
public void doMeow() { /* ... */ }
#Override
public void act() {
doMeow();
}
}
public class Dog implements Animal {
public void doBark() { /* ... */ }
#Override
public void act() {
doBark();
}
}
Then the doSomething method could polymorphically call the act method:
protected void doSomething(Animal animal) {
animal.act();
}
Depending on which object is passed (e.g. Cat or Dog), the behavior of doSomething will change.
Assuming this is the classic OO inheritance example. A simple solution works like this:
public class AnimalExample {
interface Animal {
void action();
}
public static class Cat implements Animal{
#Override
public void action() {
System.out.println("meow");
}
}
public static class Dog implements Animal{
#Override
public void action() {
System.out.println("bark");
}
}
public static class Horse implements Animal{
#Override
public void action() {
System.out.println("run");
}
}
static void doSomething(Animal animal){
animal.action();
}
public static void main(String[] args) {
Cat cat = new Cat();
Dog dog = new Dog();
Horse horse = new Horse();
doSomething(cat);
doSomething(dog);
doSomething(horse);
}
}

Avoiding use of 'instanceof'

I'm struggling with how I might avoid using instanceof() in some of my code. This contrived example somewhat captures the problem.
Class Meat extends Food;
Class Plant extends Food;
Class Animal;
Class Herbivore extends Animal
{
void eat( Plant food);
}
Class Carnivore extends Animal
{
void eat( Meat food);
}
Class Omnivore extends Animal
{
void eat(Food food);
}
Class Zoo
{
List<Animals> animals;
void receiveFood( Food food)
{
// only feed Plants to Herbivores and Meat to Carnivores
// feed either to Omnivores
}
}
Herbivores are only interested in Plants, Carnivores only in Meat and Omnivores both. When the Zoo receives Food it only makes sense to try to feed food to animals that eat that type of food.
I've thought of a few solutions, but all seem to depend on the use of instanceof() somewhere and my various refactorings just seem to move it around.
(1) I could implement eat( Food food) in Animal and each subclass could choose to ignore food that it doesn't eat, but that is inefficient and would require that each Animal subclass use instanceof() to test the type of food.
(2) I could keep three collections of animals in the Zoo based on the type of food they eat, but would still have to use instanceOf() to test the type of food to see which collection to feed it to. At least this would be more efficient as I wouldn't be feeding food to Animals that won't eat it.
I've thought of some other approaches, but again, they just seem to pass the instanceof() buck.
Any suggestions? Or would this (2, at least) be an acceptable use of instanceof()?
The visitor pattern solves your problem. Here's the code:
public abstract class Animal {
public abstract void accept(AnimalVisitor visitor);
}
public interface AnimalVisitor {
public void visit(Omnivore omnivore);
public void visit(Herbivore herbivore);
public void visit(Carnivore carnivore);
}
public class Carnivore extends Animal {
#Override
public void accept(AnimalVisitor visitor) {
visitor.visit(this);
}
public void eat(Meat meat) {
System.out.println("Carnivore eating Meat...");
}
}
public class Herbivore extends Animal {
#Override
public void accept(AnimalVisitor visitor) {
visitor.visit(this);
}
public void eat(Plant plant) {
System.out.println("Herbivore eating Plant...");
}
}
public class Omnivore extends Animal {
#Override
public void accept(AnimalVisitor visitor) {
visitor.visit(this);
}
public void eat(Food food) {
System.out.println("Omnivore eating " + food.getClass().getSimpleName() + "...");
}
}
public abstract class Food implements AnimalVisitor {
public void visit(Omnivore omnivore) {
omnivore.eat(this);
}
}
public class Meat extends Food {
#Override
public void visit(Carnivore carnivore) {
carnivore.eat(this);
}
#Override
public void visit(Herbivore herbivore) {
// do nothing
}
}
public class Plant extends Food {
#Override
public void visit(Carnivore carnivore) {
// do nothing
}
#Override
public void visit(Herbivore herbivore) {
herbivore.eat(this);
}
}
public class Zoo {
private List<Animal> animals = new ArrayList<Animal>();
public void addAnimal(Animal animal) {
animals.add(animal);
}
public void receiveFood(Food food) {
for (Animal animal : animals) {
animal.accept(food);
}
}
public static void main(String[] args) {
Zoo zoo = new Zoo();
zoo.addAnimal(new Herbivore());
zoo.addAnimal(new Carnivore());
zoo.addAnimal(new Omnivore());
zoo.receiveFood(new Plant());
zoo.receiveFood(new Meat());
}
}
Running the Zoo demo prints
Herbivore eating Plant...
Omnivore eating Plant...
Carnivore eating Meat...
Omnivore eating Meat...
In your case, if the consumer of the object must know certain things about that object (e.g. is it meat), include a property in your base class isMeat() and have concrete subclasses override the implementation of the base class method to return an appropriate value.
Leave that knowledge in the class itself, rather than in consumers of the class.
A simple solution is when using multiple custom classes interacting with one another, just create isFood(), isAnimal(), isCarnivore(), etc. methods that return a boolean depending on which class they're in. It's not the prettiest but it gets the job done 100% of the time.
Expanding on my comment, I would attempt to use generics to help me here:
interface Animal<T extends Food> {
void eat(T food);
}
class Herbivore extends Animal<Plant> {
void eat(Plant food) { foo(); }
}
class Carnivore extends Animal<Meat> {
void eat(Meat food) { bar(); }
}
Note that this still doesn't solve the problem of iterating through a list of Food and Animal and only sending appropriate food to each animal -- I don't see a way to do that without explicit instanceof style checks. But, it does allow you to be more specific with what your subclasses accept.
Another solution is to maintain 2 lists: one for Herbivores and one for Carnivores.

Categories