Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Idea

I had this idea for a language feature that I think would be useful, does anyone know of a language that implements something like this?

The idea is that besides inheritance a class can also use something called "imprinting" (for lack of better term). A class can imprint one or several (non-abstract) classes. When a class imprints another class it gets all it's properties and all it's methods. It's like the class storing an instance of the imprinted class and redirecting it's methods/properties to it. A class that imprints another class therefore by definition also implements all it's interfaces and it's abstract class.

So what's the point? Well, inheritance and polymorphism is hard to get right. Often composition gives far more flexibility. Multiple inheritance offers a slew of different problems without much benefits (IMO).

I often write adapter classes (in C#) by implementing some interface and passing along the actual methods/properties to an encapsulated object. The downside to that approach is that if the interface changes the class breaks. You also you have to put in a lot of code that does nothing but pass things along to the encapsulated object.

A classic example is that you have some class that implements IEnumerable or IList and contains an internal class it uses. With this technique things would be much easier

Example (c#)

[imprint List<Person> as peopleList]
public class People : PersonBase 
{
    public void SomeMethod()
    {
        DoSomething(this.Count); //Count is from List
    }
}

 //Now People can be treated as an List<Person>
 People people = new People();
 foreach(Person person in people)
 {
  ...
 }

peopleList is an alias/variablename (of your choice)used internally to alias the instance but can be skipped if not needed. One thing that's useful is to override an imprinted method, that could be achieved with the ordinary override syntax

public override void Add(Person person)
{ 
    DoSomething();
    personList.Add(person); 
}

note that the above is functional equivalent (and could be rewritten by the compiler) to:

public class People : PersonBase , IList<Person>
{
    private List<Person> personList = new  List<Person>();


    public override void Add(object obj)
    {
       this.personList.Add(obj)
    }

   public override int IndexOf(object obj)
    {
       return personList.IndexOf(obj)
    }

   //etc etc for each signature in the interface
}

only if IList changes your class will break. IList won't change but an interface that you, someone in your team, or a thirdparty has designed might just change. Also this saves you writing a whole lot of code for some interfaces/abstract classes.

Caveats

There's a couple of gotchas. First we, syntax must be added to call the imprinted classes's constructors from the imprinting class constructor.

Also, what happends if a class imprints two classes which have the same method? In that case the compiler would detect it and force the class to define an override of that method (where you could chose if you wanted to call either imprinted class or both)

So what do you think, would it be useful, any caveats? It seems it would be pretty straightforward to implement something like that in the C# language but I might be missing something :)

Sidenote - Why is this different from multiple inheritance

Ok, so some people have asked about this. Why is this different from multiple inheritance and why not multiple inheritance. In C# methods are either virtual or not.

Say that we have ClassB who inherits from ClassA. ClassA has the methods MethodA and MethodB. ClassB overrides MethodA but not MethodB.

Now say that MethodB has a call to MethodA. if MethodA is virtual it will call the implementation that ClassB has, if not it will use the base class, ClassA's MethodA and you'll end up wondering why your class doesn't work as it should.

By the terminology sofar you might already confused. So what happens if ClassB inherits both from ClassA and another ClassC. I bet both programmers and compilers will be scratching their heads.

The benefit of this approach IMO is that the imprinting classes are totally encapsulated and need not be designed with multiple inheritance in mind. You can basically imprint anything.

share|improve this question
4  
Is there any difference between imprinting and inheritance? More specifically, is there any difference besides syntax in what you're proposing and adding real public inheritance to C#? –  David Thornley Mar 1 '11 at 17:57
    
How is this different from multiple inheritance? –  Paul Nathan Mar 1 '11 at 17:58
    
There's no virtual calls with this approach and the imprinter can't call anything on the imprintee, only vice versa. Messing with multiple inheritance is pretty complicated business whereas this is simply encapsulation –  konrad Mar 1 '11 at 18:03
2  
@MKO: To make this more clear, could you give a counter-eaxmple? A situation that could be improved by this potential feature? –  FrustratedWithFormsDesigner Mar 1 '11 at 18:25
3  
It sounds a lot like mixins from Ruby (and a few other languages). –  mipadi Mar 1 '11 at 18:34
show 15 more comments

4 Answers

That's an interesting feature.

Scala also supports this.

Not exactly the way you're describing it, but it does, take a look at this:

trait  A { 
    def a() = "Hola"
}

trait B { 
    def b() = ", mundo!"
}

class C extends Object with A with  B  {}

object Main { 
    def main( args : Array[String] ) { 
        val c = new C()
        println( c.a() + c.b() );

    }
}

Output:

Hola, mundo!

Python has something similar, but I don't know exactly how it is implemented.

share|improve this answer
add comment

Perl 5 has the Moose OO system, which provides roles (sometimes also called "traits," which I think stems from the original academic background.) This includes method and attribute composition, as well as conflict detection and resolution like you specified.

share|improve this answer
add comment

The usual name for this concept is mix-in. It is supported by many languages, but not C# or Java. I would suggest that you learn some new languages, but that may spoil you for C#.

share|improve this answer
    
In the languages I'm familiar with that have used mixins (C++ and Common Lisp), it's an application of multiple inheritance. –  David Thornley Mar 1 '11 at 19:47
add comment

The behaviour you're looking for is exactly equivalent to multiple inheritance.

The problems you're describing with multiple inheritance in C# are not exactly present in all languages, you can look at some other examples (mixins from ruby have been mentioned already) of how multiple inheritance is implemented to find approaches that might make more sense to you.

It's worth noting that the problems you've described with C# stem from attempts to deal with basic complexities in the configuration - complexities which your imprinting approach does not resolve. In other words, with the imprinting implementation, as you describe it, implementors cannot yet ignore the same complexities that exist in multiple inheritance. Say that you imprint both PeopleList and ChemistList. Which "count" message will be sent in your example? I think you'll find that once you've considered this, and all the other corner cases, of your implementation, you will end up with an exact copy of the multiple inheritance functionality, with a different name.

share|improve this answer
    
As I mentioned in the post, if a class imprints more than one class with overlapping signature it has to explicitly declare an override. I guess the other difference is that an imprinted class cannot call virtual methods on the class that's imprinting it therefore it's completely encapsulated which reduces complexity. Furthermore if C# had multiple inheritance you'd have to depend on the classes you inherit to have virtual methods. If you look at the functionally equivalent code you see that it's more of a convenience than changing behavior. –  konrad Mar 1 '11 at 19:13
    
@MKO: And, if you have multiple inheritance in C++, and you have two different inherited member functions with identical names and signatures, you think this will work without an override? (BTW, what is the point about not calling virtual functions on the inheriting class? Isn't that going to be surprising, and therefore undesirable, behavior?) –  David Thornley Mar 1 '11 at 19:52
    
It sounds like you've learned of one implementation of multiple inheritance in C#, didn't like it, and decided to go a different route, calling it something else. The alternative you came up with is still, however, a multiple inheritance implementation. It looks like, on the spectrum of MI, it sits somewhere between what's available in C++ and what's available in Ruby. The convenience you speak of is exactly the motivation for multiple inheritance in the first place. I still claim that if you deal with all the corner cases, you'll end up back at your original MI definition. –  blueberryfields Mar 1 '11 at 19:55
1  
David, typically with MI there's some kind of automatic conflict resolution. Since the class just encapsulates the classes it "imprints" it doesn't matters. That's the point, imprinted classes doesn't have to be specifically designed and intermixed with other classes, they're simply encapsulated. –  konrad Mar 1 '11 at 19:56
    
yeah, it might be that this is just a solution to a very c# specific problem –  konrad Mar 1 '11 at 19:57
show 3 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.