我有一个抽象的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的构造函数中的第一行这个方案不起作用。所以我想知道是否有不同的方式/设计模式来解决这个问题?
答案 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);