Overloads Versus Overrides in VB.net - vb.net

What are the behavior differences for the Previous Property of Other1 and Other2 Class.
Note than the return type of the overloaded Previous Property of Other2 has been changed to Other2 while it stays as Base for Other1.
Public Class Base
Private _Previous as Base
Protected Overridable ReadOnly Property Previous As Base
Get
Return _Previous
End Get
End Property
Public Sub New(Previous as Base)
_Previous = Previous
End Sub
End Class
Public Class Other1
Inherits Base
Private _Parent as SomeType
Protected Overrides ReadOnly Property Previous As Base
Get
Return _Parent.Previous.Something
End Get
End Property
Public Sub New(Parent as SomeType)
MyBase.New(Nothing)
_Parent = Parent
End Sub
End Class
Public Class Other2
Inherits Base
Private _Parent as SomeType
Protected Overloads ReadOnly Property Previous As Other2
Get
Return _Parent.Previous.Something
End Get
End Property
Public Sub New(Parent as SomeType)
MyBase.New(Nothing)
_Parent = Parent
End Sub
End Class

After one of my comment to Jim Wooley's answer, "it look like it Shadows the overloaded property." I saw the light in this article.
So, the Overloads in the Other2 class act some more like shadowing than override. There is one of the comments in the article that is particularly instructive :
The confusion arises because the keyword "Overloads" isn't what a C# programmer considers an overload in the traditional OO sense. It's a type of hiding that is specific to VB.Net. You can actually swap the keyword SHADOWS with OVERLOADS in most cases, and the behavior is the same. The difference is when you have a base class with multiple overloaded method signatures. If you declare a method in a subclass with a matching name, and the SHADOWS keyword, it will hide EVERY overload of that method in the base class. If you use the OVERLOADS keyword instead, it will only hide the base class method with an identical signature.

Typically you would use Overloads when you are supplying different input parameters. Overrides replaces the functionality. In your case, you want Overrides in Other2 not Overloads. While properties can take parameters other than the value, it is best to not provide them and to use methods rather than properties when passing other values:
Public Class OldMath
Public Overridable Function DoSomething(val1 As Integer) As Integer
Return val1 + val1
End Function
End Class
Public Class NewMath
Public Overrides Function DoSomething(val1 As Integer) As Integer
Return val1 * val1
End Function
Public Overloads Function DoSomething(val1 As Integer, val2 As Integer) As Integer
Return val1 * val2
End Function
End Class

I found a great explanation on a social.msdn.microsoft.com forum.

Overloading is adding more methods to a class with the same name but different parameters.
Overriding means is replacing existing method of parent class in child class with exactly the same signature.

Related

Overload resolution works for normal method but not for constructor

