java - 继承不允许我创建子类的对象?

标签 java class oop inheritance polymorphism

   class Animal {

    String type;
    int size;

    public Animal(String name, int size)
    {
        this.type = name;
        this.size = size;
    }

    public Animal ()
    {

    }

    public void run() {
        System.out.println("I can run!");
    }

}


class Cat extends Animal {

    String color;

    public void meow() {
        System.out.println("I can meow!");
    }

}

public class HelloWorld{

     public static void main(String []args){

        Animal cat = new Cat();

        cat.meow();
        cat.run();

     }
} 

为什么当我尝试从父类(super class) Animal 创建新的 Cat 对象时,代码的 .meow() 部分出现错误。具体来说是“错误:找不到符号 cat.meow();” 。我不是创建了一个 Cat 对象,所以它不应该访问其中的方法吗?

最佳答案

Animal 是基类。如果您扩展 Animal,您可以在该类中添加其他方法和实例变量,您实际上这样做是正确的。

一旦实例化一个子类(扩展基类的类,例如:new Cat()),但将其分配给基类的类型(Animal) code>)您只能调用那里可用的方法,即在您的情况下,您只能调用 Animal 类中声明的方法。

假设您有一个类Animal:

public class Animal {
  public void makeSound() {
    System.out.println("Default sound");
  }
}

现在您创建一个扩展 Animal 的类 Cat:

public class Cat extends Animal {
  private int catProperty = 5;

  //Override method of base class
  public void makeSound() {
    System.out.println("Meow");
  }

  public int getCatProperty(){
    return this.catProperty;
  }
}

另一个名为 Dog 的类,它扩展了 Animal:

public class Dog extends Animal {
  private int dogProperty = 8;

  //Override method of base class
  public void makeSound() {
    System.out.println("Woof");
  }

  public int getDogProperty(){
    return this.dogProperty;
  }
}

由于 Animal 是基类,您现在可以创建一个 Animal 类型的数组,其中包含 CatsDogs >.

Animal[] animals = new Animal[2];
animals[0] = new Cat();
animals[1] = new Dog();

for (Animal animal : animals) {
  animal.makeSound();
}

每种动物(CatDog)现在都会打印正确的声音。 如果您确实需要调用子类特定方法,则必须将对象强制转换回该子类的实例。在这种情况下,您必须确定子类是什么类型。

例如:

for (Animal animal : animals) {
  // Calls overriden method
  animal.makeSound();
  // This is illegal. Method getCatProperty is not declared in Animal  
  animal.getCatProperty();
  // This is illegal. Method getDogProperty is not declared in Animal class
  animal.getDogProperty();

  /*
   * IF YOU HAVE TO CALL CHILD CLASS SPECIFIC METHODS, DO IT LIKE THIS:
   */

  // Checks if animal is of type Cat
  if (animal instanceof Cat) {
    // Casts animal to instance of Cat
    Cat cat = (Cat) animal;
    // Calls specific Cat instance method
    System.out.println(cat.getCatProperty());
  }

  // Checks if animal is of type Dog
  if (animal instanceof Dog) {
    // Casts animal to instance of Dog
    Dog dog = (Dog) animal;
    // Calls specific Dog instance method
    System.out.println(dog.getDogProperty());
  }
}

作为旁注:如果您打算不直接创建 Animal 的实例(Animal a = new Animal()),您应该声明类本身以及应由子级重写的方法类作为抽象

public abstract class Animal {
  public abstract void makeSound();
}

此外,如果基类只有方法而没有可供子类使用的实例变量,那么最好使用接口(interface)而不是(抽象)类。

public interface Animal {
  public abstract void makeSound();
}

接口(interface)必须由具体类实现(而不是扩展)。

public class Cat implements Animal {
  public void makeSound() {
    System.out.println("Meow");
  }
}

希望这有帮助!

关于java - 继承不允许我创建子类的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58797481/

相关文章:

java - 这是instanceof 可接受的用法吗?

java - EntityLIstener 未通过级联的 OneToOne 映射调用

java - 奇怪的 JSON 对象解析

ios - 如何在 Swift 2 中将结构转换为 Anyobject?

c++ - 从对象调用成员对象,错误: initial value of reference to non-const must be an lvalue

java - 在这种情况下如何避免代码重复?

java - 数组索引越界

java - 接口(interface)方法的修饰符非法

c# - Parameterless constructor constructor less 类(来自另一个程序集)

c# - 了解 Ref 和 Val 类型有何帮助