<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"><channel><title>mikeash.com pyblog/friday-qa-2010-03-12-subclassing-class-clusters.html comments</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-03-12-subclassing-class-clusters.html#comments</link><description>mikeash.com Recent Comments</description><lastBuildDate>Sun, 10 May 2026 05:56:31 GMT</lastBuildDate><generator>PyRSS2Gen-1.0.0</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>mikeash - 2010-04-30 01:20:53</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-03-12-subclassing-class-clusters.html#comments</link><description>I don't think I've ever created one or seen a reason to. Class clusters are usually most useful for an API provider, since they make it easy to change the implementation of something behind the scenes without breaking client code, and provide specialized implementations for different uses. When you're writing both sides, you can just access stuff more directly, or use a more explicit factory pattern.
&lt;br /&gt;
&lt;br /&gt;For the implementation, I'd probably do something like:
&lt;br /&gt;&lt;code&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;+ (id)allocWithZone: (NSZone *)zone
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(self == [MyAbstractClass class])
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return [MyAbstractClassInitFactory allocWithZone: zone];
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return [super allocWithZone: zone];
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@implementation MyAbstractClassInitFactory
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- (id)init
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[self release];
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return [[MyConcreteClassThatHandlesInit alloc] init];
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- (id)initWithSomeObject: (id)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[self release];
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return [[MyConcreteClassThatHandlesSomeObject alloc] init];
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// etc.
&lt;br /&gt;&lt;/code&gt;</description><guid isPermaLink="true">ab500132fda92b49f33081ae9d338f5b</guid><pubDate>Fri, 30 Apr 2010 01:20:53 GMT</pubDate></item><item><title>Anonymous - 2010-04-29 14:57:58</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-03-12-subclassing-class-clusters.html#comments</link><description>Great write-up as usual. I'm more curious though about your take on &lt;i&gt;creating&lt;/i&gt; class clusters; specifically, when it's appropriate or not, how to safely patch the init chain when instantiating a subclass, etc.</description><guid isPermaLink="true">b76f4b0a2331e15bb1197a1bb17a3a3e</guid><pubDate>Thu, 29 Apr 2010 14:57:58 GMT</pubDate></item><item><title>mikeash - 2010-03-15 02:32:00</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-03-12-subclassing-class-clusters.html#comments</link><description>&lt;b&gt;Alex J:&lt;/b&gt; I don't think your plan is as simple as you think. What if I want to subclass an abstract class to create another abstract class by not overriding all of the necessary methods, like &lt;code&gt;NSMutableString&lt;/code&gt; does? You could allow that with extra keywords and such, but it adds complication.
&lt;br /&gt;
&lt;br /&gt;Worse, I think, is the fact that method implementations cannot all be seen by the compiler at compile time. What if your class is concrete by virtue of a category that the compiler doesn't know about? What if it's concrete because you add the necessary methods at runtime? Again, you can fix this with &lt;i&gt;more&lt;/i&gt; extra keywords, but that's more complication. Although ObjC 2.0 is getting away from it to some extent, ObjC's underlying philosophy is to be a minimal set of extensions to C, so I think a complicated system of abstract class keywords wouldn't be worth it.</description><guid isPermaLink="true">34f07c183e3e3c6396d349f2150b4f38</guid><pubDate>Mon, 15 Mar 2010 02:32:00 GMT</pubDate></item><item><title>Alex J - 2010-03-14 18:05:38</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-03-12-subclassing-class-clusters.html#comments</link><description>There are two things that a compiler can enforce with abstract classes: definition and instantiation. While I agree that detecting instantiation of abstract classes wouldn't make a lot of sense in Obj C, it would be possible to treat an incomplete implementation as an error. It would b fairly easy to tag abstract classes and methods (e.g. @abstract) and then refuse to compile if a concrete subclass does not implement all of the abstract methods from its superclasses. Personally, I am a fan of lettin the compiler do this kind of work fir me, rather than scouring the documentation or blowing up at runtime.</description><guid isPermaLink="true">9d80f97c34b88d13a8dbfb87597471b2</guid><pubDate>Sun, 14 Mar 2010 18:05:38 GMT</pubDate></item><item><title>mikeash - 2010-03-13 18:48:27</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-03-12-subclassing-class-clusters.html#comments</link><description>From what I can tell, "class cluster" describes much more than Abstract Factory, although it involves an Abstract Factory. Abstract Factory is simply a class which instantiates objects of other, hidden classes. Class clusters involve that, but also have the notion of explicitly allowing subclasses, with required primitive methods and a great deal of concrete functionality implemented in the base class that's built on top of the primitives. I don't see any of those aspects in the descriptions of Abstract Factory that I've found.</description><guid isPermaLink="true">193ae03798d5e8831dac8716b962925b</guid><pubDate>Sat, 13 Mar 2010 18:48:27 GMT</pubDate></item><item><title>Jens Ayton - 2010-03-13 12:09:45</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-03-12-subclassing-class-clusters.html#comments</link><description>Trevor: for the simple reason that Cocoa’s usage predates the GoF book and the habit of Patterns With Names in Capital Letters.
&lt;br /&gt;
&lt;br /&gt;Incidentally, there’s another problem with compiler checking of virtual classes: it’s normal and correct to use the standard allocation pattern with a class cluster, as in &lt;code&gt;[[NSArray alloc] initWithSomething]&lt;/code&gt;. In this case, a subclass (or proxy) could validly be returned by &lt;code&gt;+alloc&lt;/code&gt;, &lt;code&gt;-initWithSomething&lt;/code&gt;, or both, and this could change between system versions.</description><guid isPermaLink="true">9c846d8284bb4eb9194e8addcefe249b</guid><pubDate>Sat, 13 Mar 2010 12:09:45 GMT</pubDate></item><item><title>Trevor - 2010-03-13 05:06:15</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-03-12-subclassing-class-clusters.html#comments</link><description>For those wondering... Class clusters are more commonly known as the Abstract Factory design pattern. Not sure why Cocoa has to use different terminology.</description><guid isPermaLink="true">aa14669f389aaeac1887ae15ae8281ee</guid><pubDate>Sat, 13 Mar 2010 05:06:15 GMT</pubDate></item><item><title>Jens Ayton - 2010-03-13 00:18:55</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-03-12-subclassing-class-clusters.html#comments</link><description>There’s not much compiler-enforced anything in Objective-C, and the idea doesn’t fit the nature of the language. How would you go about doing this in the compiler? Object creation doesn’t involve a special operator, and you need to be able to refer to the class object for things like &lt;code&gt;isKindOfClass:&lt;/code&gt; checks.
&lt;br /&gt;
&lt;br /&gt;If you really wanted, you could override &lt;code&gt;+alloc&lt;/code&gt; to refuse to allocate instances of an abstract class, but there’s little advantage to having a runtime failure in &lt;code&gt;+alloc&lt;/code&gt; rather than slightly later when you try to actually use the object (or in the initializer).</description><guid isPermaLink="true">62339c015878f98369f9d467807c16f4</guid><pubDate>Sat, 13 Mar 2010 00:18:55 GMT</pubDate></item><item><title>mikeash - 2010-03-12 23:44:35</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-03-12-subclassing-class-clusters.html#comments</link><description>There aren't. I've never found it to be a problem. The typical pattern is to call out the necessary overrides in the docs/header, and implement the methods to log an error so it's easy to find at runtime:
&lt;br /&gt;&lt;code&gt;
&lt;br /&gt;- (void)somePrimitiveMethod
&lt;br /&gt;{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NSLog(@"-[AbstractClass somePrimitiveMethod] called, this should never happen. Did you forget to implement -[%@ somePrimitiveMethod]?", [self class]);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[self doesNotUnderstand: _cmd];
&lt;br /&gt;}
&lt;br /&gt;&lt;/code&gt;
&lt;br /&gt;This works well enough.</description><guid isPermaLink="true">d1b9eca1ad10dd31bac2f694a2c07e48</guid><pubDate>Fri, 12 Mar 2010 23:44:35 GMT</pubDate></item><item><title>Mike V - 2010-03-12 23:00:43</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-03-12-subclassing-class-clusters.html#comments</link><description>Is it true that there are no compiler-enforced abstract classes in Obj-C?  That's a shame if so.</description><guid isPermaLink="true">e2dcb3b01034f7121aa7cf70dcd29ad3</guid><pubDate>Fri, 12 Mar 2010 23:00:43 GMT</pubDate></item><item><title>mikeash - 2010-03-12 21:14:41</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-03-12-subclassing-class-clusters.html#comments</link><description>No, because I'm not implementing &lt;code&gt;init&lt;/code&gt;, so I don't need &lt;code&gt;super&lt;/code&gt;. In this particular case, both are equivalent, because I don't override &lt;code&gt;init&lt;/code&gt;, but if I did, I would want it to be called.
&lt;br /&gt;
&lt;br /&gt;See &lt;a href="http://www.mikeash.com/pyblog/the-how-and-why-of-cocoa-initializers.html"&gt;http://www.mikeash.com/pyblog/the-how-and-why-of-cocoa-initializers.html&lt;/a&gt;</description><guid isPermaLink="true">20f8757359811bf3f1b1a107b94632f6</guid><pubDate>Fri, 12 Mar 2010 21:14:41 GMT</pubDate></item><item><title>Dave DeLong - 2010-03-12 20:59:57</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-03-12-subclassing-class-clusters.html#comments</link><description>Are you sure you meant to do:
&lt;br /&gt;
&lt;br /&gt;&lt;code&gt;if ((self = [self init])) { ... }&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;Shouldn't it be &lt;code&gt;[super init]&lt;/code&gt;?</description><guid isPermaLink="true">70fe0b396886c0bedc525b7ac49bf94f</guid><pubDate>Fri, 12 Mar 2010 20:59:57 GMT</pubDate></item></channel></rss>
