Java继承......困惑

时间:2011-04-25 18:47:02

标签: java inheritance

我有一个抽象的父类,它有多个子节点。我希望孩子能够拥有一个对于该孩子的每个实例都相同的变量。我宁愿不将一个构造函数传递给孩子来告诉它它的名字,因为当它可以被硬编码时,它看起来很愚蠢。从我读到的内容中,执行以下操作“隐藏”父实例变量并且不能按我的意愿工作。

public abstract class Parent {
    public String name = "the parent";
    public getName(name);
}
public class Child1 extends Parent {
    public String name = "Jon";
}
public class Child2 extends Parent {
    public String name = "Mary";
}

Child1 c = new Child1();
c.getName(); // want this to return "Jon", but instead returns "the parent".

要清楚,基本上我想要的是像c.getClass()。getName(),但我不想让它的结果依赖于类名,而是依赖于硬编码值。

由于

8 个答案:

答案 0 :(得分:6)

您可以在父级中声明一个抽象方法,并让每个子级实现该方法以返回相应的名称,如下所示:

public abstract class Parent {
    public abstract String getName();
}

public class Child1 extends Parent {
    private static final String NAME = "Jon";
    public String getName() { return NAME; }
}

public class Child2 extends Parent {
    private static final String NAME = "Mary";
    public String getName() { return NAME; }
}

答案 1 :(得分:3)

在每个具有您的硬编码名称的孩子中创建static final String

public class Child1 extends Parent 
{
    public static final String NAME = "Jon";
}

答案 2 :(得分:3)

使用方法而不是字段(变量):

public abstract class Parent {
  public String getName() {
    return "the parent";
  }
}

public class Child1 extends Parent {
  public String getName() {
    return "Jon";
  }
}
public class Child2 extends Parent {
  public String getName() {
    return "Mary";
  }
}

至少在Java中,你只能覆盖方法而不是变量。

另一个选择是让Parent的构造函数将名称作为参数。如果你这样做,最好是Parent是抽象的,并且所有构造函数都采用name参数。然后,子类需要传入名称,通常会执行以下操作:

public class Child1 extends Parent {
  public Child1() {
    this("Jon");
    // ...
  }
}

实际上,即使使用方法覆盖方法,如果Parent是抽象的,那么你可以使getName()抽象化。

答案 3 :(得分:3)

根据您实际尝试的内容,有几种解决方案。一种是让子类为父级提供名称:

public abstract class Parent {
    protected Parent(String name) {
        this.name = name;
    }
    public getName() {return name;}
}
public class Child1 extends Parent {
    public Child1() {
        super("Jon");
    }

}
public class Child2 extends Parent {
    public Child2() {
        super("Mary");
    }
}

另一种方法是使用方法继承like Isaac Truett suggests

答案 4 :(得分:1)

您对getName()的调用未返回孩子姓名的原因是您在孩子中创建了一个新的变量调用名称。试试这个:

public class Child3 extends Parent{
    public String name = "Jon";

    public String getNames(){
        return super.name + " : " + name;
    }
}

你会看到:

the parent : Jon

将子项名称设置为父项name变量的正确方法是:

super.name = "Jon";

答案 5 :(得分:0)

您需要覆盖getName函数才能获得所需的结果。 因为新的String名称没有替换父名称,所以getName函数实际上是在读取父String

答案 6 :(得分:0)

为什么不使用构造函数?

public abstract class Parent {
    public String name = "the parent";
    public String getName() {
      return name;
    }
    public void setName(String s){
      name = s;
    }
}
public class Child1 extends Parent {
    public Child1() {
      setName("Jon");
    }
}
public class Child2 extends Parent {
    public Child2() {
      setName("Mary");
    }
}

Child1 c = new Child1();
c.getName(); 

//打印'Jon'

答案 7 :(得分:0)

你可以使用Java Reflection来做到这一点......但这不是一种非常干净的做事方式:

public abstract class Parent {
    public String name = "the parent";
    public String getName() throws Exception { return getClass().getField("name").get(this).toString(); }
}

虽然我认为艾萨克的方法是解决方案的最佳方式。