在子类中设置超类字段

时间:2012-04-10 03:25:49

标签: java design-patterns

我有一个抽象的Java类,它有一个hashcode字段,应该由具体的子类初始化。我在想初始化方法是抽象的,即

abstract class A {
  protected int hashcode;
  // hashcode should be initialized in constructor
  protected A () { hashcode = setHashcode(); }
  abstract int setHashcode() {} // implemented by subclasses
}

但不幸的是,不同的子类需要为setHashcode接受不同数量的参数,例如,B类可能使用其两个字段计算哈希码,而C类可能需要三个,但由于对super的调用必须是B的构造函数中的第一行这个方案不起作用。所以我想知道是否有不同的方式/设计模式来解决这个问题?

4 个答案:

答案 0 :(得分:2)

  

但由于对super的调用必须是B的构造函数中的第一行,因此该方案不起作用

为什么它不起作用?如果将哈希代码的计算放在子类的静态函数中,则可以将预先生成的哈希代码传递给超类的构造函数。

class BaseClass {
    private int hashCode;
    protected BaseClass(int hashCode) {this.hashCode = hashCode;}
}
class DerivedClass : BaseClass {
    private static int calcHash(String str) {
        return str.hashCode();
    }
    public DerivedClass(String s) {
        super(calcHash(str));
    }
}

答案 1 :(得分:2)

您实际上不需要将值存储在超类中,只需声明子类将覆盖的抽象getHashCode

public abstract class Base {
  protected abstract int getHashCode();
}

这样做更好,因为无论存储要求如何,都会保留方法的“意图”。

顺便说一句,hashCode已经在Object中定义,并且可以被子类覆盖。如果您的哈希码概念与Object提供的概念不同,也许您应该重命名它。

答案 2 :(得分:1)

听起来好像接口可能适合初始化,因此您创建的任何子类都可能只是重载接口实现。

答案 3 :(得分:0)

变化:

abstract int setHashcode(); 

要:

abstract int getHashcode(Object...objects); 

子类需要检查传递的对象的计数和类型。

然后你拨打电话:

  hashcode = getHashcode(); 
  hashcode = getHashcode(o1); 
  hashcode = getHashcode(o1,o2);