Java 字段必须是机密的,但子类必须重写使用此字段的方法?

Java 字段必须是机密的,但子类必须重写使用此字段的方法?,java,Java,我有一个设计问题: 问题类:有一个问题和答案(字符串) 文本问题类:普通文本问答 NumberQuestion类:问题(字符串)、答案(number-int、float…)和使用ε值检查答案 但是我有一个数字问题。我必须采取正确的答案,转换成数字,并与用户的答案进行比较。那我怎么才能得到答案呢?使用getter方法不安全。还是我的设计不好?我怎样才能改变 我不确定您是否熟悉泛型类,但这在本例中是合适的。你可以在谷歌上搜索它。:-) 如果您不想这样做,您始终可以将您的答案和this.answe

我有一个设计问题:

  • 问题类:有一个问题和答案(字符串)
  • 文本问题类:普通文本问答
  • NumberQuestion类:问题(字符串)、答案(number-int、float…)和使用ε值检查答案
但是我有一个数字问题。我必须采取正确的答案,转换成数字,并与用户的答案进行比较。那我怎么才能得到答案呢?使用getter方法不安全。还是我的设计不好?我怎样才能改变


我不确定您是否熟悉泛型类,但这在本例中是合适的。你可以在谷歌上搜索它。:-)


如果您不想这样做,您始终可以将
您的答案
this.answer
转换为同一类型,然后您可以找到绝对差异,并确保它们低于特定阈值

我不确定您是否熟悉泛型类,但这在这种情况下是合适的。你可以在谷歌上搜索它。:-)


如果您不想这样做,您始终可以将
您的答案
this.answer
转换为同一类型,然后您可以找到绝对差异,并确保它们低于特定阈值

如果您的答案可以有不同的类型,那么您也可以在抽象类中使用泛型

public abstract class Question<T> {
    private final String question;
    protected final T answer;

    public Question(String question, T answer) {
        this.question = question;
        this.answer = answer;
    }

    //Default implementation
    public boolean checkAnswer(T yourAnswer) {
        return answer.equals(yourAnswer);
    }
}

而且要小心,因为BigDecimal类是不可变的(不是完全的,但这是另一个问题),当您尝试更改其状态时会返回新实例。

如果您的答案可以有不同的类型,那么您也可以在抽象类中使用泛型

public abstract class Question<T> {
    private final String question;
    protected final T answer;

    public Question(String question, T answer) {
        this.question = question;
        this.answer = answer;
    }

    //Default implementation
    public boolean checkAnswer(T yourAnswer) {
        return answer.equals(yourAnswer);
    }
}

而且要小心,因为BigDecimal类是不可变的(不是完全的,但这是另一个问题),当您试图更改它的状态时,它会返回新实例。

我不明白为什么您需要对子类(或任何客户机代码)隐藏答案。为了创建
TextQuestion
NumberQuestion
实例,客户端代码首先肯定需要知道答案

您应该从
问题
类中抽象出测试逻辑以及答案类型:

public abstract class Question<AnswerType> {
  private String question;
  private AnswerType answer;

  public Question(String question, AnswerType answer) {
    this.question = question;
    this.answer = answer;
  }

  public abstract boolean checkAnswer(AnswerType yourAnswer);

  protected AnswerType getAnswer() {
    return answer;
  }
}

class TextQuestion extends Question<String> {
  public TextQuestion(String question, String answer) {
    super(question, answer);
  }

  public boolean checkAnswer(String yourAnswer) {
    return answer.equals(yourAnswer);
  }
}

class NumberQuestion extends Question<Double> {
  private double epsilon;

  public NumberQuestion(String question, Double answer, double epsilon) {
    super(question, answer);
    this.epsilon = epsilon;
  }

