OOP hurdle

J

Jason

I have a fun OOP question.

I want to have a base class that contains methods that should always be
overridden... I can't mark the base class methods as MustOverride because
they will "overridden" by Shared (static) methods, so I have to code a "work
around".

In the code below, I've identified where I am getting an error. Somehow I
need to execute the Derived Class's ChangePassword method instead of the
base class's ChangePassword method.

I've confirmed that Me.GetType().ToString() resolves to MyDerivedClass1 or
MyDerivedClass2, so there HAS to be a way to do this... I just need a few
suggestions. :)

Thanks in advance,

-- Jason



Here's the class definitions:

Public MustInherit Class BaseClass1
Overridable Sub ChangePassword( _
ByVal Username as String, _
ByVal Password as String, _
ByVal theOU as String, _
ByVal theEmployeeEmailAddr as String)

'next line won't compile...
CType(Me, Me.GetType()).ChangePassword(Username, Password, theOU,
theEmployeeEmailAddr)
End Sub
End Class

Public Class MyDerivedClass1
Public Shared Sub ChangePassword( _
ByVal username as String, _
ByVal password as String, _
ByVal theOU as String, _
ByVal theEmployeeEmailAddr as String)

' code goes here where I actually change the users password using
ADSI or System.DirectoryServices
End Sub
End Class

Public Class MyDerivedClass2
Public Shared Sub ChangePassword( _
ByVal username as String, _
ByVal password as String, _
ByVal theOU as String, _
ByVal theEmployeeEmailAddr as String)

' code goes here where I would pass the request off to a web service
to handle the request instead of doing it here...
End Sub
End Class

Public Class MyMainClass
Public Sub ChangePassword( _
ByVal username as string, _
ByVal Password as String, _
ByVal theOU as String, _
ByVal theEmployeeEMailAddr as String)

Dim theBaseClass as BaseClass1

Select case theOU
case "FirstOrginizationalUnit"
theBaseClass = New DerivedClass1
case "SecondOrginizationalUnit"
theBaseClass = New DerivedClass2
End Select

theBaseClass.ChangePassword(username, password, theou,
theemployeeemailaddr)
End Sub
End Class
 
D

David Browne

Jason said:
I have a fun OOP question.

I want to have a base class that contains methods that should always be
overridden... I can't mark the base class methods as MustOverride
because they will "overridden" by Shared (static) methods, so I have to
code a "work around".

Shared (static) methods just don't participate in inheritence.

Why are you using Shared (static) methods? You have an instance of the
type. Use instance methods.

David
 
J

Jay B. Harlow [MVP - Outlook]

