Error when extending superclass to subclass in Java - polymorphism - java

I'm currently tackling polymorphism on my java journey and I'm trying out these example codes in Eclipse. I just copied the codes but I'm really wondering why my codes wouldn't compile.
So I got three files: Example.java, Animals.java and Dog.java.
Example.java contains the main method:
public class Example {
public static void main(String[] args) {
Animal myDog = new Dog();
}
}
Then I created two other classes for Animal and Dog as follows
Animal Class
public class Animal {
public void makeNoise() {
}
public void eat(){
}
public void sleep() {
}
public void roam() {
}
}
Dog Class
public class Dog {
}
The way I understand it is that I can make Dog my subclass that extends the superclass Animal. But why wouldn't my codes compile?
Am I missing something in these codes?

Your Dog class doesnt extend animal class so this is invalid:
Animal myDog = new Dog();
you need to modify the class Dog in order to inherit the Animal Class
you achieve that doing:
public class Dog extends Animal{

Related

Abstract class or casting?

I'm trying to figure out whether implementing individual methods of a subclass in an abstract superclass, or casting is the better way to go about the following scenario.
Suppose I have an abstract class Animal which has two subclasses, Dog and Cat and a Main class where I save objects of Dog and Cat in an Animal array. The following is how I would go about using methods of the subclasses in a more generalized array.
class Main{
public static void main(String[] args){
Animal[] animalArray = new Animal[2];
animalArray[0] = new Cat();
animalArray[1] = new Dog();
for (Animal a : animalArray){
if (a.getClass().equals(Dog.class){
((Dog)a).bark();
} else {
((Cat)a).meow();
}
}
}
}
However a friend suggested that casting isn't best practice, and that I should define each method in the abstract superclass in the following way:
public abstract class Animal{
public abstract String meow(){
return null;
}
public abstract String bark();
return null;
}
}
After setting the return values of these methods to null I would need to use #Override and implement them in the respective subclasses.
Which way is better? I'm afraid the abstract class will be too large and will have methods assigned to subclasses that don't make sense (even if all they do is return null). I think by using casting I can make more precise uses of the methods.
meow() and bark() shouldn't be defined in the Animal class. These methods are specific to Cat and Dog classes.
You should define an abstract method as shown below, in the Animal class and override it in the sub classes.
public abstract class Animal {
public abstract String action() {};
}
public class Dog extends Animal {
#Override
public String action() {
//your implementation (bark)
}
}
public class Cat extends Animal {
#Override
public String action() {
//your implementation (meow)
}
}
Hope it answers your query.

Can i call child class method using parent object?

I have created base class animal and child class as cat.
In main, I want to create obj of PARENT class and call the method of child class.
So, is it possible or not?
I have also used instanceOf to just check relationship
public class Animal
{
public void eats()
{
System.out.println("Animal Eats");
}
}
public class Cat extends Animal
{
public void walks()
{
System.out.println("Cat Walks");
}
}
public class AnimalMain
{
public static void main(String args[])
{
Animal a=new Animal();
display(a);
}
public static void display(Animal a)
{
a.eats();
if(a instanceof Cat)
((Cat)a).walks();
}
}
Your code should work fine. The if condition will result in false, so your animal will not walk().
Animal animal = new Animal();
This animal will have all the behaviours of Animal, i.e. eat(), but none of the behaviours of the sub-class Cat, i.e. walk().
If you want your animal to have all the behaviours of Animal as well as all the behaviours of Cat, you need to instantiate the Cat class.
Animal animal = new Cat();
Now your animal will eat and walk.
Yes, it will. You are changing the type, so it will work.

Pattern Matching like behavior

I am at a lookout for a design pattern for my simple problem. Here is a simplified version.
class Animal{...}
class Dog extends Animal{...}
class Cat extends Animal{...}
... // so on, 3 other classes as of now
I have a static method (in reality exposed via web-service but its synonymous) which takes an id and returns an animal.
If a cat is returned then the other team using the cat object generates a CatReport. If Dog, then dog report (They can use it for anything). Obviously Cat & Dog have different attributes. Cat and Dog don't have anything else in common apart from the fact that they are Animals. So making a call like below, is insufficient because I need the precise type:
public static Animal getAnimal(int id){}
Not sufficient because animal does not contain all the information what the precise type can give me.
What is the best way to deal with this problem?
PS: In Scala, I would simply do pattern-matching on the object. This solves the problem elegantly.
One solution I have is: make a call which returns an enum signifying what the id corresponds to. And then have a separate call for each:
public static AnimalType getAnimalType(int id){}
public static Cat getCat(int id){}
public static Dog getDog(int id){}
....
But this is cumbersome.
In a language like Java, you can simulate pattern matching behavior using the Visitor pattern.
You can do it in some steps :
Define an interface Animal representing an Animal with a accept method
Add some subclasses to Animal and give the same implementation like in my little example below.
Define an interface Visitor and give it an implementation. This classe will allows to you to simulate some pattern matching on your classes.
Here a little example :
public interface Animal {
public void accept(AnimalVisitor v);
}
public class Dog extends Animal {
public void accept(AnimalVisitor v) {
v.visit(this);
}
}
public class Cat extends Animal {
public void accdept(AnimalVistior v) {
v.visit(this);
}
}
public interface AnimalVisitor {
public void visit(Dog d);
public void visit(Cat c);
}
public class PrintAnimal implements AnimalVisitor {
public void visit(Dog d) {
System.out.println("Dog");
}
public void visit(Cat c) {
System.out.println("Cat");
}
}
Visitor pattern is a elegant way to solve your problem and also it's avoid the accumulation of if (x instance of bar) in one function. With this pattern, your code will be more readable and easier to extend.
The corresponding Scala code to make an idea of my answer:
abstract class Animal {}
case class Dog() extends Animal
case class Cat() extends Animal
object Animal {
def printAnimal(a : Animal) = a match {
case x : Dog => "Dog"
case x : Cat => "Cat"
case _ => "Unknown"
}
def main(args : Array[String]) = {
println(printAnimal(Dog()))
}
}
Well, I don't see any really elegant solution but you can create a kind of report factory with this kind of code
public Report getCorrespondingReport(Animal animal){
if(animal instanceof Dog) return new DogReport();
if(animal instanceof Cat) return new CatReport();
...
...or you could make a generic report and use reflection to inspect your Animal instance and generate your report following general rules but it might not be doable.
If I understand the question correctly, you want to call correct implementation of methods regards of the type of object you have. So if an animal is a cat, generate report method should be called from Cat class if you have code like below
public static Animal getAnimal(int id){
//your code to return object of either Cat or Dog
}
animal.generateReport();
First of all as you said,
Obviously Cat & Dog have different attributes. Cat and Dog dont have
anything else in common apart from the fact that they are Animals.
As the subclasses do not have any common functionality, define Animal as an interface instead of a class like given below
interface Animal{
public void generateReport();
}
And create Cat and Dog like this
class Cat implements Animal{
//define cat specific attributes here
public void generateReport(){
//your logic to generate cat report
}
}
class Dog implements Animal{
//define dog specific attributes here
public void generateReport(){
//your logic to generate dog report
}
}
Since the generateReport() method is defined in interface, all the classes implementing the interface must have generateReport().
So when you make a call like this,
public static Animal getAnimal(int id){
//your code to return object of either Cat or Dog
}
animal.generateReport();
the underlying object's method will be called.
If you simply want to know what animal object refers to (returned from getAnimal method i.e. either Cat or Dog), you can check it like below
class Animal{
}
class Dog extends Animal{
public String dogName = "Dog1";
}
class Cat extends Animal{
public String catName = "Cat1";
}
public class HelloWorld{
public static void main(String []args){
//call getAnimal and get the object instead of following line
Animal animal = new Cat();
if ( animal instanceof Cat ){
//cast Animal to Cat
Cat cat = (Cat) animal;
System.out.println(cat.catName);
}else if ( animal instanceof Dog ){
//cast Animal to Dog
Dog dog = (Dog) animal;
System.out.println(dog.dogName);
}
}
}

Static abstract method workaround

I would like to create a abstract static method in an abstract class. I am well aware from this question that this is not possible in Java. What is the default workaround / alternative way of thinking of the problem / is there an option for doing this for seemingly valid examples (Like the one below)?
Animal class and subclasses:
I have a base Animal class with various subclasses. I want to force all subclasses to be able to create an object from an xml string. For this, it makes no sense for anything but static does it? E.g:
public void myMainFunction() {
ArrayList<Animal> animals = new ArrayList<Animal>();
animals.add(Bird.createFromXML(birdXML));
animals.add(Dog.createFromXML(dogXML));
}
public abstract class Animal {
/**
* Every animal subclass must be able to be created from XML when required
* (E.g. if there is a tag <bird></bird>, bird would call its 'createFromXML' method
*/
public abstract static Animal createFromXML(String XML);
}
public class Bird extends Animal {
#Override
public static Bird createFromXML(String XML) {
// Implementation of how a bird is created with XML
}
}
public class Dog extends Animal {
#Override
public static Dog createFromXML(String XML) {
// Implementation of how a dog is created with XML
}
}
So in cases where I need a static method, and I need a way of forcing all subclasses to have an implementation of this static method, is there a way I can do that?
You can create a Factory to produce the animal objects, Below is a sample to give you a start:
public void myMainFunction() {
ArrayList<Animal> animals = new ArrayList<Animal>();
animals.add(AnimalFactory.createAnimal(Bird.class,birdXML));
animals.add(AnimalFactory.createAnimal(Dog.class,dogXML));
}
public abstract class Animal {
/**
* Every animal subclass must be able to be created from XML when required
* (E.g. if there is a tag <bird></bird>, bird would call its 'createFromXML' method
*/
public abstract Animal createFromXML(String XML);
}
public class Bird extends Animal {
#Override
public Bird createFromXML(String XML) {
// Implementation of how a bird is created with XML
}
}
public class Dog extends Animal {
#Override
public Dog createFromXML(String XML) {
// Implementation of how a dog is created with XML
}
}
public class AnimalFactory{
public static <T extends Animal> Animal createAnimal(Class<T> animalClass, String xml) {
// Here check class and create instance appropriately and call createFromXml
// and return the cat or dog
}
}

Overriding a method(with the same signature) present in both Parent Class as well as the Interface

We have a Class(say Animal), and we have an Interface(say Behave). Both Animal as well as Behave have a method with the same signature(say public void eat()).
When we try to write the body for the method eat() in a Class(say Dog) which extends Animal and implements Behave, which eat() method is actually referred to? The one in Animal or Behave. In whichever case that happens, why does it happen that way?
Edit:
I tried this scenario on Eclipse before posting this question.
An interesting part here is, even though I am implementing Behave, if I dont create an eat() method(i.e. if I dont implement Behave's inherited abstract method) inside Dog, there is no error, since I am already extending from Animal which has an eat() method.
which eat() method is actually referred to? BOTH.
Try this: if you don't override the method at all, when you call with the interface, you will get the one from the parent.
Behave b = new Dog();
System.out.println(b.eat());//this will call eat from Animal if Dog did not override.
If you override, you always get the one from the child:
Behavior b = new Dog();
Animal a = new Dog();
a.eat() and b.eat() will both refer to the eat inside of Dog class.
USE THESE CLASSES:
public class BClass {
public int add(int a, int b){
return a*b;
}
}
public interface BInterface {
public int add(int a, int b);
}
public class BChild extends BClass implements BInterface{
public static void main(String... args){
BInterface bi = new BChild();
BClass bc = new BChild();
System.out.println(bi.add(3, 5));
System.out.println(bi.add(3, 5));
}
#Override
public int add(int a, int b){
return a+b;
}
}
interface can contain only body definition of method , once you implements, it must have implementation of all defined methods. In you example
class Dog extends Animal implements Behave
{
#Override
public void eat() {...}
}
abstract class Animal{
public abstract void eat();
}
interface Behave{
void eat();
}
Here it need a body of abstract method where as it is in Main method. In other way
class DOG extends Animal implements Behave{
...
}
class Animal{
public void eat(){
...
}
}
interface Behave{
void eat();
}
Here Dog class having eat method body in its super class Animal. So it wount ask to implement body again in Animal as it is already implemented.
An interface simply defines a method that a class must provide. If we have
public class Animal{
public void eat(){
System.out.println("Om nom nom");
}
}
public class Dog extends Animal{
}
Dog now provides the eat method and can so implement Behave.
There is only one eat() method, because the designers of the language decided that the simplicity of having the method signature consist of its name and argument types was more useful than having the complexity of being able to specify that you are providing an implementation of an interface.
In Java, if the two have different semantics, provide a method which returns a Behave instance which does something else:
class Animal {
public void eat () { }
}
interface Behave {
void eat ();
}
class Dog extends Animal {
public void eat () {
// override of Animal.eat()
}
public Behave getBehave() {
return new Behave {
public void eat() {
BehaveEat();
}
};
}
private void BehaveEat() {
// effectively the implementation Behave.eat()
}
}
In other languages, you can explicitly state that a method implements a method from an interface.

Categories

Resources