Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you force a subclass to initialize a superclass property at compile-time?

Tags:

java

jsf

I have an abstract superclass with a property that must be set by the subclass for proper operation of instances...

abstract SuperClass {
  // this list must be initialized by the subclass
  List<? extends SavedSearch> savedSearches;
}

This abstract superclass has methods that operate on the savedSearches but it's up to the subclass to ensure that list is properly initialized.

What's the best way to do this?

It's easy with Java create superclass methods that must be implemented by subclasses, but not properties. I thought about requiring an abstract initSavedSearch method like this in the superclass...

abstract initSavedSearchList();

... but that seemed strange, the subclass implementer is under no obligation to do anything in their method implementation, they could just do nothing.

I know I can code up some runtime checks to make sure the savedSearch list is init'd before running code in the superclass, but I'm hoping for compile-time checks (akin to to abstract methods) not runtime checks.

I saw a C# answer to a similar question which suggests hiding the default (zero-arg) constructor and creating a constructor in the abstract class that requires the list as an arg. That sounds decent for Java, too. But my particular class is a JSF 1.x managed bean. I'm a JSF newbie, but AFAIK there's no easy way to get JSF to call a non-standard constructor for Managed Beans.

Is there a way to do this where I get some compile-time help to ensure that implementing subclasses are properly initializing a superclass property?

Thanks!

  • Gary
like image 801
Gary Affonso Avatar asked Sep 08 '11 18:09

Gary Affonso


1 Answers

One of the ways is to provide a constructor which takes that as argument.

public abstract class SuperClass {

    private List<SavedSearch> savedSearches;

    protected SuperClass(List<SavedSearch> savedSearches) {
        this.savedSearches = savedSearches;
        // You can do additional checks here on null, size(), etc.
    }

}

The subclasser is required to invoke that constructor.

public class SubClass extends SuperClass {

    public SubClass() {
        super(initAndGetSavedSearchesSomehow());
    }

}
like image 155
BalusC Avatar answered Oct 21 '22 04:10

BalusC