Others have noted that constructors may have access modifiers; an aspect not yet mentioned is that the aspect modifiers on a constructor control two very different aspects of construction, but do not allow them to be controlled separately:
- Who is allowed to create instances of
ClassName
and what constructors are they allowed to use.
- Who is allowed to create extensions of
ClassName
and what constructors are they allowed to use.
Both Java and .NET require that the answers to those two questions go together; if a class isn't final
(or sealed
) and allows a constructor to be used by outside code to create new instances, then outside code will also have total freedom to use that same constructor to create derived types.
In many cases, it may be appropriate for a class to have only package-private (internal
) constructors, but expose public methods that return new instances. Such an approach might be used if one were designing a type like String
from scratch; a package including String
could define it as an abstract type but include concrete derived types like AsciiString
and UCS16String
which store their content as a byte[]
and Char[]
, respectively; methods that return String
could then return one of the derivatives depending upon whether the string contained characters outside the ASCII range. If neither String
nor any derived types expose any constructors outside its package, and all derived types within the package behave as a string would be expected to behave, then code which receives a reference of type String
could expect it to behave sanely as a string (e.g. guaranteeing that any observations about its value will forevermore remain true). Exposing constructors outside the package, however, would make it possible for derived types to behave in weird and bizarre fashion (e.g. changing their contents after they've been examined and validated).
From a syntactical perspective, being able to say Fnord foo = new Fnord(123);
is a little nicer than having to say Fnord foo = Fnord.Create(123);
, but a class Fnord
that requires the latter syntax can maintain much better control over the object-creation process.