From: Chris Gehlker Date: 2002-10-18T03:02:53+09:00 Subject: Re: Interfaces in Ruby 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)