这是制作继承对象的唯一方法吗?

Is this the only way to make inherited objects?

public class Animal
{
    public String name;
    public boolean legs;
    public boolean eyes;

    public Animal(String name, boolean legs, boolean eyes)
    {
        this.name = name;
        this.legs = legs;
        this.eyes = eyes;
    }
}

public class Dog extends Animal
{
    String name;
    boolean legs;
    boolean eyes;
    public boolean vacinated;
    public boolean rabid;
    public Dog(boolean vacinated, boolean rabid, String name, boolean legs, boolean eyes)
    {
        super(name, legs, eyes);
        this.vacinated = vacinated;
        this.rabid = rabid;
    }
}

public class Bulldog extends Dog
{
    String name;
    boolean legs;
    boolean eyes;
    public boolean vacinated;
    public boolean rabid;
    public String breedtype;

    public Bulldog(String breedtype, String name, boolean legs, boolean eyes, boolean vacinated, boolean rabid)
    {
        super(vacinated, rabid, name, legs, eyes);
        this.breedtype = breedtype;
    }
}

如您所见,如果这种情况一直持续下去,换句话说,如果我的继承线真的很长,我真的需要一遍又一遍地列出每个变量吗?我只是觉得有一种更有效的方法可以做到这一点。

您的 classes 违反了 OOP。您应该定义可以由 protected 继承到 child classes 的公共属性。这意味着 child classes 可以访问那些

其次,公共属性应该在parent class中定义,不需要在child中定义re-created。

P/S:由 BlackFlash 评论更新。我将对此类公共属性使用 private 修饰符。在这个问题的范围内,child classes不需要访问parent的属性。

您的 classes 应更改如下:

public class Animal
{
  private String name;
  private boolean legs;
  private boolean eyes;

  public Animal(String name, boolean legs, boolean eyes)
  {
    this.name = name;
    this.legs = legs;
    this.eyes = eyes;
 }
}

public class Dog extends Animal
{
   private boolean vacinated;
   private boolean rabid;
   private Dog(boolean vacinated, boolean rabid, String name, boolean legs, boolean eyes)
    {
      super(name, legs, eyes);
      this.vacinated = vacinated;
      this.rabid = rabid;
  }
}

public class Bulldog extends Dog
{
   private String breedtype;
   public Bulldog(String breedtype, String name, boolean legs, boolean eyes, boolean vacinated, boolean rabid)
   {
    super(vacinated, rabid, name, legs, eyes);
    this.breedtype = breedtype;
  }
}

这违反了整个 OOP 概念。您可以将父 class 中的公共变量作为 protected 变量,以便它可以被 class 及其子项访问。

不仅变量而且公共方法都可以在父class中定义和实现为受保护的。

Read more here

这是您正在做的问题之一的更简单示例:

class A {
  String a;

  A(String a) { this.a = a; }
}

class B extends A {
  String a;

  A(String a) { super(a); }
}

此代码可能会产生您意想不到的结果:

B b = new B("hello");
System.out.println(b.a);  // null

这可能会让您感到惊讶,因为看起来您似乎是通过 super(a) 调用在 A 的构造函数中初始化了 a

但更令人惊讶的是,如果将其转换为 A,它 不会 打印 null:

System.out.println(((A) b).a);  // hello

这看起来很奇怪:当您将其视为不同类型时,它会打印不同的内容。

这里的问题是 Java 中的字段不是多态的:B 中的 a 隐藏了 aA。这两个字段都在那里,但是当您在 B 类型的变量上引用 a 时,您将获得与在 [=16= 类型的变量上引用 a 时不同的字段].

为了使这个工作 "less confusingly",不要在 B 中重复 a 的声明:

class A {
  String a;

  A(String a) { this.a = a; }
}

class B extends A {
  A(String a) { super(a); }
}

现在:

B b = new B("hello");
System.out.println(b.a);  // hello
System.out.println(((A) b).a);  // hello