My goal is to have a series of overloads, where the correct version of a method gets called depending on the type of the parameter (known only at runtime). However, I've run into an interesting problem in a case where the method I want to overload is a constructor.
Take the following inheritance structure:
Public MustInherit Class A
Public Property Common As String
End Class
Public Class X
Inherits A
Public Property Unique1 As String
Public Property Unique2 As String
End Class
Public Class Y
Inherits A
Public Property Unique3 As String
Public Property Unique4 As String
End Class
Base class A is inherited by both X and Y.
Now take this class which I'll use to show the problem:
Public Class Foo
Public Sub New(v As X)
Common = v.Common
Prop1 = v.Unique1
Prop2 = v.Unique2
Prop3 = "Some value"
Prop3 = String.Empty
End Sub
Public Sub New(v As Y)
Common = v.Common
Prop1 = "Some value"
Prop2 = String.Empty
Prop3 = v.Unique3
Prop4 = v.Unique4
End Sub
Public ReadOnly Property Common As String
Public ReadOnly Property Prop1 As String
Public ReadOnly Property Prop2 As String
Public ReadOnly Property Prop3 As String
Public ReadOnly Property Prop4 As String
Public Shared Sub Bar(v As X)
End Sub
Public Shared Sub Bar(v As Y)
End Sub
End Class
There is a normal method Bar with an overload, and also a constructor New with an overload. The first New has the same signature as the first Bar, and the second New has the same signature of the second Bar.
Finally take this test code:
Public Sub Test()
Dim Param As Object = New X
'This works fine
Foo.Bar(Param)
'This gives a compile error
Dim Thing As New Foo(Param)
End Sub
The compiler seems to have no problem with the call to Bar, but for the constructor call I get the following compile error:
Overload resolution failed because no accessible 'New' can be called without a narrowing conversion:
'Public Sub New(v As X)': Argument matching parameter 'v' narrows from 'Object' to 'X'.
'Public Sub New(v As Y)': Argument matching parameter 'v' narrows from 'Object' to 'Y'.
Why does the constructor call cause an error while the call to Bar does not.
Also, if I change the Param declaration to Dim Param As A = New X, then neither of them will compile.
I feel like I should understand this one, but for whatever reason I don't. Could someone fill me in on why this doesn't work, and maybe suggest a work-around?
While it's still unclear exactly what you are trying to achieve, an Answer is the only reasonable place to share code. Here is an attempt at solving your problem with Option Strict On, using an interface to define the properties that a class must have in order to be passed to a Foo for its construction.
Note the comments in the code which also help explain things.
This abstracts things so that Foo doesn't have to know about all the types derived from A - it only knows about the interface. In fact, it 'inverts' the relationship so that A and its derived types know what is necessary for Foo (per the interface). The rest is the implementation of X and Y, where the definitions of Props 1 through 4 now live (instead of in the various overloaded Foo constructors). This collapses the number of constructors for Foo down to just one.
The logic for translating properties of a class derived from A into Foo's properties has to live somewhere. By pushing this logic out of Foo and instead into the derived classes, you can avoid the narrowing issues that Option Strict Off defers until runtime. In addition, adding a new Z class derived from A is easy, and you don't have to modify Foo to immediately use it.
But again, as it's not perfectly clear what you intend to do with this sample code, it's hard to know if this approach 'works' for what you are thinking of, or not.
Option Strict On
Module Module1
Sub Main()
Dim Param As A = New X
Dim Thing As New Foo(Param)
Param = New Y
Thing = New Foo(Param)
'if you make a new class Z which Inherits A, it will immediately be translatable to Foo
'albeit with all String.Empty properties unless you override the properties from A
End Sub
End Module
'Defines what a Foo wants, what a Foo needs
Public Interface IPropertiesForFoo
ReadOnly Property Common As String
ReadOnly Property Prop1 As String
ReadOnly Property Prop2 As String
ReadOnly Property Prop3 As String
ReadOnly Property Prop4 As String
End Interface
Public MustInherit Class A
Implements IPropertiesForFoo
Public Property Common As String
#Region "IPropertiesForFoo implementation"
'these are Overridable, so derived classes can choose what to change and what not to
'note these are all Protected, so only derived classes know about them. Users of A may not care.
'This is just one choice;
' you could also use Throw New NotImplementedException (instead of Return String.Empty)
' and force derived classes to handle every property
Protected Overridable ReadOnly Property IPropertiesForFoo_Prop1 As String Implements IPropertiesForFoo.Prop1
Get
Return String.Empty
End Get
End Property
Protected Overridable ReadOnly Property IPropertiesForFoo_Prop2 As String Implements IPropertiesForFoo.Prop2
Get
Return String.Empty
End Get
End Property
Protected Overridable ReadOnly Property IPropertiesForFoo_Prop3 As String Implements IPropertiesForFoo.Prop3
Get
Return String.Empty
End Get
End Property
Protected Overridable ReadOnly Property IPropertiesForFoo_Prop4 As String Implements IPropertiesForFoo.Prop4
Get
Return String.Empty
End Get
End Property
'private, and doesn't need to be Overridable, as Common can map directly
Private ReadOnly Property IPropertiesForFoo_Common As String Implements IPropertiesForFoo.Common
Get
Return Common
End Get
End Property
#End Region
End Class
Public Class X
Inherits A
Public Property Unique1 As String
Public Property Unique2 As String
Protected Overrides ReadOnly Property IPropertiesForFoo_Prop1 As String
Get
Return Unique1
End Get
End Property
Protected Overrides ReadOnly Property IPropertiesForFoo_Prop2 As String
Get
Return Unique2
End Get
End Property
Protected Overrides ReadOnly Property IPropertiesForFoo_Prop3 As String
Get
Return "Some value"
End Get
End Property
'doesn't need to override Prop4; leave it as String.Empty
End Class
Public Class Y
Inherits A
Public Property Unique3 As String
Public Property Unique4 As String
Protected Overrides ReadOnly Property IPropertiesForFoo_Prop1 As String
Get
Return "Some value"
End Get
End Property
'doesn't need to override Prop2; leave it as String.Empty
Protected Overrides ReadOnly Property IPropertiesForFoo_Prop3 As String
Get
Return Unique3
End Get
End Property
Protected Overrides ReadOnly Property IPropertiesForFoo_Prop4 As String
Get
Return Unique4
End Get
End Property
End Class
Public Class Foo
Public Sub New(v As IPropertiesForFoo)
Common = v.Common
Prop1 = v.Prop1
Prop2 = v.Prop2
Prop3 = v.Prop3
Prop4 = v.Prop4
End Sub
Public ReadOnly Property Common As String
Public ReadOnly Property Prop1 As String
Public ReadOnly Property Prop2 As String
Public ReadOnly Property Prop3 As String
Public ReadOnly Property Prop4 As String
End Class
For that matter, depending on what the rest of Foo actually does, you may not even need Foo - just pass around your instances of A, since they are also IPropertiesForFoo. Then pull out their properties labeled as Prop1, Prop2, as needed. (Again, your simplified sample source doesn't hint at the larger context enough to know if this approach fits well, or not.)
I'm sure I'll get plenty of people telling me again that I shouldn't be doing things this way, but here's what I did to actually solve the problem as I needed it:
Public Class Foo
Public Sub New(v As X)
End Sub
Public Sub New(v As Y)
End Sub
Public Shared Function Create(v As X) As Foo
Return New Foo(v)
End Function
Public Shared Function Bar(v As Y) As Foo
Return New Foo(v)
End Function
End Class
Which lets me use Foo like this:
Dim Param As Object = New Y
Foo.Create(Param)
Yes, the above uses late binding and loosely-typed code. But it also keeps redundant code to a minimum, requires no lengthy interface definition or implementation, is still completely predictable, and does exactly what I want. I do consider features like this useful and valid when used in the right context.
I do still wish I could get some answer as to why the overload resolution works with a normal method but not a constructor. But for now I guess I'll just have to settle for this work-around.

How can I force a child class to assign a unique value to an inherited field?

Say I have a parent class:
Public MustInherit Class ParentClass
Protected str As String
Public MustOverride Sub Method()
End Class
And then I have a child class:
Public Class ChildClass
Inherits ParentClass
Public Overrides Sub Method()
End Sub
End Class
At the moment I have no way to ensure that str is assigned a unique value (a value which will be different for each class that inherits ParentClass).
Is there any way to force any child classes (even ones that I don't create) to assign str a value, similar to how MustOverride forces the child class to implement Method()? I thought there might a MustAssign keyword but there isn't.
Aha! I think I've reasoned out a way to do this myself.
I will create a protected constructor in ParentClass that takes a String and assign it to the field.
In ParentClass:
Protected Sub New(ByVal s As String)
Me.str = s
End Sub
Now, every class must implement a constructor that calls the single ParentClass constructor which takes a String.
In ChildClass
Public Sub New()
MyBase.New("String")
End Sub
This seems to solve my problem.
Is there a better method to solving this problem, or have I hit the nail on the head?
Use name Class, ensure the unique value
Public MustInherit Class ParentClass
Protected str As String = Me.GetType.Name
Public MustOverride Sub Method()
End Class
Beware, in your solution, there is nothing to prevent two daughters classes with the same initialization.
One of the possible patterns is to use a getter function instead of a field. Define it in each of the child classes. It may or may not be what you want.
Public MustOverride Function Str() As String

Call baseclass property

It's rather a simple question and both will work. But I'm just wondering what the best practice is. When a child class changes a variable in the baseclass. Should it call the property or just change the underlying variable.
I'm not using the property to do something with the data. The code in the child class is the same. But what is considered the best practice OOP wise?
Sample code:
Public Class TestDirect
Protected temp As Integer
End Class
Public Class TestChldDirect
Inherits TestDirect
Public Sub New()
MyBase.temp = 1
End Sub
End Class
versus
Public Class TestProperty
Private _temp As Integer
'
Public Property temp() As Integer
Get
Return Me._temp
End Get
Set(ByVal value As Integer)
Me._temp = value
End Set
End Property
End Class
Public Class TestChldProperty
Inherits TestProperty
Public Sub New()
MyBase.temp = 1
End Sub
End Class
The second approach gives you more flexibility later on and better protects/hides your underlying implementation. For instance, in your example you might want to modify the type of temp, add some validation etc. Those changes would be more difficult in your first example as you would be affecting the classes that derive from your base class. In the second example you can make the change without affecting any derived classes.

Is there a keyword that can make a class variable readonly from outside the class but not on the inside?

Basically, the readonly keyword doesn't let me modify a field after I first create the class instance. I could use a property but in this case its just extra overhead. Is there a keyword to make a class field readonly from only outside the class?
make the field private, provide getter and setter for it.
Make the setter private.
This way the value can be seen from outside the class by the getter,but, cannot be set/written from outside the class.
this makes the property read-only from outside the class.
As others have stated, use a property. If you don't want to split the property into one Getter and one Setter then make the setter private.
Public Class Foo
Public Property Abc() As Object
Get
Return Me.m_Abc
End Get
Private Set(value As Object)
Me.m_Abc = value
End Set
End Property
Private m_Abc As Object
End Class
However: The common way is to set the access level of the field to Friend making it accessible within the same assembly, but not from outside the assembly.
Public Class Foo
Public ReadOnly Property Abc() As Object
Get
Return Me.m_Abc
End Get
End Property
Friend m_Abc As Object
End Class
No there isn't. This type is scenario is precisely why properties are provided in the first place. You get a whole lot of flexibility.
However, if you insist you want to use a read only field, you can use reflection to change the value:-
Public Class TestClass
Public ReadOnly MyNumber As Integer
Public Sub New()
'Readonly fields can only be changed this way
'in the constructor
Me.MyNumber = 900
End Sub
Public Sub ChangeNumber(ByVal num As Integer)
SetNumber(num)
End Sub
Private Sub SetNumber(ByVal num As Integer)
Dim fi = Me.GetType.GetField("MyNumber")
'Reflection can change the value of
'a read only field after construction
fi.SetValue(Me, num)
End Sub
End Class
Note that this is a very terrible thing. Reflection shouldn't be used for this sort of thing as you're going to take a performance hit. Just use properties and save yourself the trouble.

Similar classes with different signatures

I have two classes:
Public Class Subscribing
Private _subscribingObjects As IList(Of String)
Public Sub Add(ByVal obj As SubscribeObject)
'...code...'
End Sub
Public Sub Remove(ByVal index As Integer)
'...code...'
End Sub
End Class
Public Class Providing
Private _providingObjects As IList(Of String)
Public Sub Add(ByVal obj As ProvideObject)
'...code...'
End Sub
Public Sub Remove(ByVal index As Integer)
'...code...'
End Sub
End Class
Is there a more elegant way to add do this? One class would suffice, but since the Add methods have different arguments, then one really wouldn't work.
Any help would be appreciated.
this?
Public Class SubscribingProviding(Of t)
Private _subscribingObjects As IList(Of String)
Public Sub Add(ByVal obj As t)
'...code...'
End Sub
Public Sub Remove(ByVal index As Integer)
'...code...'
End Sub
End Class
Your add functions should be fine. As long as you have different variable types being passed in you can have the function names be the same. Your remove Subs will not be allowed in the same class because it is using the same parameter Integer.
Eh.. probably not. They are different enough that you cant even Interface them.
I personally wouldn't mix the two responsibilities (of subscribing and providing) in one class. The classes themselves can easily be simplified by just inheriting from List(Of T)
Public Class Subscribing
Inherits List(Of SubscribeObject)
End Class
Public Class Providing
Inherits List(Of ProvideObject)
End Class
If you really want to get down to one class and make sure that it can only accept SubscribeObject and ProvideObject respectively, implement a common interface in both SubscribeObject and ProvideObject. Then create a generic class that accepts the interface:
' Common interface '
Public Interface ISubscribeProvideObject
End Interface
' SubscribeObject and ProvideObject both implementing the common interface '
Public Class SubscribeObject
Implements ISubscribeProvideObject
'...'
End Class
Public Class ProvideObject
Implements ISubscribeProvideObject
'...'
End Class
' Generic class accepting both types '
Public Class SubscribingProviding(Of T As ISubscribeProvideObject)
Inherits List(Of T)
'... Add() and Remove() methods only needed if custom logic applies ...'
End Class