Path: csiph.com!usenet.pasdenom.info!gegeweb.org!eternal-september.org!feeder.eternal-september.org!mx02.eternal-september.org!.POSTED!not-for-mail From: Eric Sosman Newsgroups: comp.lang.java.programmer Subject: Re: a question about factory method Date: Thu, 18 Dec 2014 12:04:18 -0500 Organization: A noiseless patient Spider Lines: 72 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Thu, 18 Dec 2014 17:04:02 +0000 (UTC) Injection-Info: mx02.eternal-september.org; posting-host="bd4e1cba8d8592bec5d5ed9e4537fbfd"; logging-data="30797"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+94rhVQn8X7Wzp76cVIgKs" User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.3.0 In-Reply-To: Cancel-Lock: sha1:DBS9vJVjtT1gB4JWMQaxEwOh64Q= Xref: csiph.com comp.lang.java.programmer:30586 On 12/18/2014 11:04 AM, John wrote: > Thank you all for replies. > > Can you elaborate a little more about > Its getInstance() methods usually return a GregorianCalendar instance, > but could (if Locales and so on were set up) return an instance of > MayanCalendar or JulianCalendar or BabylonianCalendar or whatever: > Classes whose names, whose very existence, might not have been known > when the calling code was written. > > My guess is something like below. Is that correct? Thank you very much. > > public class Calendar { > > /** > * Static factory method returns an object of this class or subclass. for choice: 1 for GregorianCalendar, 2 for MayanCalendar , 3 for JulianCalendar > */ > public static Calendar getInstance(Date aDate, int choice) { > if(choice==1){ > ... //return a GregorianCalendar object > } > else if(choice==2) { > ... //return a MayanCalendar object > } > else if(choice==3) { > ... //return a JulianCalendar object > } > else { > return null; > } > > } > > ... > } > > How can I make it return MayanCalendar or JulianCalendar? First, you'd need to write MayanCalendar and JulianCalendar classes (they're not part of Java SE; I just made them up as examples that someone might add someday). These new classes would be subclasses of Calendar: public class MayanCalendar extends Calendar { ... } public class JulianCalendar extends Calendar { ... } ... so that Calendar.getInstance() -- which must return a Calendar -- could legitimately return them. Next, you'd have to make the new classes known to Java. I haven't actually tried to do this, but it can (probably) be done somehow: All the variants of Calendar.getInstance() eventually wind up with a TimeZone and a Locale, and from these they're supposed to produce a suitable Calendar. Java doesn't specify exactly how suitable Calendars are found, but if you look at the source code for Calendar.java you'll find that (in Sun/Oracle's implementation) the heavy lifting happens in CalendarProvider and LocaleProviderAdapter classes. (These are not part of Java SE, but part of Sun/Oracle's implementation of Java SE.) I can't explore much further, because the JDK doesn't provide source for those internal classes; all I can see is the compiled bytecode. But I imagine there's a configuration file somewhere that describes the available Locales and things, and (presumably) there's a way to say "For the following Locale, use *this* Calendar subclass." Whether this actually happens exactly this way with Calendar isn't crucial to the issue of using a factory method; the point is that a factory method *could* do something like this, and make a run-time choice of which precise class it returns. A constructor couldn't. -- esosman@comcast-dot-net.invalid "Don't be afraid of work. Make work afraid of you." -- TLM