I was wondering if the below code makes any sense, since the compiler warns that "the blank final field objects may not have been initialized". Is there a better way of doing this?
public abstract Test { protected final ArrayList<Object> objects; } public TestSubA extends Test { public TestSubA() { objects = new ArrayList<Objects>(20); // Other stuff } } public TestSubB extends Test { public TestSubB() { objects = new ArrayList<Objects>(100); // Other stuff } }
An abstract class may contain non-final variables. Type of variables: Abstract class can have final, non-final, static and non-static variables. The interface has only static and final variables.
Declaring abstract method final Similarly, you cannot override final methods in Java. But, in-case of abstract, you must override an abstract method to use it. Therefore, you cannot use abstract and final together before a method.
Constructors: b. Since an abstract class can have instance variables. Therefore, we can define constructors within the abstract class to initialize instance variables.
Abstract classes in Java are classes which cannot be instantiated, meaning we cannot create new instances of an abstract class. The purpose of an abstract class is to function as a base for subclasses. but why java allows to define data member in an abstract class, where we can not create object of an abstract class.
I would make the field final and force the constructors to pass the value up:
public abstract class Test { private final ArrayList<Object> objects; protected ArrayList<Object> getObjects() { return objects; } protected Test(ArrayList<Object> objects) { this.objects = objects; } } public class TestSubA extends Test { public TestSubA() { super(new ArrayList<Object>(20)); // Other stuff } } public class TestSubB extends Test { public TestSubB() { super(new ArrayList<Object>(100)); // Other stuff } }
The problem with initializing the final parameters directly in the constructor of the sub-classes is that you need to do it all in one line since super() must be the first statement of the constructor. So instead, I prefer to make the constructor non-public and make a static build method like this:
public abstract class Test { protected final ArrayList<Object> objects; protected Test(ArrayList<Object> objects) { this.objects = objects; } } public class TestSubA extends Test { public static TestSubA build() { ArrayList<Object> objects = new ArrayList<Object>(20); objects.put(...); // Other stuff return new TestSubA(objects); } private TestSubA(ArrayList<Object> objects) { super(objects); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With