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

前端 未结 7 1381
天命终不由人
天命终不由人 2021-01-04 03:39

Inheritance.java

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

            


        
相关标签:
7条回答
  • 2021-01-04 03:49

    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");
        }
    }
    
    0 讨论(0)
  • 2021-01-04 03:52

    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.

    0 讨论(0)
  • 2021-01-04 03:52

    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.

    0 讨论(0)
  • 2021-01-04 03:54

    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]

    0 讨论(0)
  • 2021-01-04 03:57

    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";
      }
    }
    
    0 讨论(0)
  • 2021-01-04 04:00

    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'.

    0 讨论(0)
提交回复
热议问题