在Java抽象类中使用受保护字段

在Java抽象类中使用受保护字段,java,abstract-class,encapsulation,Java,Abstract Class,Encapsulation,我目前在一个基于Java的大学课堂上,教授正在使用protected字段对样本进行编码,以供子类访问 我问这是否是一个坏习惯,并被告知这是正常的。这是真的吗?为什么不为抽象方法使用setter和getter呢?我认为,除非另有要求,否则尽可能多地限制信息始终是最佳做法 我在abstractparent中使用setter和getter进行了测试,对于子类化的abstract父类来说效果很好。虽然抽象类不能被实例化,但据我所知,当子类被实例化时,它们仍然可以用来创建对象 下面是一个简短的例子: pu

我目前在一个基于Java的大学课堂上,教授正在使用
protected
字段对样本进行编码,以供子类访问

我问这是否是一个坏习惯,并被告知这是正常的。这是真的吗?为什么不为抽象方法使用setter和getter呢?我认为,除非另有要求,否则尽可能多地限制信息始终是最佳做法

我在
abstract
parent中使用setter和getter进行了测试,对于子类化的
abstract
父类来说效果很好。虽然抽象类不能被
实例化
,但据我所知,当
子类被
实例化时,它们仍然可以用来创建对象

下面是一个简短的例子:

public abstract class Animal {
    protected int height;
}

public class Dog extends Animal {
    public Dog() {
        height = 6;
    }
}

public class Cat extends Animal {
    public Cat() {
        height = 2;
    }
}
相对于使用:

public abstract class Animal {
    private int height;

    public getHeight() {
        return height;
    }

    public setHeight(int height) {
        this.height = height;
    }
}

public class Dog extends Animal {
    public Dog() {
        setHeight(6);
    }
}

public class Cat extends Animal {
    public Cat() {
        setHeight(2);
    }
}

在第一个示例中,只有动物的子类可以访问受保护的字段高度。 在第二个示例中,任何类都可以通过公共setter方法间接操纵字段高度。
看到区别了吗?

虽然您当然可以两种方式都做,但是
受保护的
字段方式不太可取,我认为不太惯用,特别是如果这是您计划共享的库代码

您可以在JavaCollectionsAPI和Guava中看到这一点。您将很难找到具有
受保护
字段(更不用说任何字段)的
抽象

也就是说,总是存在异常,并且您并不总是编写库代码(即公共api)

下面是我对
受保护的
和/或
私有的
字段和抽象类的看法。如果要执行此操作,请创建一个接受初始值的构造函数:

public abstract class Animal {
    private int height;
    public Animal(int height) { this.height = height; }
    public int getHeight() { return this.height }
}

public class Cat extends Animal {
    public Cat() {
        super(2);
    }
}

现在,您的子类需要将height设置为某个值,因为它们必须调用获取height的构造函数。

发布一些代码。很难理解你的论点。添加了一些简短的代码,如果不够说明,请告诉我。如果你阅读Java语言源代码,你会发现受保护字段有很多用途。我不怀疑受保护字段是否有用,但我只是想知道,在这种情况下,在抽象类中是否有理由使用受保护字段?或者如果private+setters/getter更好呢?尽管您在第二个示例中实现了相同的目标,但是您添加了第一个示例没有公开的公共API。您的新实现是可变的。他可以轻松地使setter也受到保护。好的,我知道您来自哪里。除了安全方面,如果您通过getter和setter访问抽象类数据,那么您可以选择以任何方式实现甚至重新实现抽象类实现,而不破坏子类实现。这就是我要寻找的。因此,在您给出的这个示例中,使用private而不是protected会更好吗?我只是想弄清楚private+getter/setter是否比抽象类中的受保护字段更好。非常感谢。您的指导老师可能也在尝试教您传统的OOP,它确实涉及许多状态被继承,特别是在某些框架(如Swing)中。在现代Java中,这是被回避的。抽象类用于共享行为而不是状态(GOF的书也支持这一点)。状态的继承非常糟糕,除非它的getter/setter对象(又名POJO)是出于枯燥的原因而进行的。也就是说,行为对象通常没有太多的getter和setter,但数据对象有,所以短的是yes。更喜欢对字段进行私有保护。为什么要对字段进行保护而不是私有保护?有效点,第66条。很抱歉更新了一篇4年前的文章,但我相应地编辑了Adam Gent的代码。