2

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 happens 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 :)

Side note - 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 so far 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.

22
  • 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#? Commented Mar 1, 2011 at 17:57
  • 2
    @MKO: To make this more clear, could you give a counter-eaxmple? A situation that could be improved by this potential feature? Commented Mar 1, 2011 at 18:25
  • 5
    It sounds a lot like mixins from Ruby (and a few other languages).
    – mipadi
    Commented Mar 1, 2011 at 18:34
  • 1
    Basically it's composition vs inheritance and avoiding things like the diamond problem (en.wikipedia.org/wiki/Diamond_problem) I'm sorry that I can't describe it clearer for you.
    – Homde
    Commented Mar 1, 2011 at 19:51
  • 1
    possible duplicate of How are mixins or traits better than plain multiple inheritance?
    – gnat
    Commented Jun 27, 2015 at 11:59

4 Answers 4

9

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#.

1
  • In the languages I'm familiar with that have used mixins (C++ and Common Lisp), it's an application of multiple inheritance. Commented Mar 1, 2011 at 19:47
3

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.

2

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.

8
  • 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.
    – Homde
    Commented Mar 1, 2011 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?) Commented Mar 1, 2011 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. Commented Mar 1, 2011 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.
    – Homde
    Commented Mar 1, 2011 at 19:56
  • yeah, it might be that this is just a solution to a very c# specific problem
    – Homde
    Commented Mar 1, 2011 at 19:57
2

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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