On Thursday, October 17, 2002, at 07:55 AM, Paul Brannan wrote:

> On Thu, Oct 17, 2002 at 11:19:04AM +0900, Chris Gehlker wrote:
>>> The goals behind an interface or abstract class are:
>>>   1) Be able to write a function that can take as a parameter any
>>>      object that inherits from the abstract class (generic
>>>      programming).
>>
>> I don't agree that an interface, in the Java sense, and an abstract
>> class, in the Java/C++ sense are synonymous or that an interface has
>> necessary relationship to generic programming. Generic programming 
>> came
>> out of C++, which has no notion of interface.
>
> I think I was mistaken to call this "generic programming," which is
> similar but different.  Must have been too much sugar after lunch. :)
> I think the correct word is "polymorphism."
>

Aha
>
>> I believe the most common uses of the abstract class are:
>>
>> 1) To provide code clarity and to avoid code duplication
>
> I can agree that abstract classes can help provide clarity.  I don't 
> see
> how they avoid code duplication, since pure abstract base classes are
> not supposed to have any implementation.

It's actually the *impure* ones that centralize methods and data common 
to all their children in one place.
>
>> 2) To provide a way of referencing an object who's type is not
>> determined until run time, for example, the elements of a display list
>> in a drawing program.
>
> This also falls under polymorphism.
>
>> There are also:
>> 3) Idiosyncratic but very clever uses as, for example, in the STL,
>> where it is somewhat obscured by all the template stuff, and in 
>> GNUStep
>> where it isn't.
>>
>> Motivation 2 disappears in dynamic langaguages. 1 and 3 remain.
>
> I can't think of a case in Ruby where #3 would apply.

Maybe I can. Remember all the discussion of string and how some users 
can't even represent their own name? I can envision some future version 
of Ruby making string a class cluster and making "string" the cluster 
base as a common interface to "ascii_string", "UTF8_string", 
"unicode32_string", etc. This might be done in such a way that existing 
code would only take a minor performance hit but strings methods would 
automagically work for richer encoding schemes.

>
>> There is no need to enforce the use of the factory method. What needs
>> to be enforced is that the program cannot instantiate an instance of
>> the cluster base class. This corresponds directly to the C++ case 
>> where
>> their is no enforcement of a restriction on directly constructing a
>> derived concrete class but there is enforcement of the "no
>> instantiation of virtual classes" rule.
>
> In Ruby, if the base class has implementation, I would almost certainly
> throw it into a Module, because you cannot instantiate a Module.  If it
> has no implementation (the "Toy" abstract base class in the wiki link
> above), then I generally remove it completely.
>
> What would keep you from turning your cluster base class into a Module,
> and using it as a mixin?

Because the 'is a' relationship is going the opposite direction. I use 
Modules in Ruby where I would use MI in C++ and cluster bases where I 
would use virtual classes. That way I have a nice clean inheritance 
tree.

--
There are two kinds of fool. One says, "This is old, and therefore 
good."
And one says, "This is new, and therefore better."
-John Brunner, science fiction writer (1934-1995)