Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
    }
}
like image 748
Adam Thompson Avatar asked Oct 15 '15 01:10

Adam Thompson


2 Answers

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.

like image 189
Adam Gent Avatar answered Oct 19 '22 10:10

Adam Gent


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?

like image 33
Darren Avatar answered Oct 19 '22 11:10

Darren