Pregunta

I am going through Effective Java. The very first item makes a convincing case for static factory methods over constructors.

I didn't get the first disadvantage which is

The main disadvantage of providing only static factory methods is that classes without public or protected constructors cannot be subclassed.

Why do i need to subclass the class having static factory method since static methods can't be inherited?

Can someone please explain.

¿Fue útil?

Solución

Suppose you have a class called Person:

class Person {
  public static Person createWithFirstName(String firstName) {
    return new Person(firstName, null, null);
  }
  // etc. - more factory methods

  // private constructor
  private Person(String firstName, String lastName, String nickname) { }

  // useful method
  public String getDisplayName() { }
}

It's all good and dandy. But now you also need a class called Programmer, and you suddenly realize the programmers are persons too!

But all of a sudden, you can't just

class Programmer extends Person { }

since Person doesn't have any public constructors.

Otros consejos

For an instance of the subclass to be created, its constructor must be invoked.

And the first thing a constructor must do is to call one of its parent class constructor (the compiler inserts a call to super() for you if you don't explicitely add it).

If all the parent class constructors are private, the subclass can't call any of them, making the parent class effectively final, i.e. impossible to subclass.

Few facts

  • In subclass each constructor must call super(..) (.. may be arguments) at start of its constructors which invokes superclass constructor.
  • To implement correct Static factory pattern all constructors of class with this pattern must be private to prevent instantiating class without using factory method.

So since constructors of base class with factory method must be private, derived class will not be able to call super(..) which will not let subclass to compile.

It means that your class will not support some inheritance features eg you can not override any of it's method , you can not use this as a super type for dynamic dispatch .

When you instantiate a base class the first thing that happens is invocation of its parent class's constructor. If the parent class constructor is private it can't be called from outside the class body hence won't work. Remember while you were reading about inheritance there was one point stating that if you want to use super() it should be first line in the base class constructor, if you don't explicitly use super() in base class compiler automatically puts it there for you. Think what would happen if your parent class constructor is private, the super() call will fail.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top