声明需要存在于子类中的字段的正确方式



假设我有一个类Animal,然后是一堆扩展Animal的子类。假设我想要一个名为name的公共字段,它也应该存在于每个子类中。在每个子类中包含和初始化该字段的正确方法是什么?

1) 将父类中的字段声明为protected,然后在每个子类中初始化它。如果我这样做,将字段称为super.variable或简称为variable合适吗?就我个人而言,使用super可以更明显地表明字段是在父字段中声明的。(这就是我目前正在做的)

2) 将父级中的字段声明为private,然后创建getterssetters以访问字段

3) 只需在每个子类中声明并初始化相同的变量

4) 我缺少的另一种方法?

谢谢你的帮助。我知道这个问题很基本,但我很好奇最合适的风格是什么

编辑:

我不确定你们是否会看到这个,但这里有一个后续问题。

有什么好的方法可以确保子类初始化字段吗?

答案取决于您是否需要控制对该字段的访问以确保正确性(例如,确保其他字段同时更新)。如果子类可以直接旋转字段,那么只需使用protected。如果在设置字段时需要执行额外的检查或操作,则应将其设为超类的private,并使子类使用setter来确保逻辑运行。如果你知道这个字段总是需要的,你就不应该重复它;如果您不确定,那么您应该考虑使用interface Animal并将字段放在AbstractAnimal implements Animal上。

在Java中,除了调用方法的超类版本之外,不使用super进行任何操作。只需直接访问protected字段;这就是它们的作用,如果需要的话,您的开发环境将跟踪它们的声明位置。

我投票支持2:

创建一个私有字段,并具有setter和getter(可以对它们进行保护,使它们只能由子类访问)。

如果你不需要setter(只需要getter),其他选项:

4) 抽象getter并将其留给子类如何实现

5) 私有最终字段,由抽象类构造函数和getter设置。

我总是将字段设为protected字段,因为这有助于调试性&可扩展性,并将公共getters&setter在他们身上创建一个"属性"。

(各种开源库、Swing组件等中的私有字段一再阻碍我进行合法的调试/扩展工程。所以我相当反对它们。)

如果我关心可追溯性,其中可能涉及行为或错误(例如获取和缓存的值),我可能会通过getter访问子类中的变量。

向变量写入时,我总是使用this.name——它可以很好地提高代码的清晰度,并简化了setter中的参数命名。(仅使用name作为参数,使用this.name作为字段。)

读取变量时,我不使用this——这是我想清楚的写入。对于集合,我在字段后面加上List或map或任何东西,即childList,但参数和局部变量是"children"。

在引用变量时,我从不使用super。Super只有在消除继承&声明的变量具有相同的名称,您可以合法地这样做,但几乎可以保证在代码风格、清晰度和;往往会导致错误。


我还喜欢使大多数属性都是可变的,而不是只在构造时设置。如果您想要使用Hibernate或持久化数据,这会有所帮助。过度依赖构造函数初始化往往会演变成困难——大型&脆弱的调用签名,无法将类用于部分形成的数据或"特殊值"答案,以及初始化顺序问题。

我认为这取决于情况。如果name字段应该是可公开访问的,我会将该字段声明为private,然后使其成为公共的get/set方法。有时,您希望将基类上的字段作为派生类的公共接口的一部分公开。

如果name字段应该只在派生类中使用,我只会使用一个受保护的字段。

如果要确保子类初始化字段,请在基类构造函数中添加参数,然后使用派生类构造函数提供的参数初始化基类中的字段。

我通常使用选项2(private+accessors-protected,而不是必需的public)来定制变量访问。

关于您的编辑:如果是强制性要求,则强制使用构造函数名称

Animal(String name) {
    this.name = name;
}

String getName()  {
    if(null == name){
        name = initializeName();
    }
    return name;
}

并使CCD_ 22抽象

最新更新