Jason,
If you have:
Public MustInherit Class BaseClass1
Overridable Sub ChangePassword( _
Requires:

Public Class MyDerivedClass2
Public Overrides Sub ChangePassword( _

Shared methods are not polymorphic friendly per se, while Overridable &
MustOverride methods are. You use Overrides in derived class when you want
polymorphic behavior with an Overridable & MustOverride method.

For a complete discussion one the "how to" of OOP in VB.NET including how
Shared works and how Overridable works I would strongly recommend Robin A.
Reynolds- Haertle's book "OOP with Microsoft Visual Basic .NET and Microsoft
Visual C# .NET" from MS Press

Hope this helps
Jay
 
G

Guest

At the time of execution, I dont know what kind of object I have... all
that I know is that I have a reference to an object that was derived from
MyBaseClass1...

I also know that the object has a specific method... ie... ChangePassword

I want to execute the shared method ChangePassword method of the derived
class. To perform the given functionality in this individual example, I
would run the following code in the MyBaseClass1.ChangePassword method:

if Me.GetType().ToString() = "project1.MyDerivedClass1" then
MyDerivedClass1.ChangePassword( .........)
Elseif Me.GetType().ToString() = "project1.MyDerivedClass2" then
MyDerivedClass2.ChangePassword(.........)
end if

The issue that I will have is that this code is bulky and difficult to
maintain because it's likely that I may eventually have 50+ different derived
classes from MyBaseClass1. In that case, I would need to add an extra elseif
for each possibility.

I would like to implement a solution where it determines which static method
will be executed at a given time depending upon the results of the
Me.GetType() method. It would make sense that I could do something like
this, but it doesnt compile:

Dim MyObjType = Me.GetType()
Dim MyDerivedObject = CType(Me, MyObjType)

MyDerivedObject.ChangePassword(.......)

Any ideas?

-- Jason
 
D

David Browne

Jason Folkens said:
At the time of execution, I dont know what kind of object I have... all
that I know is that I have a reference to an object that was derived from
MyBaseClass1...

I also know that the object has a specific method... ie...
ChangePassword

I want to execute the shared method ChangePassword method of the derived
class. To perform the given functionality in this individual example, I
would run the following code in the MyBaseClass1.ChangePassword method:

if Me.GetType().ToString() = "project1.MyDerivedClass1" then
MyDerivedClass1.ChangePassword( .........)
Elseif Me.GetType().ToString() = "project1.MyDerivedClass2" then
MyDerivedClass2.ChangePassword(.........)
end if


Yes, but that's the point of making ChangePassword _not_ shared. Then you
can just invoke MyBaseClass1.ChangePassword and the derived class's
ChangePassword will be called automatically.

David
 
J

Jay B. Harlow [MVP - Outlook]

Jason,
I think we need to back up a couple of steps.
At the time of execution, I dont know what kind of object I have... all
that I know is that I have a reference to an object that was derived from
MyBaseClass1...
Which is why ChangePassword is overridable in the base class. In fact
BaseClass1.ChangePassword should NOT be attempting to call
MyDerivedClass1.ChangePassword, you probably want to make it MustOverride.
Public MustInherit Class BaseClass1
Public MustOverride Sub ChangePassword( _
ByVal Username as String, _
ByVal Password as String, _
ByVal theOU as String, _
ByVal theEmployeeEmailAddr as String)
End Class

Then as my other post stated, you want to Override it in MyDerivedClass1

Public Class MyDerivedClass1

Public Overrides Sub ChangePassword( _
ByVal username as String, _
ByVal password as String, _
ByVal theOU as String, _
ByVal theEmployeeEmailAddr as String)

' code goes here where I actually change the users password using
ADSI or System.DirectoryServices
End Sub
End Class


To use the ChangePassword method you need to create an instance of
MyDerivedClass1, which you can place in a BaseClass1 variable and simply use
it.

Dim base As BaseClass = New MyDerivedClass1

base.ChangePassword(username, password, organizationUnit, emailAddress)

Will call MyDerivedClass1.ChangePassword as MyDerivedClass1 overrides
BaseClass1.ChangePassword.

The "trick" is then deciding which derived class you want to create, I
normally have a Factory method someplace that uses the app.config or other
parameter to create a specific instance of the class...

Again I would strongly recommend Robin A. Reynolds-Haertle's book I
mentioned in my other post.

Hope this helps
Jay
 
G

Guest

Thanks to both Jay and David for your help... In my app, I took your advice
and made them non-static methods.

I'm still curious though... with my bad application design set aside, is
there any way to use the CType function to create a reference to a class type
that is known only at runtime?
 
D

David Browne

Jason Folkens said:
Thanks to both Jay and David for your help... In my app, I took your
advice
and made them non-static methods.

I'm still curious though... with my bad application design set aside, is
there any way to use the CType function to create a reference to a class
type
that is known only at runtime?

Yes.
 
D

David Browne

Jason Folkens said:
Thanks to both Jay and David for your help... In my app, I took your
advice
and made them non-static methods.

I'm still curious though... with my bad application design set aside, is
there any way to use the CType function to create a reference to a class
type
that is known only at runtime?

oops.

Yes. Reflection (aka late binding).

Option Strict Off
Class A
Public Shared Function M() As String
Return "A"
End Function
End Class
Class B
Inherits A
Public Shared Function M() As String
Return "B"
End Function
End Class

Shared Sub Main()
Dim a As New A
Dim b As A = New B
Console.WriteLine(a.M)
Console.WriteLine(b.M)
Console.WriteLine(CType(b, Object).M)
End Sub
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top