简体   繁体   English

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

[英]Using Protected Fields in Abstract Class in Java

I'm currently in a Java-based university class and for coding samples the professor is using protected fields for the subclasses to access. 我目前在一个基于Java的大学课程中,对于编码样本,教授正在使用protected字段来访问子类。

I asked if this was bad practice and was told it is normal. 我问这是不好的做法,并被告知这是正常的。 Is this true, why not use setters and getters for abstract methods? 这是真的,为什么不使用setter和getter来抽象方法呢? I thought it was always best practice to restrict as much information as possible unless required otherwise. 我认为除非另有要求,否则最好限制尽可能多的信息。

I tested out using setters and getters with abstract parent and it works fine for abstract parent classes that are subclassed. 我使用setter和getters测试了abstract父级,它适用于子类的abstract父类。 Although abstract classes cannot be instantiated , they can still be used to create objects when a subclass is instantiated as far as I understand. 虽然抽象类不能被instantiated ,它们仍然可以使用,当创建对象subclassinstantiated ,据我了解。

Here is a short example: 这是一个简短的例子:

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

As opposed to using: 与使用相反:

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

While you can certainly do both ways the protected field way is less desirable and I would argue less idiomatic particularly if this is library code that you plan to share. 虽然你当然可以做到这两种方式,但是protected字段方式不太可取,如果这是您计划共享的库代码,我会认为不那么惯用。

You can see this in the Java Collections API as well as Guava. 您可以在Java Collections API和Guava中看到这一点。 You will be hard pressed to find Abstract classes that have protected fields (let alone any fields). 您将很难找到具有protected字段的Abstract类(更不用说任何字段)。

That being said there are always exceptions and you are not always writing library code (ie public api). 话虽如此,但总有例外,你并不总是在编写库代码(即公共API)。

Here is my opinion on protected and/or private fields and abstract classes. 这是我对protected和/或private字段和抽象类的看法。 If you are going to do it than make a constructor that takes the initial values: 如果你要做的比制作一个带有初始值的构造函数:

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

Now your subclasses are required to set height to something as they have to call the constructor that takes height. 现在你的子类需要设置高度,因为他们必须调用占用高度的构造函数。

In your first example, only subclasses of Animal can access the protected field height. 在第一个示例中,只有Animal的子类可以访问受保护的字段高度。 In you second example, any class whatsoever can manipulate the field height indirectly via the public setter method. 在第二个示例中,任何类都可以通过公共setter方法间接操作字段高度。 See the difference? 看到不同?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM