【问题标题】:Inheritance not allowing me to create an object of subclass?继承不允许我创建子类的对象?
【发布时间】:2020-03-06 21:52:41
【问题描述】:
   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();

     }
} 

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

【问题讨论】:

  • 您不会被阻止创建实例。您无法通过对超类实例的引用来调用子类的方法。

标签: java class oop inheritance polymorphism


【解决方案1】:

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

一旦您实例化了一个子类(扩展基类的类,例如:new Cat())但将其分配给基类的类型(Animal),您就只能调用那里可用的方法,即在您的情况下,您只能调用在 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 是基类,您现在可以创建一个包含CatsDogsarray of type Animal

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

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

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

例如:

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()) 的实例,则应将类本身和应被子类覆盖的方法声明为 abstract

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

另外,如果基类只有子类可用的方法而没有实例变量,最好使用接口而不是 (abstract) 类。

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

那么具体类的接口必须是implemented(而不是extended)。

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

希望这会有所帮助!

【讨论】:

  • 注意:您的源示例充满了拼写错误和错误的语法。请做得更好。随着时间的推移,数百人将阅读您的内容。不要将它们与甚至无法编译的“类似 java”的代码混淆。
  • @GhostCatsaysReinstateMonica,是的,你完全正确。感谢您的提示。现在一切都应该是正确的。下次我将直接在我的 IDE 中编写代码。
【解决方案2】:

动物猫 = new Cat()

编译器“忘记”你创建了一个 Cat 实例。

您的源代码显示:我有一个名为 cat 的变量,它是 Animal 的一个实例。

Animal 类上没有方法meow()

如果要调用子类方法,则需要一个子类实例:

Cat cat = new Cat();
cat.meow();

或者你需要投射。基本上你告诉编译器:“我比你更清楚”。

Animal cat = new Cat();
( (Cat) cat).meow();

重点是:java 是静态类型的。在 python 中,解释器只会查看 cat 是否有一个可以调用的名为 meow() 的方法。在 Java 中不能这样工作。

【讨论】:

  • 那么创建 Animal a = new Cat(); 实例的目的是什么?是?我在网上看到继承允许的事情之一是给定类 A 是超类而类 B 是子类,你可以有 A obj = new B();但现在我看不出这样做的目的,如果它只是创建一个 A 的实例,它无法访问 B 中的方法。
  • @krauser126 当您不关心特定子类时,您使用基类。例如,您有一个“命令”类,它有一个“执行”方法。以及许多不同的子类。但是您所有其他代码只关心 Command 对象。您可能有命令列表,并且您唯一要做的事情是:调用该执行方法。但请注意:这些都是非常基本的 OOP 问题。这些东西都写在任何一本好书中。始终尝试先做好研究。问别人应该是你的最后选项,而不是你的第一个方法......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多