Why can a class not inherit from more than one other class?

rbulph

Junior Contributor
Joined
Feb 17, 2003
Messages
397
If you want to have a class inherit from more than one other class you get a message from VB that only one Inherits statement is allowed in each class. But why? Suppose I have a Securities class and a Debt Class. A Loan Class would inherit Debt. A Shares Class would inherit Securities. A Bonds Class would inherit Debt and Securities. It seems a reasonable enough thing to want to do to me. I guess you have to be sure there's no conflict between properties in the Securities and the Debt class, but I'm sure that could be dealt with.

Is there any decent workaround to this?
 
.Net doesn't support multiple inheritance so you can only inherit from a single parent class, this may change in a future version but I wouldn't hold my breath waiting for it.
It may be possible (but a bit more code heavy) to use interfaces instead on inheritance to achieve the same effect.
 
It seems rather substandard to me. I'm already holding my breath for Visual Studio 2005 (of which I'm using the Beta Version, and that doesn't allow multiple inheritance) so I certainly won't be holding my breath for the version after that. Maybe I could do it with interfaces, but it would be a big inconvenience.
 
I'd just suggest encapsulation, the "has a" relationship should be applicable.

From the C# faq blog:

1. Different languages actually have different expectations for how MI works. For example, how conflicts are resolved and whether duplicate bases are merged or redundant. Before we can implement MI in the CLR, we have to do a survey of all the languages, figure out the common concepts, and decide how to express them in a language-neutral manner. We would also have to decide whether MI belongs in the CLS and what this would mean for languages that don't want this concept (presumably VB.NET, for example). Of course, that's the business we are in as a common language runtime, but we haven't got around to doing it for MI yet.

2. The number of places where MI is truly appropriate is actually quite small. In many cases, multiple interface inheritance can get the job done instead. In other cases, you may be able to use encapsulation and delegation. If we were to add a slightly different construct, like mixins, would that actually be more powerful?

3. Multiple implementation inheritance injects a lot of complexity into the implementation. This complexity impacts casting, layout, dispatch, field access, serialization, identity comparisons, verifiability, reflection, generics, and probably lots of other places.
 
rbulph said:
If you want to have a class inherit from more than one other class you get a message from VB that only one Inherits statement is allowed in each class. But why? Suppose I have a Securities class and a Debt Class. A Loan Class would inherit Debt. A Shares Class would inherit Securities. A Bonds Class would inherit Debt and Securities. It seems a reasonable enough thing to want to do to me. I guess you have to be sure there's no conflict between properties in the Securities and the Debt class, but I'm sure that could be dealt with.

Is there any decent workaround to this?

Best workaround I can see is to create an Interface for each class you want to inherit including all the public properties, events, methods & functions you need exposed.

create an instance of the classes you need to your current class to have and expose those methods/properties/events/functions that you want/need to expose.

It's more work than just inheriting from the class, but it's less work than rewriting the .net framework to allow multiple inheritance.

Personally, in most cases I'd prefer it this way. I like to see exactly what I'm using and have accessable and sometimes inheritence hides that from me.

If you plan on reusing these "base classes" (ie, you wanted multiple classes to inherit from them), do this in a "Code Snippit" and store it in the IDE (and back it up!). you can lay down the code of you exposing all the methods/properties/events/functions with a few mouseclicks/keystrokes.

An interface isn't nessicary, technically, but if you want all the classes that inherit from your "base classes" to all expose the same methods, only interfaces will enforce that if you change it, that you expose the new methods and the IDE will show you that with code errors until you add what you need to add.

Ideal? Maybe not, but it seems to get the job done and if you're using "Snippits", then most of your work is up front, barring changes in the classes at a later point.
 
Denaes said:
If you plan on reusing these "base classes" (ie, you wanted multiple classes to inherit from them), do this in a "Code Snippit" and store it in the IDE (and back it up!). you can lay down the code of you exposing all the methods/properties/events/functions with a few mouseclicks/keystrokes.
That's sort of defeating the purpose of having a base class, isn't it? Copy and pasting code is not reuse. You introduce a ton of code duplication this way and when the "base class" or snippit does change, you'll be in a world of hurt.

