abstract class NumberFormat - very confused about

2019-01-26 16:42发布

问题:

I'm new to Java and I have a beginner question:

NumberFormat is an abstract class and so I assume I can't make an instance of it. But there is a public static (factory?) method getInstance() that allow me to do

NumberFormat nf = NumberFormat.getInstance();  

I'm quite confuse. I'll be glad if someone could give me hints on:

  1. If there is a public method to get an instance of this abstract class, why don't we have also a constructor?
  2. This is an abstract class ; how can we have this static method giving us an instance of the class?
  3. Why choosing such a design? If I assume it's possible to have an instance of an abstract class (???), I don't get why this class should be abstract at all.

Thank you.

回答1:

  1. The class is abstract because it is the base class for every number format in Java (this includes DecimalFormat, for example). Having a constructor for an essentially unknown number format is pretty useless.
  2. The getInstance() method is a so-called factory method. It returns a matching number format for the current locale. Since it is not known what kind of sub-class is required at compile-time, it returns a NumberFormat, however, the instance itself, will be of a sub-type, obviously (since you can't create instances of abstract classes).
  3. This design gives you the flexibility of somehow determining the proper subclass instance to return at runtime without making too much of that design rigid at design/compile time. Static methods are exempt from being abstract so a class can work as both a factory and an abstract supertype for concrete implementations. If this weren't the case you'd probably have a NumberFormatFactory somewhere which would have the factory methods.


回答2:

Actually what you can obtain from

public static final NumberFormat getInstance()

is something that is ALSO a NumberFormat, but it is a concrete instance of a subclass of it.

You can't in anyway instantiate an abstract class so that method can't return a plain NumberFormat but something that is at least a NumberFormat. In this case the method is used to obtain a default formatter for your locale that will probably be a DecimalFormat or some variations of it

In the documentation of DecimalFormat it states:

To obtain a NumberFormat for a specific locale, including the default locale, call one of NumberFormat's factory methods, such as getInstance(). In general, do not call the DecimalFormat constructors directly, since the NumberFormat factory methods may return subclasses other than DecimalFormat.

To end: you can be sure, if it's abstract, then you cannot instantiate it, neither Java itself can.. since the declaration is missing some parts so it's a real incomplete type.