Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

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?

Posted
Is there any reason you have to inherit from this class, rather than creating a new one?
"For every complex problem, there is a solution that is simple, neat, and wrong." - H. L. Mencken
Posted

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?

Posted (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 by Mike_R

Posting Guidelines

 

Avatar by Lebb

Posted (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 by Mike_R

Posting Guidelines

 

Avatar by Lebb

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