【问题标题】:Superclass' fields: private+accessors vs protected [closed]超类的字段:private+accessors vs protected [关闭]
【发布时间】:2013-08-19 16:24:25
【问题描述】:

片段#1:

public abstract class SuperClass {
    protected int i;   
}

public class SubClass extends SuperClass {
    public void method() {
        i = doAnythingWithI(i); // for example
    }
}

片段#2:

public abstract class SuperClass {
    private int i;    
    protected int getI() {
        return i;
    }    
    protected int setI(int i) {
        this.i = i;
    }
}

public class SubClass extends SuperClass {
    public void method() {
        setI(doAnythingWithI(getI())); // for example
    }
}

为什么要使用一个 sn-p 而不是另一个?最常见的处理方式是什么?

【问题讨论】:

  • 我会说你很可能会使用前一个代码 sn-p 而不是后一个代码 sn-p。正确封装 i 毫无意义,因为您甚至没有使用 set 方法执行任何操作,因此您只是在堆栈上添加更多内容,可能会减慢您的程序。
  • 在第一个sn-p中SuperClassSubClass是紧耦合的,这让我产生疑问,为什么要引入SubClass。在第二个 sn-p 中,i 字段被 get/set 对完全暴露,这对再次将 SubClass 紧密耦合到其父级。这再次提出了同样的问题:为什么要引入SubClass。此外,sn-ps 看起来您想使用继承来实现,但您应该将其用于表现为,而不是实现为。

标签: java inheritance protected


【解决方案1】:

抽象类的一个更常见的用途是拥有不在抽象类中实现的抽象方法,而是在java程序的子类中实现。这显然不是您的用例。但是,抽象类也可以用作防止某人实例化应该首先扩展的类的一种方式。我假设这是你的愿望。

此外,我认为该示例的琐碎性质仅用于说明。否则可能会怀疑有两个类来“管理”单个原始“int”!

鉴于此和两个选择,片段 #2 更接近正确。原因是“类型”希望封装状态、​​数据和行为。 Snippet #1 违反了这一点,通常会被劝阻。

“doAnythingWithI”方法虽然值得讨论。您的示例中并未真正声明它。如果它仅对“i”进行操作并且不受具体类的更改,那么它也属于抽象基类。

如果它可以随着扩展超类的多个实现而变化,那么它可能应该被定义为超类中的抽象方法并由子类实现。

【讨论】:

    猜你喜欢
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    • 2017-04-19
    • 2020-04-25
    • 2020-07-31
    • 1970-01-01
    • 2017-05-29
    • 2017-08-21
    相关资源
    最近更新 更多