在子类中设置超类字段

Posted

技术标签:

【中文标题】在子类中设置超类字段【英文标题】:setting superclass fields in subclass 【发布时间】:2012-04-10 03:25:48 【问题描述】:

我有一个抽象的 Java 类,它有一个哈希码字段,应该由具体的子类初始化。我正在考虑使初始化方法抽象,即,

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

【问题讨论】:

作为风格说明:有一个名为setSomething() 的方法很尴尬,它不设置任何值而是返回计算值。 calculateHashcodedetermineHashcode 可能会更好地表达方法的意图。 您可能会发现this question 和this question 中的信息很有用。 【参考方案1】:

但是由于对 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));
    

【讨论】:

【参考方案2】:

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

public abstract class Base 
  protected abstract int getHashCode();

这更好,因为方法的“意图”被保留,而不管其存储要求如何。

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

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

变化:

abstract int setHashcode(); 

收件人:

abstract int getHashcode(Object...objects); 

并且子类需要检查传递的对象的数量和类型。

然后你拨打这样的电话:

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

【讨论】:

以上是关于在子类中设置超类字段的主要内容,如果未能解决你的问题,请参考以下文章

如果子类调用超类方法,将使用其字段的 Java

无法从超类访问 Django 模型的子类

使超类字段可观察

休眠:覆盖(实体)超类的 OneToMany 映射字段?

只读字段作为子类构造函数的目标

Java基础学习笔记