This article goes into a little more detail on how to use encapsulation and interfaces to fake multiple inheritance. It's written for Java but the concepts hold true for .Net.
 
mskeel said:
That's sort of defeating the purpose of having a base class, isn't it? Copy and pasting code is not reuse. You introduce a ton of code duplication this way and when the "base class" or snippit does change, you'll be in a world of hurt.

This article goes into a little more detail on how to use encapsulation and interfaces to fake multiple inheritance. It's written for Java but the concepts hold true for .Net.
Can't get my head around this article at all. For instance he says "To implement the Child class we create a new Mixin object and save it.". Well in VB the only thing you implement is an interface, and the Child class is not an interface, so I've no idea what this means. Below is my attempt to convert the Java into VB. It defines a Child class which inherits from a Parent class and implements two interfaces. It also defines a Mixin class, but I don't understand what I'm supposed to do with that!

Code:
Public Interface MRequires
    Function getInt() As Integer
End Interface

Public Interface MProvides
    Function func()
End Interface

Public Class mixin
    Implements MProvides

    Public Function func() As Object Implements MProvides.func
        Return 123
    End Function

    Public Sub New(ByVal X As MRequires)
        'What do I do with X?
    End Sub
End Class

Public Class Parent
    Public Function getInt() As Integer
        Return 77
    End Function
End Class

Public Class Child
    Inherits Parent
    Implements MRequires
    Implements MProvides

    Public Function func() As Object Implements MProvides.func
        Return 123
    End Function
    Public Function getInt1() As Integer Implements MRequires.getInt

    End Function
End Class
 
From your code:
'What do I do with X?
>>> save X in a private member in mixin:
Visual Basic:
Public Class mixin
    Implements MProvides

   private _parent as MRequires

    Public Function func() As Object Implements MProvides.func
        Return 123
    End Function

    Public Sub New(ByVal X As MRequires)
        me._parent = X
    End Sub
End Class

I think the confusion is coming from the decleration of the parent class in the article. I think it is supposed to impliment the MRequires Interface.

