For example:
I have two classes like this:
Look for a question inside class B comment, down.
classdef A < handle
properties
classBobj; % class B is a property of class A
end
methods
MethodFromA (obj)
end
end
end
classdef B <handle
methods
MethodFromB (obj)
% I is possible to call class A method MethodFromA here
end
end
end
There are two ways in which this is possible:
You try to call a static method from class A but then you have to define it as such:
classdef A < handle
properties
classBobj; % class B is a property of class A
end
methods (Static)
MethodFromA()
end
end
This can be called everywhere in your code (without a reference to an instance of A) as follows A.MethodFromA()
You have a reference to an instance of class A within your so instead of calling MethodFromB(obj), you should all MethodFromB(obj, classAobj)
Related
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.
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
I would like to define an interface with properties in an abstract class like this
classdef A
properties (Abstract = true)
Valid;
end
end
with an implementation of this interface like this
classdef B < A
properties (Dependent = true)
Valid;
end
methods
function v = get.Valid(obj)
v = 1;
end
end
end
but when I try to make an instance of B I get the following error
>> c = B()
??? Error using ==> B
The property 'Valid' restriction defined in class 'B' must match the property definition in base class 'B'.
Can anyone tell me what I doing wrong?
Try setting the Dependent property attribute in the base class as well:
classdef A
properties (Abstract = true, Dependent = true)
Valid;
end
end
According to the documentation:
Concrete subclasses must redefine abstract properties without the
Abstract attribute set to true
The way I understood this, subclass property attributes must match the base class (without the Abstract property)
I have 2 classes, lets call them parentClass and childClass. parentClass has two methods, lets call them firstMethods and secondMethods. childClass inherits parentClass and implements firstMethod. parentClass implements both methods. And here is my problem. In my parentClass in side of secondMethods I want to call firstMethods but when I do it with [self firstMethods] I jump into implementation of childClass. If I call it with [super firstMethods] it calls method in a super class (in this example it's UIView).
So, is it possible in objective c to call methods in side of a base class? One methods calling other method without jumping in a concrete class implementation?
You dont. Change your design.
To explain this here is a some code. (My example uses ruby because it's easy to read for almost any programmer, but this is not a ObjC question, its about classes and inheritance).
class A
def one
"one"
end
def two
self.one + "-two"
end
end
class B < A
def one
"B-"+ super
end
end
a = A.new
puts a.one #=> "one"
puts a.two #=> "one-two"
b = B.new
puts b.one #=> "B-one"
puts b.two #=> "B-one-two"
So class B overrides the one method from it's parent with it's own implementation. Which is picked up even if we dont directly use that method. This is an awesome feature of any class based language. class B has it's own way to do a one and no matter how it's asked to do it, it does it it's own way. In fact the whole idea of of the child class overriding a method is that it wants to do something in a different or augmented way from it's parent.
To get around this, you need avoid the issue entirely. Instead refactor out the internals to another method you do not override. Then your base class and child class both can call that other method for data. The cool thing now is that your child can now override this other method if it needs to as well.
class A
def one
one_string
end
def two
self.one_string + "-two"
end
def one_string
"one"
end
end
class B < A
def one
"B-"+ self.one_string
end
end
a = A.new
puts a.one #=> "one"
puts a.two #=> "one-two"
b = B.new
puts b.one #=> "B-one"
puts b.two #=> "one-two"
In this example we added a third method that class B inherits and does not override.
The whole point here is that the child class retains control over what code gets run, NOT the parent class. This is important. Your desired solution would mean you have to change the base class if you wanted to change this behavior. But simply letting inheritance be awesome allows you the most flexibility by letting the child classes define exactly how the want to use the methods exposed by their parents.
If you have object of childClass then [self firsteMethod] will call childClass implementation [super firsMethod] will call parentImplementation.
VB.Net2005
Simplified Code:
MustInherit Class InnerBase(Of Inheritor)
End Class
MustInherit Class OuterBase(Of Inheritor)
Class Inner
Inherits InnerBase(Of Inner)
End Class
End Class
Class ChildClass
Inherits OuterBase(Of ChildClass)
End Class
Class ChildClassTwo
Inherits OuterBase(Of ChildClassTwo)
End Class
MustInherit Class CollectionClass(Of _
Inheritor As CollectionClass(Of Inheritor, Member), _
Member As OuterBase(Of Member))
Dim fails As Member.Inner ' Type parameter cannot be used as qualifier
Dim works As New ChildClass.Inner
Dim failsAsExpected As ChildClassTwo.Inner = works ' type conversion failure
End Class
The error message on the "fails" line is in the subject, and "Member.Inner" is highlighted. Incidentally, the same error occurs with trying to call a shared method of OuterBase.
The "works" line works, but there are a dozen (and counting) ChildClass classes in real life.
The "failsAsExpected" line is there to show that, with generics, each ChildClass has its own distinct Inner class.
My question: is there a way to get a variable, in class CollectionClass, defined as type Member.Inner? what's the critical difference that the compiler can't follow?
(I was eventually able to generate an object by creating a dummy object of type param and calling a method defined in OuterBase. Not the cleanest approach.)
Edit 2008/12/2 altered code to make the two "base" classes generic.
Dim succeeds as OuterBase.Inner
.net does not have C++'s combination of template classes and typedefs, which means what you are trying to do is not possible, nor does it even make sense in .net.
ChildClass.Inner and SomeOtherChildClass.Inner are the same type. Here's a short but complete program to demonstrate:
Imports System
MustInherit Class InnerBase
End Class
MustInherit Class OuterBase
Class Inner
Inherits InnerBase
End Class
End Class
Class ChildClass
Inherits OuterBase
End Class
Class OtherChildClass
Inherits OuterBase
End Class
Class Test
Shared Sub Main()
Dim x as new ChildClass.Inner
Dim y as new OtherChildClass.Inner
Console.WriteLine(x.GetType())
Console.WriteLine(y.GetType())
End Sub
End Class
The output is:
OuterBase+Inner
OuterBase+Inner
What were you trying to achieve by using "parameterised" nested classes? I suspect that either it wouldn't work how you'd want it to, or you can achieve it just by using OuterBase.Inner to start with.
Now if each of your child classes were declaring their own nested class, that would be a different situation - and one which generics wouldn't help you with.