关于java:这是制作继承对象的唯一方法吗?

Is this the only way to make inherited objects?

1
2
3
4
5
6
7
8
9
10
11
12
13
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;
    }
}

ZZU1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
    }
}

如你所见,如果这句话继续下去,换言之,如果我有一条真正长久的遗产线,我是否需要再次列举每一个单一的变量?我只是觉得这样做有一种更有效的方式。


下面是一个简单的例子,说明您正在做的事情中的一个问题:

1
2
3
4
5
6
7
8
9
10
11
class A {
  String a;

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

class B extends A {
  String a;

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

此代码可能会给出您不期望的结果:

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

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

但更令人惊讶的是,如果您将它投射到a,它不会打印null

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

这看起来很奇怪:当你把它当作一个不同的类型时,它会打印出不同的东西。

这里的问题是,在Java中字段不是多态的:EDOCX1 2在EDOCX1中引用8在EDOCX1 2中隐藏EDOCX1 2。这两个字段都存在,但是当您在B类型的变量上引用a时,您会得到与在a类型的变量上引用a时不同的字段。

为了"减少混乱",不要在B中重复a的声明:

1
2
3
4
5
6
7
8
9
class A {
  String a;

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

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

现在:

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

这违反了整个OOP概念。父类中的公共变量可以是protected变量,以便该类及其子类可以访问它。

不仅可以在父类中定义和实现受保护的变量,还可以定义公共方法。

在这里阅读更多


您的类被违反了OOP。您应该定义可以由protected继承到子类的公共属性。这意味着儿童班可以访问

其次,公共属性应该在父类中定义,而不需要在子类中重新创建。

P/S:由Blackflash评论更新。对于这样的公共属性,我将使用私有修饰符。在这个问题的范围内,子类不需要访问父类的属性。

您的课程应更改如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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;
  }
}