On Thu, Oct 17, 2002 at 12:45:41AM +0900, Chris Gehlker wrote:
> > This doesn't make sense to me.  I see interfaces and mixins as
> > orthogonal concepts; interfaces are used to specify a contract, while
> > mixins are used to provide additional methods to a class.
> 
> It's just that the contract is used as a weak form of multiple 
> inheritance. At least I've never seen it used any other way. 

I think that MI can be used to implmement the contract, but that does
not mean that the contract is a form of MI.

> And it is called "Interface Inheritance" because it allows the
> programmer to add functionality to a class that is orthogonal to the
> functionality of the main inheritance path. For example if bird
> inherits from animal and implements flight then a bird 'is a' animal
> but a bird also 'is a' flier. In Ruby I'd just make flight a mixin.

Interface inheritance does not add any functionality to a class.

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).
  2) Be able to easily determine whether a given concrete class has a
     particular set of features

In Ruby:
  - #1 is unnecessary in Ruby, because any method can accept any object
    as a parameter.
  - #2 is the source of an ongoing debate on ruby-talk.

If there are other uses for interface inheritance (besides derivatives
of the above), then I am yet to see them in use.

> > What is a "class cluster"?  Can you provide an example?
> 
> Lets start with the hoary example from C++ of the abstract class shape 
> whose only non-virtual methods are move and resize where resize 
> operates on a circumscribed rectangle and whose only attributes are the 
> coordinates of the bounding rectangle. To do something similar in 
> dynamic languages, you define a class shape with move and resize 
> methods but you make shape's new method private. Then you define 
> concrete constructors such as create_circle_with_radius(r) and 
> create_rectangle_with_sides(length, width) etc. Of course you derive 
> circle, rectangle,  pentagon and friends from shape. You can call 
> draw(boundingBox) in shapes move and resize methods so long as every 
> child of shape defines a draw method.
> 
> Shape is called a class cluster because the private constructor 
> guarantees that any variable referencing a shape is actually 
> referencing a member of a concrete subclass. Use it as you would an 
> abstract class.
> 
> I hope that helps. It was pretty condensed so ask again if it's 
> confusing. I'll try to provide a better example.

Yes, it's confusing.  I tried implementing your example in Ruby, but I
ran into the following problems:
  1) If resize is a method of Shape, then what parameters does it take?
     For a Circle, I would expect it to take a radius, but for a
     Rectangle, I would expect it to take a length and a width.
  2) I could not figure out how to define a concrete constructor for
     Rectangle while still making it impossible to accidentally
     instantiate a Rectangle without going through the factory method
     (if I can't call Rectangle.new, then neither can the factory
     method).
  3) Having a private constructor in Ruby doesn't make sense; this is
     the purpose of a Module (you can always instantiate a Class, but
     you can't always instantiate a Module).

Perhaps if you provide a sample implementation it would be easier to
see.

Paul