Jump to content
Xtreme .Net Talk

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


Recommended Posts

Posted

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?

  • Administrators
Posted

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

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

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

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.

"Who is John Galt?"
Posted
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.

Posted
If you plan on reusing these "base classes" (ie' date=' 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.[/quote']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.

Posted
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!

 

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

Posted

From your code:

'What do I do with X?

>>> save X in a private member in mixin:

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.

Posted

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.

Posted

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.

Posted

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:

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.

Posted
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:

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:

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.

Posted
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!
Posted

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.

Posted
Remember' date=' the parent class could inherit the interface if you want it to.[/quote'] 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.

 

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.

 

Mixin is advantageous because it removes the ambiguity of possilbe method name collisions. something like: parent1.GetInt' date=' parent2.GetInt, then you use base.GetInt -- but which base?[/quote'] If you have a name collision then this will be revealed in Parent because you are copying the methods of the interfaces in that.
Posted

I think I'll just do this:

 

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

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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...