  public boolean checkAnswer(Double yourAnswer) {
    return Math.abs(getAnswer() - yourAnswer) < epsilon;
  }
}
公共抽象类问题{
私有字符串问题;
私人回答型回答;
公开问题(字符串问题、回答类型答案){
这个问题=问题;
这个答案=答案;
}
公共抽象布尔检查答案(AnswerType yourAnswer);
受保护的应答类型getAnswer(){
返回答案;
}
}
类TextQuestion扩展了这个问题{
公共文本问题(字符串问题、字符串答案){
超级(问题、答案);
}
公共布尔值checkAnswer(字符串yourAnswer){
返回答案。等于(您的答案);
}
}
类编号问题扩展问题{
私有双ε;
公共数字问题(字符串问题、双答案、双ε){
超级(问题、答案);
this.epsilon=epsilon;
}
公共布尔检查答案(答案加倍){
返回Math.abs(getAnswer()-yourAnswer)
我不明白为什么需要对子类(或任何客户端代码)隐藏答案。为了创建
TextQuestion
NumberQuestion
实例,客户端代码首先肯定需要知道答案

您应该从
问题
类中抽象出测试逻辑以及答案类型:

public abstract class Question<AnswerType> {
  private String question;
  private AnswerType answer;

  public Question(String question, AnswerType answer) {
    this.question = question;
    this.answer = answer;
  }

  public abstract boolean checkAnswer(AnswerType yourAnswer);

  protected AnswerType getAnswer() {
    return answer;
  }
}

class TextQuestion extends Question<String> {
  public TextQuestion(String question, String answer) {
    super(question, answer);
  }

  public boolean checkAnswer(String yourAnswer) {
    return answer.equals(yourAnswer);
  }
}

class NumberQuestion extends Question<Double> {
  private double epsilon;

  public NumberQuestion(String question, Double answer, double epsilon) {
    super(question, answer);
    this.epsilon = epsilon;
  }

  public boolean checkAnswer(Double yourAnswer) {
    return Math.abs(getAnswer() - yourAnswer) < epsilon;
  }
}
公共抽象类问题{
私有字符串问题;
私人回答型回答;
公开问题(字符串问题、回答类型答案){
这个问题=问题;
这个答案=答案;
}
公共抽象布尔检查答案(AnswerType yourAnswer);
受保护的应答类型getAnswer(){
返回答案;
}
}
类TextQuestion扩展了这个问题{
公共文本问题(字符串问题、字符串答案){
超级(问题、答案);
}
公共布尔值checkAnswer(字符串yourAnswer){
返回答案。等于(您的答案);
}
}
类编号问题扩展问题{
私有双ε;
公共数字问题(字符串问题、双答案、双ε){
超级(问题、答案);
this.epsilon=epsilon;
}
公共布尔检查答案(答案加倍){
返回Math.abs(getAnswer()-yourAnswer)
什么叫“不安全”?你想避免什么样的风险?@TedHopp:这意味着所有类(除了它的子类)都可以得到答案。什么叫“不安全”?你想避免什么样的风险?@TedHopp:这意味着所有类(除了它的子类)都可以得到答案。OP想用类似于
Math.abs(答案-你的答案)
的方法来回答数字问题
equals()
通常不适用于浮点比较。是。但是他可以很容易地更改子类中的默认实现。@dimas:但是我如何检查NumberQuestion中的答案呢?你的答案是什么?好的。为了检查答案,我建议将问题类中的答案字段设置为受保护的和最终的(这样,在对象创建之后,没有人可以更改它)。我将根据这一点放弃我的回答。不。我无法想象这样的解决方案。OP想用类似于
Math.abs(答案-你的答案)
的东西来回答数字问题
equals()
通常不适用于浮点比较。是。但是他可以很容易地更改子类中的默认实现。@dimas:但是我如何检查NumberQuestion中的答案呢?你的答案是什么?好的。为了检查答案,我建议将问题类中的答案字段设置为受保护的和最终的(这样,在对象创建之后,没有人可以更改它)。我将根据这一点放弃我的回答。不。我无法想象这样的解决方案。OP出于某种原因想对子类保密
answer
。OP出于某种原因想对子类保密
answer
。好的,谢谢你的回答。我想问这个问题
public abstract class Question<AnswerType> {
  private String question;
  private AnswerType answer;

  public Question(String question, AnswerType answer) {
    this.question = question;
    this.answer = answer;
  }

  public abstract boolean checkAnswer(AnswerType yourAnswer);

  protected AnswerType getAnswer() {
    return answer;
  }
}

class TextQuestion extends Question<String> {
  public TextQuestion(String question, String answer) {
    super(question, answer);
  }

  public boolean checkAnswer(String yourAnswer) {
    return answer.equals(yourAnswer);
  }
}

class NumberQuestion extends Question<Double> {
  private double epsilon;

  public NumberQuestion(String question, Double answer, double epsilon) {
    super(question, answer);
    this.epsilon = epsilon;
  }

  public boolean checkAnswer(Double yourAnswer) {
    return Math.abs(getAnswer() - yourAnswer) < epsilon;
  }
}