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

时间:2015-10-15 01:55:47

标签: java abstract-class encapsulation

我目前在基于Java的大学课程中,对于编码样本,教授正在使用protected字段供子类访问。

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

我使用带有abstract父级的setter和getter测试了它,它适用于子类的abstract父类。虽然抽象类不能是instantiated,但据我所知,当subclassinstantiated时,它们仍可用于创建对象。

这是一个简短的例子:

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);
    }
}

2 个答案:

答案 0 :(得分:4)

虽然你当然可以同时采用这两种方式protected字段方式不太理想,但如果这是你打算分享的图书馆代码,我会认为不那么惯用。

您可以在Java Collections API和Guava中看到这一点。您将很难找到具有Abstract字段的protected类(更不用说任何字段)。

话虽如此,但总是存在例外,并且您并不总是在编写库代码(即公共API)。

以下是我对protected和/或private字段和抽象类的看法。如果你打算这样做,而不是制作一个带有初始值的构造函数:

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);
    }
}

现在你的子类需要设置高度,因为他们必须调用占用高度的构造函数。

答案 1 :(得分:1)

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