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

Ada*_*son 6 java abstract-class encapsulation

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

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

我使用setter和getter测试了abstract父级,它适用于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;
    }
}
Run Code Online (Sandbox Code Playgroud)

与使用相反:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Ada*_*ent 6

虽然您当然可以同时采用两种方式,但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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 您的讲师也可能正在尝试教您传统的 OOP,这确实涉及继承大量状态,特别是在 Swing 等框架中。在现代 Java 中,这种情况被回避了。抽象类用于共享行为而不是状态(GOF 书也赞成这一点)。状态的继承是相当令人讨厌的,除非它的 getter/setter 对象(又名 POJO)是出于 DRY 原因而完成的。也就是说,行为对象通常不会有大量的 getter 和 setter,但数据对象却有。 (2认同)