Now you get the functionality that you wrote in your mixin (accesible via me._mixin or something similiar -- it's a private member) and the functionality in the parent (you inherited from it -- base.method I beleive) which will give you, essentially, dual inheritence in Child. This is better than other methods becuase you are using the base objects instead of copying the code from the base objects. I don't think I would reccomend this for triple+ :eek: inheritance, but then triple+ is not really reccomended for anything.
 
mskeel said:
I think the confusion is coming from the decleration of the parent class in the article. I think it is supposed to impliment the MRequires Interface.

No it's not - the author of the article specifically states of the Parent class "This class must have all of the methods required of the MRequires interface, but it need not implement this interface.". That seems a bizarre thing to do and he doesn't offer any explanation for it.

And what code am I supposed to put inside the Child class? Currently I'm not making any use of the mixin class.
 
Visual Basic:
Public Class Child
    Inherits Parent
    Implements MRequires
    Implements MProvides
That's why you must have the methods but done require the interface. You'll pick up the interface later but you still need the public methods to cover the interface you'll inherit later. If you don't have the methods in the parent class you'll end up having to implement them again in the child class. It does seem rather odd that you wouldn't want to impliment that interface in the parent, though.

Essentially, you'll impliment the other interface (not implimented by the parent) in the child class using the mixin class. If you aren't using the mixin at all, maybe you didn't really need multiple inheritence?

I'll see if I can find a better article and play with this some more over the next few days. Sorry I can't be of much more help right now.
 
Thanks, but I remain completely baffled. You seem to be saying that by declaring methods in the parent class (without those methods implementing anything) you can avoid having to implement methods of an interface which is implemented by the child class. Does the child class somehow specify that the methods it inherits from the Parent are being used to implement methods of an interface? If so, how? Do you say MyBase.getInt1 Implements MRequires.getInt? I don't think that works.

I'm not using the mixin class because I haven't a clue what I'm meant to do with it! I have not achieved what I want to achieve. What I'd like to have is as I stated in my original post. In essence, getting:
Code:
TypeOf(Shares) Is Securities = True
TypeOf(Shares) = Debt = False
TypeOf(Loan) = Securities = False
TypeOf(Loan) = Debt = True
TypeOf(Bonds) = Securities = True
TypeOf(Bonds) = Debt = True

without having to repeat a whole lot of code for implementing an interface in exactly the same way across a lot of bottom level classes.
 
rbulph said:
You seem to be saying that by declaring methods in the parent class (without those methods implementing anything) you can avoid having to implement methods of an interface which is implemented by the child class.
I was, but the problem is that I had my C# hat on at the time. The VB solution isn't quite as slick, but it still works and it will do what you want it to do. You'll have to impliment the interface and call mybase from within the method you implemented:
Visual Basic:
Public Shadows Function getInt() As Integer Implements MRequires.getInt
   Returns MyBase.GetInt()
End Function
In C#, the child class will see the base class impementation in Parent and will use that to satisfy the Interface.

Sorry for the confusion. And what does all this buy you? Well, you can now say the following:
Code:
TypeOf(Shares) Is ISecurities = True
TypeOf(Shares) = IDebt = False
TypeOf(Loan) = ISecurities = False
TypeOf(Loan) = IDebt = True
TypeOf(Bonds) = ISecurities = True
TypeOf(Bonds) = IDebt = True
without duplicating code for either the Securities or Debt classes.
 
OK, I can now see something. You have a parent class and several types of child classes. All child classes inherit the parent. You have any number of interfaces. The parent class contains properties that match those of each interface, but does not implement any of them. Each child class can implement any number of the interfaces and does so by shadowing the relevant procedures of the parent class. That way each child class can be TypeOf any number of the interfaces, but all the code for those interfaces will be in the parent class. And maybe you can hide the parent methods that you don't want in the respective child classes. Is that the idea? This still doesn't use the mixin class though!
 
It sounds like you've got it. I'm sure my C#/VB confusion didn't help anything.

Remember, the parent class could inherit the interface if you want it to. The mixin is the other class that you are "inheriting" from. You are mixing it in with the the parent class to create the child class. Mixin is advantageous because it removes the ambiguity of possilbe method name collisions. something like: parent1.GetInt, parent2.GetInt, then you use base.GetInt -- but which base? With a mixin you will call either base.GetInt (parent class) or mixin.GetInt (other parent class that you are mixing in).

It's a little awkward in VB but it pretty much works the same way. The solution is pretty slick in C# and Java.
 
mskeel said:
Remember, the parent class could inherit the interface if you want it to.
Do you mean implement? Interfaces can't be inherited. If you do, I disagree with you, because then the child classes would always be TypeOf the interface. If you don't then I don't know what you mean.

mskeel) said:
The mixin is the other class that you are "inheriting" from. You are mixing it in with the the parent class to create the child class.
Please give me a line of code that actually does something with mixin. At the moment there is no reference to it.

mskeel said:
Mixin is advantageous because it removes the ambiguity of possilbe method name collisions. something like: parent1.GetInt, parent2.GetInt, then you use base.GetInt -- but which base?
If you have a name collision then this will be revealed in Parent because you are copying the methods of the interfaces in that.
 
I think I'll just do this:

Code:
Public Class Funding
    Public Rate As Single
    Public ISIN As String
    Public Registered As Boolean
    'etc, etc.
End Class

Interface Debt
    'Nothing goes in here, it's just so TypeOf works.
End Interface

Interface Securities
    'Nothing goes in here either.
End Interface

Public Class Bonds
    Inherits Funding
    Implements Debt
    Implements Securities
   
End Class

Public Class Shares
    Inherits Funding

    Implements Securities

    <System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> Public Shadows Rate As Single

End Class

Public Class Loan
    Inherits Funding
    Implements Debt
    <System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> Public Shadows ISIN As String
    <System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> Public Shadows Registered As Boolean

End Class
 
Do you mean implement?
Yes. It's all sort of the same thing but I should have been more specific.

I've got some code on my office machine I can post up tommorow to show you the other stuff.

I would say that as long as the funding class is used in each of the classes that inherits it, then you've got a solution. It doesn't look like the best solution, but there seem to be some language limitations that are preventing extremely elegant solutions and there isn't much you can do about that.
 
Back
Top