Adam Thompson
Adam Thompson

Reputation: 3506

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.

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? 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. Although abstract classes cannot be instantiated, they can still be used to create objects when a subclass is instantiated as far as I understand.

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

Upvotes: 7

Views: 10007

Answers (2)

Adam Gent
Adam Gent

Reputation: 49085

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.

You can see this in the Java Collections API as well as Guava. You will be hard pressed to find Abstract classes that have protected fields (let alone any fields).

That being said there are always exceptions and you are not always writing library code (ie public api).

Here is my opinion on protected and/or private fields and abstract classes. 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.

Upvotes: 6

Darren
Darren

Reputation: 792

In your first example, only subclasses of Animal can access the protected field height. In you second example, any class whatsoever can manipulate the field height indirectly via the public setter method. See the difference?

Upvotes: 1

Related Questions