Abstract class using an interface impleented in subclass? - vb.net

I have an idea that uses both an abstract class and an interface, but i'm not sure if its possible to do what I am thinking of and how.
I have an abstract class modeling a device, containing only abstract functionality. When implemented this class basically serves as a driver for the specific device.
Each device may have different features, I am attempting to model the feature sets as different interfaces that may or may not be implemented by the class designer.
Is there a mechanism for me to determine if a subclass of the device class is implementing these interfaces. I have to determine it FROM the super class, then be able to call the functions defined in the subclass from there.
This sounds impossible to me, but I'm just curious if someone else has more intuition, or possibly a better solution.
In the example below I've illustrated my point. I would like to be able ot have an object of type device, and call the functions implemented in the subclass through some mechanism.
Thanks!
Public MustInherit Class Device
Public MustOverride Sub One()
Public Function SupportsBonding As Boolean
'Returns true if subclass implments interface
End Function
End Class
Public Interface Bonding
Sub Two()
Sub Three()
End Interface
Public Class Device1
Inherits Device
Implements Bonding
Public Sub Two()
End Sub
Public Sub Three()
End Sub
End Class

You can always use a TypeOf operator using the Me keyword, something like:
If TypeOf Me Is IAmSomeInterface Then
...
End If
Even if this code is running in the superclass, it will always work against the runtime type of the object, so you'll get the subclass information.
Or, if you're planning to call methods on the interface, you might use a TryCast instead:
Dim someObject = TryCast(Me,IAmSomeInterface)
If Not someObject Is Nothing Then
someObject.DoSomething()
End If

Related

Too many identical simple methods using an interface

I have a few dozen classes which all implement the same interface and many of the methods have identical implementation. I have to do a lot of copy and paste whenever I add a new class. How can I get less code duplication?
I've heard that you should put the common code in a helper class but a lot of these methods are really trivial so calling a helper method is barely any simpler than doing the actual work.
Inheritance would save re-declaring all these methods but it would make it messy for the few classes that don't have the identical implementation.
Examples:
Identical in nearly every class...
Public Sub ThingWasDeleted(ByVal deletedThing As Thing) Implements Iinterface.ThingWasDeleted
If MyThing Is deletedThing Then
MyThing = Nothing
End If
End Sub
...but occasionally different:
Public Sub ThingWasDeleted(ByVal deletedThing As Thing) Implements IInterface.ThingWasDeleted
'Do nothing
End Sub
Identical in every class but already just as simple as calling a common helper method:
Public ReadOnly Property DisplayName() As String Implements IInterface.DisplayName
Get
Return DisplayNameShared
End Get
End Property
If you put these methods in a helper class, wouldn't that make it just as messy (if not more) than having an abstract base class where you can override the base class's functionality when needed?
For example:
Public MustInherit Class BaseClass
Public ReadOnly Property DisplayName() As String
Get
Return DisplayNameShared
End Get
End Property
Public Overridable Sub ThingWasDeleted(ByVal deletedThing As Thing)
If MyThing Is deletedThing Then
MyThing = Nothing
End If
End Sub
End Class
This provide a definition of the property that all inheriting classes can use, and gives the inheriting class an option to override and create their own implementation of ThingWasDeleted.
For example:
Public Class MyClass
Inherits BaseClass
Public Overrides Sub ThingWasDeleted(ByVal deletedThing As Thing)
' Do nothing
End Sub
End Class
On the other hand, if you wrote a helper class, you'd have to define every method, and the developer (which may or may not be you) would have to know which method to change. Additionally, instead of having the option to use the existing functionality in the base (abstract) class, every class you create will have to call each of the proper helper methods.
Personally, I prefer the former option, mainly because the inheriting classes don't have to call anything to get the base functionality established in the base class, and can override what they need to on a case-by-case basis. Conversely, having them all in a helper class means you have to at least write the code to call each of the necessary helper methods in every class you have.

Implementing Inherited Interface with Overloaded Member vb.net

