public class InheritanceExample {
static public void main(String[] args){
Cat c = new Cat();
System.out.println(c.speak());
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");
}
}
You're hiding fields. The sound
in Animal
is not the same String
as the sound
in Cat
.
One possible solution is to create a constructor and there simply say
super.sound = "meow";
instead of in the class body saying
protected String sound = "meow";
to set the field.
You're shadowing the field inherited from Animal
. You have a few options, but the prettiest way of doing it is passing the sound in the constructor:
public class Animal {
private final String sound;
protected Animal(String sound){
if (sound == null)
throw new NullPointerException("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"); }
}
This way, you can make sure that an Animal
always has a valid sound, right from construction.
A method will look in its own class' namespace to resolve fields. While methods defined in sub-classes can look up the hierarchy to resolve fields, the same is not true for classes defined higher up in the hierarchy, i.e., super-classes won't look down the hierarchy to resolve fields [and their values]
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";
}
}
You didn't allow your animals to speak! you should do like this :
Cat.java:
public class Cat extends Animal {
// protected String sound = "meow";
public Cat(){
this.sound = "cat";
}
}
Dog.java:
public class Dog extends Animal {
// protected String sound = "woof";
public Dog(){
this.sound = "dog";
}
}
just because there are two members "sound" in Cat or Dog,and the one inherited from Animal is hidden without value(so it prints null);another is special to Cat or Dog,which is assigned a value. So you should use the pointer 'this' to quote the original member 'sound'.