Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's wrong with this example of Java property inheritance?

Inheritance.java

public class InheritanceExample {
  static public void main(String[] args){
    Cat c = new Cat();
    System.out.println(c.speak());

    Dog d = new Dog();
    System.out.println(d.speak());
  }
}

Animal.java

public class Animal {
  protected String sound;
  public String speak(){
    return sound;
  }
}

Cat.java

public class Cat extends Animal {
  protected String sound = "meow";
}

Dog.java

public class Dog extends Animal {
  protected String sound = "woof";
}

Output:

null
null

My animals cannot speak. So sad.

like image 425
maček Avatar asked Oct 07 '10 06:10

maček


People also ask

What is the problem with inheritance in Java?

The problem occurs when there exist methods with the same signature in both the superclasses and subclass. On calling the method, the compiler cannot determine which class method to be called and even on calling which class method gets the priority.

Which inheritance Java does not support?

Java supports only Single, Multilevel, and Hierarchical types of inheritance. Java does not support Multiple and Hybrid inheritance.

Why multiple inheritance is not supported in Java with example?

Java doesn't support multiple inheritances in classes because it can lead to diamond problem and rather than providing some complex way to solve it, there are better ways through which we can achieve the same result as multiple inheritances.

Is inheritance a property of Java?

Java inheritance refers to the ability of a Java Class to inherit the properties from some other Class. Think of it like a child inheriting properties from its parents, the concept is very similar to that. In Java lingo, it is also called extend-ing a class.


2 Answers

Fields aren't polymorphic. You've declared three entirely distinct fields... the ones in Cat and Dog shadow or hide the one in Animal.

The simplest (but not necessarily best) way of getting your current code is to remove sound from Cat and Dog, and set the value of the inherited sound field in the constructor for Cat and Dog.

A better approach would be to make Animal abstract, and give it a protected constructor which takes the sound... the constructors of Cat and Dog would then call super("meow") and super("woof") respectively:

public abstract class Animal {
    private final String sound;

    protected Animal(String sound) {
        this.sound = sound;
    }

    public String speak(){
        return sound;
    }
}

public class Cat extends Animal {
    public Cat() {
        super("meow");
    }
}

public class Dog extends Animal {
    public Dog() {
        super("woof");
    }
}
like image 157
Jon Skeet Avatar answered Oct 23 '22 11:10

Jon Skeet


You cannot override class fields, only methods. The sound field in your Dog and Cat classes is actually hiding the sound field in the Animal superclass.

You can, however, access superclass fields from subclasses, so you could do something like this:

public class Dog extends Animal {
  public Dog() {
    sound = "woof";
  }
}

public class Cat extends Animal {
  public Cat() {
    sound = "meow";
  }
}

Or, you can make the Animal class abstract, and declare the speak method abstract too, then define it in subclasses:

public abstract class Animal {
  public abstract String speak();
}

public class Dog extends Animal {
  public String speak {
    return "woof";
  }
}

public class Cat extends Animal {
  public String speak {
    return "meow";
  }
}
like image 21
Grodriguez Avatar answered Oct 23 '22 11:10

Grodriguez