I am trying to implement a derived interface in a class. My interfaces and class are similar to the following. The Namespaces relate to different projects that hold these interfaces and the class:
Namespace ns1
Public Interface IParent
Function myFunction() As Double
End Interface
End ns1
Namespace ns2
Public Interface IDerived
Inherits ns1.IParent
Overloads / Shadows Function myFunction(ByRef myObject as Object) As Double
End Interface
End ns2
Namespace ns3
Public Class myClass
Implements ns2.IDerived
Public Function myFunction(ByRef obj as Object) As Double Implements ns2.IDerived.myFunction
End Function
End ns3
In the derived interface, I am trying to overload the function in a way that when I implement the derived interface, I only have to implement the function as defined therein - as is done with the code above on "myClass". However, I am getting an error saying I have to also implement the function from the parent interface (with the empty argument list). The error exists regardless of my using Overloads or Shadows on the function in the derived interface - both cause the error.
Is there anyway to accomplish what I am trying to do - implement only the derived interface's function in my class - using interfaces? If there is not a way using interfaces, can anyone suggest an alternate way? We really need to use interfaces and are trying to avoid using classes. That said, abstract classes my allow us to do all we need to do with these.
I have read a lot of info on all the topics covered by this question as every concept is pretty basic and well covered in online help. But, I have not found anything that I recognize as a direct solution to my specific issue.
Thanks in advance for any help.
I don't know if this is a typo but you have two distinct methods: one that takes no parameter, and another that takes an object, so the compiler requirement is legitimate.
If this is a typo and that you have only one method, say "myFunction()", then I fear VB.Net does not act like C# by simply hiding the base interface and allowing to only implement the derived one.
But you could easily fix this by forwarding:
Namespace ns1
Public Interface IParent
Function myFunction() As Double
End Interface
End Namespace
Namespace ns2
Public Interface IDerived
Inherits ns1.IParent
Function myFunction() As Double
End Interface
End Namespace
Namespace ns3
Public Class Class1
Implements ns2.IDerived
Public Function myFunction() As Double Implements ns2.IDerived.myFunction
Return 42
End Function
Private Function myFunction1() As Double Implements ns1.IParent.myFunction
Return myFunction()
End Function
End Class
End Namespace
Module Module1
Sub Main()
Dim cp As ns1.IParent = New ns3.Class1
cp.myFunction()
Dim cd As ns2.IDerived = New ns3.Class1
cd.myFunction()
End Sub
End Module
EDIT:
So was not a typo, here is the standard (good/best practice?) fix:
Public Class Class1
Implements ns2.IDerived
Public Function myFunction(ByRef obj As Object) As Double Implements ns2.IDerived.myFunction
End Function
Public Function myFunction() As Double Implements ns1.IParent.myFunction
Throw New NotImplementedException("'ns1.IParent.myFunction' has not been implemented because unicorns can't fly!")
End Function
End Class
I don't believe that what you want to accomplish is possible the way you are trying... As I recall when you inherit an Interface any class that implements your derived Interface is actually being told that it must implement both Interfaces rather allowing the options you have in a full class.
So effectively what you have in myClass is:
Namespace ns3
Public Class myClass
Implements ns2.IDerived
Implements ns1.IParent
Public Function myFunction(ByRef obj as Object) As Double Implements ns2.IDerived.myFunction
End Function
End ns3
So inheriting an interface is really just a way to enforce that a class implementing the derived interface must also implement the base interface.

How to get the class type in a inherited shared method

Folks;
Code looks like:
Public Class MasterA
Inherits Underling
End Class
Public Class MasterB
Inherits Underling
End Class
Public Mustinherit Class Underling
Sub DoSomething()
Me.GetType 'Using the instance, I can get the class.
end sub
Shared function() as ???? 'How can I define the return type based on the class that inherited me?
'Me.GetType 'Won't work as this is a shared function with no instance 'Me'
End Function
End class
OK. The question is: is there a way to get at the class type from within a shared function that was inherited by another class?
What I'm building is an XML serializer/desrializer as an inheritable class so that classes that inherit it can be serilized to an XML file, and back again. Rather than writing a serializer/deserializer for each type of class I want to do this with, I'd like to just inherit the functionality.
To do that, though, requires that I be able to ascertain the clas that inherited me in the shared function.
You could get the desired behavior with a generic base class, my VB is a little rusty so you might find stray parens or brackets. This would really be the only way to get a type reference to an inheriting class in a shared base class function.
Public Mustinherit Class Underling(Of T)
Sub DoSomething()
Me.GetType 'Using the instance, I can get the class.
end sub
Shared function() As T
' GetType(T) should get the type at this point
End Function
End class
Public Class MasterA
Inherits Underling(Of MasterA)
End Class
Public Class MasterB
Inherits Underling(Of MasterB)
End Class
As a side note it does seem like a rather weird solution to handle XmlSerialization rather than through your own serializer implementation or XmlSerializer

vb.net implement strategy pattern with different interface

