mskeel Posted December 30, 2004 Posted December 30, 2004 Say I have a speicial arrayList object that has a special add function and a static append funtion that will append two of these lists together. This list also allows duplications. Now I want to create a new type of this object only I would only like to allow numbers to be added and no duplications. So I inherit the first list I mentioned, shadow the add function, and provide a new implimentation that checks to see if it's a number before calling the base class's add function. The big problem comes from how to impliment the append function (what will essentially become the union). You can't just inherit it beucase the append will be too loose -- it allows duplicates. Option 1: Duplicate the code to preform the append in the inherited class Option 2: Pass a delegate to the append method that will point to the add function you want to use. Option 3: Something clever someone here knows or has done or seen done before. The problem with option 1 is you are not producing a pragmatic solution -- you are essentially copying the code when it would be better use the code that has already been written somehow. The problem with option 2 is that the delagate must be associated with an instance of an object thus negating the purpose of declaring the append method static. The problem with option 3 is that I'm not sure it it exists... Does anyone know of a pragmatic solution to this problem or have any ideas on how to elegantly solve it? Quote
BlackStone Posted December 31, 2004 Posted December 31, 2004 Is there any reason you have to inherit from this class, rather than creating a new one? Quote "For every complex problem, there is a solution that is simple, neat, and wrong." - H. L. Mencken
mskeel Posted December 31, 2004 Author Posted December 31, 2004 Well...I suppose I could just reimpliment everything...but that doesn't really make any sense seeing as how it is all implimented for me already. Why should I reimpliment a method like clear when it is universal? Why build when I can get it for free? The data structure I am talking about definately IS a list. Why wouldn't I inherit? Quote
Mike_R Posted December 31, 2004 Posted December 31, 2004 (edited) I think the key for you is to have your DerivedClass.Append() Method 'Override' the BaseClass.Append() Method, instead of using 'Shadows'. The Static Union() Method cannot be overridden of course, but if the Append() Method is overridden, when the Union() Method() calls Append() it will be automatically calling the correct version of Append() that you want. I apologize for the use of VB code in the following, but the idea is that if your Append() Method uses overrides, you could then call:Dim BC1, BC2, BC3 As BaseClass BC1 = BaseClass.Union(BC2, BC3) And that SAME Union() Method could also handle:Dim DC1, DC2, DC3 As DerivedClass DC1 = DerivedClass.Union(DC2, DC3) Here's a sort of stub-ed out version of what I had in mind:Class ItemClass ' Arbitrary Class that the BaseClass will Hold. ' Your Classes may simply hold Int's or other basic data ' types, but I made this just to be 100% clear. End Class Class BaseClass Implements ICloneable Function Clone() As Object Implements System.ICloneable.Clone ' Note: "Me" in VB.Net is "this" in C#. Clone = Me.MemberwiseClone End Function ' Note: "Shared" in VB.Net means "static" in C#. Shared Function Union(ByVal obj1 As BaseClass, _ ByVal obj2 As BaseClass) _ As BaseClass ' ---------------------------------------------------------- ' Note that this Method is Strong Types As 'BaseClass'. ' However, the BaseClass can be safely casted to/from any class that ' derives from it. ' ---------------------------------------------------------- ' Make a duplicate of obj1, called 'newObj1'. Dim newObj1 As BaseClass = DirectCast(obj1.Clone, BaseClass) ' Append all Items in obj2 to the 'newObj1'. For Each item As ItemClass In obj2.Items newObj1.Append(item) ' <-- If obj1 is a DerivedClass then Next ' this becomes an Overridden call. ' Return the result : Return newObj1 End Function Overridable Sub Append(ByVal item As ItemClass) ' Standard Append, do not check for duplicates. End Sub Function Items() As ItemClass() ' Return an Array of Items() held by the BaseClass. End Function Function Exists(ByVal item As ItemClass) As Boolean ' Returns True if the item already exists within the Items(). End Function End Class Ok, the above does not implement .Append(), .Items() or .Exists(), but it sounds like you already have that. :) (And I don't know your exact implementation anyway.) But the point is that once this is all set up, you can have a DerivedClass lean on the coding that is within the BaseClass. It would only need to Override the Append() Method:Class DerivedClass Inherits BaseClass Overrides Sub Append(ByVal item As ItemClass) ' This Overrides version CHECKS for Duplicates and does not ' add the Item if it already exists: If Not MyBase.Exists(item) Then MyBase.Append(item) Else ' Do nothing, or Throw an Exception (up to you). End If End Function End Class I hope this was clear... :), Mike Edited December 31, 2004 by Mike_R Quote Posting Guidelines Avatar by Lebb
Mike_R Posted December 31, 2004 Posted December 31, 2004 (edited) Hmmm.... ok, there's one last thing that bothers me with the above... A call to BaseClass.Union() or DerivedClass.Union() could be misleading in that each could handle both BaseClass or DerivedClass inputs. I think you'd want to create a Shadow version of Union() within the derived class. It really only needs to call the BaseClass.Union() method, but at least the Argument Signature would be checking the inputs "at the door". I think then, the DerivedClass should now look something like this:Class DerivedClass Inherits BaseClass Shared Shadows Function Union(ByVal obj1 As DerivedClass, _ ByVal obj2 As DerivedClass) _ As DerivedClass Union = DirectCast(BaseClass.Union(obj1, obj2), DerivedClass) End Function Overrides Sub Append(ByVal item As ItemClass) ' This Overrides version CHECKS for Duplicates and does not ' add the Item if it already exists: If Not MyBase.Exists(item) Then MyBase.Append(item) Else ' Do nothing, or Throw an Exception (up to you). End If End Function End Class Now the Argument signatures look like: BaseClass.Union(BaseClass, BaseClass) DerivedClass.Union(DerivedClass, DerivedClass) Hopefully this will do it! :) Edited December 31, 2004 by Mike_R Quote Posting Guidelines Avatar by Lebb
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.