rbulph Posted November 21, 2005 Posted November 21, 2005 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? Quote
Administrators PlausiblyDamp Posted November 21, 2005 Administrators Posted November 21, 2005 .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. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
rbulph Posted November 21, 2005 Author Posted November 21, 2005 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. Quote
IngisKahn Posted November 21, 2005 Posted November 21, 2005 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. Quote "Who is John Galt?"
Denaes Posted November 21, 2005 Posted November 21, 2005 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. Quote
mskeel Posted November 21, 2005 Posted November 21, 2005 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. Quote
rbulph Posted November 22, 2005 Author Posted November 22, 2005 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 Quote
mskeel Posted November 22, 2005 Posted November 22, 2005 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. Quote
rbulph Posted November 22, 2005 Author Posted November 22, 2005 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. Quote
mskeel Posted November 22, 2005 Posted November 22, 2005 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. Quote
rbulph Posted November 22, 2005 Author Posted November 22, 2005 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. Quote
mskeel Posted November 23, 2005 Posted November 23, 2005 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 FunctionIn 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. Quote
rbulph Posted November 23, 2005 Author Posted November 23, 2005 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! Quote
mskeel Posted November 23, 2005 Posted November 23, 2005 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. Quote
rbulph Posted November 25, 2005 Author Posted November 25, 2005 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. Quote
rbulph Posted November 25, 2005 Author Posted November 25, 2005 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 Quote
mskeel Posted November 27, 2005 Posted November 27, 2005 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. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.