is it possible to implement strategy pattern with different parameters in VB.net?
For example I have the following code:
Public Interface InterfaceDataManipulation
Sub updateMyData()
End Interface
How to implemente updateMyData in the class that implements above interface class with different parameter, for example in class x :
Public Class X
Implements InterfaceDataManipulation
Public Sub updateMyData(ByVal x as String)
Console.Writeline(x)
End Sub
End Class
But the IDE raises an error "class x must implement updateMyData on interface InterfaceDataManipulation"
By adding a parameter you're not implementing the interface - The idea of the interface is that people can use your class by only knowing about the interface -so your sub with parameter wouldn't match their expectations.
There are probably many ways of skinning this cat, but these are a few of the options:
Don't use the interface
Implement your version of updateMyData as an overload, but you should still implement the original without the parameter aswell
Pass in x as a property to your class, that the updateMyData method can then use, while still having a signature that matches the interface.
Public Class X
Implements InterfaceDataManipulation
Public Sub updateMyData(ByVal x as String) Implements InterfaceDataManipulation.updateMyData
Console.Writeline(x)
End Sub
End Class
The method signature needs to be appended with the method it is implementing in the interface as show above.

Storing an object that implements multiple interfaces and derives from a certain base (.net)

In .net, it's possible to use generics so that a function can accept arguments which support one or more interfaces and derive from a base type, even if there does not exist any single type from which all valid argument types derive. For example, one could say:
Sub Foo(Of T As {IInterface1, IInterface2, SomeBaseType})(Param as T)
and be allowed to pass any derivative of SomeBaseType which implements both IInterface1 and IInterface2. This will work even if SomeBaseType does not support Interface1 and Interface2, and classes which do implement those interfaces don't share any common ancestor that also implements them.
This can be very convenient if one won't need to keep the parameter anywhere after the function has exited. Unfortunately, I can't figure out a way to persist the passed-in parameter in such a way that it can later be passed to a similar function, except perhaps by using Reflection. Is there any nice way of doing that?
The closest I've been able to come up with is to define an interface INest (perhaps not the best name--can anyone improve it?) thus:
Interface INest(Of Out T)
Function Nest() As T
End Interface
And for any interface that will be used in combination with others or with base-class "constraint", define a generic version as illustrated below
Interface IFun1
' Any members of the interface go here, e.g. ...'
Sub DoFun1()
End Interface
Interface IFun1(Of Out T)
' This one does nothing but inherit'
Inherits IFun1, INest(Of T)
End Interface
A class which will support multiple interfaces should declare itself as implementing the generic ones, with itself as the type argument.
Class test123a
Inherits sampleBase
Implements IFun1(Of test123a), IFun2(Of test123a), IFun3(Of test123a)
End Class
If that is done, one can define a function argument or class variable that supports multiple constraints thusly:
Dim SomeField as IFun1(Of IFun2(Of IFun3(Of sampleBase)))
and then assign to it any class derived from sampleBase, which implements those interfaces. SomeField will implement IFun1; SomeField.Nest will implement IFun2; SomeField.Nest.Nest will implement IFun3. Note that there's no requirement that IFun1, IFun2, IFun3, or sampleBase share any common derivation other than the generic interfaces inheriting from INest(Of T). Note also that, no matter how many INest-derived interfaces a class implements, it only needs to define one implementation of INest(Of T).Nest.
Not exactly beautiful, but there are two nice things about it: (1) any concrete class which in fact implements the necessary interfaces can be assigned directly to a field declared as above, without a typecast; (2) while fields which chain the types in a different order are not assignment compatible, they may be typecast to each other.
Is there any better way to store something in such a way that it's "known" to support multiple interfaces and derive from a certain base type? Given that one can write such code in a type-safe manner, it would seem like the .net 2.0 CLR could probably support such a thing quite nicely if compilers offered a little assistance. I'm unaware of any particularly nice approach with present compilers, though.
The best way I can think of is to make an abstract storage and generic implementation of this storage. For example (excuse my VB.NET):
MustInherit Class Storage
Public MustOverride Sub DoSomething()
End Class
Class Storage(Of T As {IInterface1, IInterface2, SomeBaseType})
Inherits Storage
Public Overrides Sub DoSomething()
' do something with Value.
End Sub
Public Value As T
End Class
And usage
Dim S As Storage
Sub Foo(Of T As {IInterface1, IInterface2, SomeBaseType})(ByVal Param As T)
S = New Storage(Of T) With {.Value = Param}
End Sub
Sub UseS()
S.DoSomething();
End Sub
Update: Ok, because we may not be able identify in advance all of the actions:
MustInherit Class Storage
MustOverride ReadOnly Property SomeBaseType As SomeBaseType
MustOverride ReadOnly Property IInterface1 As IInterface1
MustOverride ReadOnly Property IInterface2 As IInterface2
End Class
Class Storage(Of T As {IInterface1, IInterface2, SomeBaseType})
Inherits Storage
Public Value As T
Public Overrides ReadOnly Property IInterface1 As IInterface1
Get
Return Value
End Get
End Property
Public Overrides ReadOnly Property IInterface2 As IInterface2
Get
Return Value
End Get
End Property
Public Overrides ReadOnly Property SomeBaseType As SomeBaseType
Get
Return Value
End Get
End Property
End Class