Calling parent method within a parent method - objective-c

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.

Related

Is it possible to determine the type of a class at instantiation or convert the type afterwards without casting?

For example: I have some classes that all inherit from the same class.
Public Class MasterClass
' content
End Class
Public Class ClassA
Inherits MasterClass
'content
End Class
Public Class ClassB
Inherits MasterClass
'content
End Class
Public Class ClassC
Inherits MasterClass
'content
End Class
And I want decide on runtime which one I need. Then I can do something like this:
Private myInstance As MasterClass
If conditionA Then
myInstance = New ClassA
ElseIf conditionB Then
myInstance = New ClassB
Else
myInstance = New ClassC
End
But it can get quite long, and I still have to cast it evertime I use it.
I can assing a type to a variable, but I don't know how to use that type to create a new instance of that type..
Dim storedType As Type = GetType(ClassA)
Dim someInstance = New storedType 'Does not work
Is there a better way? Can you change the type of a variable at runtime?
I still have to cast it evertime I use it.
The idea around polymorphism and inheritance is that you don't have to cast them to use them. You can write things in such a way that the master class has all the functions etc that you need (whether or not they do anything) and then you call things as if you were just dealing with the master class but, because each child implements a different behavior, the end result is different - your program might not even know (if the child implementation came from a third party dll) what is going on but it doesn't matter
Can you change the type of a variable at runtime?
Sure, but you have to use it how it appears. Long chains of "if my object is an instance of x then cast my object as x and use method X1, else if my object is a y then cast as y and call y1" are not polymorphic/not leveraging inheritance principles properly - you're supposed to call myobject.whatever, and if my object is an x, then x1 happens and if it's a y then y1 happens
I want decide on runtime which one I need
But you don't have to do that in the class that knows about class a/b/c - each of class a/b/c can do that and hence become self contained. You can have all your instances in an array of the parent type, and visit each one asking them if they handle the condition and use the one that says it can
Consider a slightly better real world example than this artificial class a/b/c trope:
You are tasked with writing an app that can download an image (png, jpg or gif) from somewhere (http or ftp or disk location), rotate it and upload it to somewhere else
You decide to have an ImageRotator parent that specifies a CanHandle function and a Rotate function. It has 3 subclasses, one that handles jpg, one that rotates gif and one that does png. When presented with a PNG filename the JpgRotator says No when asked if it can handle it etc.
Separately you have a FileMover parent that CanHandle and has Download/Upload functions. Again, the parent doesn't implement these at all. The three subclasses implement the ability up/down an http, an ftp and a disk location
You create an instance of each rotator and put it into an array of ImageRotator type. You also create an instance of each mover onto an array that is a FileMover parent type.
Your user specifies a jpg in a http url, and to store it in a disk location at the end. You loop your FileMovers and ask each if they support the location the user provided. The http mover says yes, you invoke its download to a temp path. Then you pass he path to each rotator, the jpg rotator says yes, you call rotate. Finally, you look for another mover that can handle an output path of local disk...
Someone decides to extend your program with a plug-in dll that adds he ability to put files in and out of a db, and support tiff images.. ignoring the magic of how instances of their classes come to be in your arrays, you can see that your program can now move these new locations and types because the logic for whether they handle db/tiff is not a part of your code.. your code just treats everything consistently
In this case Interfaces are the best choice
Interface ABC
Property Text As String
Property Value As Integer
End Interface
Public Class MasterClass
End Class
Public Class ClassA
Inherits MasterClass : Implements ABC
Property Mystr As String Implements ABC.Text
Property Sum As Integer Implements ABC.Value
End Class
Public Class ClassB
Inherits MasterClass : Implements ABC
Property MyText As String Implements ABC.Text
Property Value As Integer Implements ABC.Value
End Class
Public Class ClassC
Inherits MasterClass : Implements ABC
Property str As String Implements ABC.Text
Property Value As Integer Implements ABC.Value
End Class
usage
Dim myABC As ABC
If conditionA Then
myABC = New ClassA
ElseIf conditionB Then
myABC = New ClassB
Else
myABC = New ClassC
End If
myABC.Text = "Interface"

marked and unmarked class in pharo 2.0 smalltalk

i need to implement the message markedSubclass in pharo that works just like subclass but i need the class that gets created to be somehow marked,for example i tried adding a unique instance variable to it after creating it but it's just not working,maybe i'm adding it to a wrong place.
the requirments are:
every subclass of this marked class should also be marked even if it
was created via subclass (not markedSubclass).
other than that a marked class should function just as a regular class should.
any help would be appreciated.
example:
User markedSubclass: #MarkedUser
User subClass: #UnmarkedUser
MarkedUser subclass: #MarkerUser2
i need to somehow know that MarkedUser and UnmarkedUser are both marked classes.
what i thought of lately is adding the method "isMarked" to Class class and this way all
the classes will have it, and each class will override it accordingly so if we write
User class isMarked.
it will return false but if we write:
MarkedUser class isMarked.
MarkedUser2 class isMarked.
it will return true for both.
but where can i add this method?and how can i make a class override the method in runtime?
Add a class method like the following to your User class:
markedSubclass: className
| subclass |
subclass := self subclass: className asSymbol.
subclass class compile: 'isMarked', String cr, String tab, ' ^ true'.
^ subclass
Then try in a workspace:
User markedSubclass: 'MyMarkedSubclass'
Add an #unmarkedSubclass: class method accordingly.
You could then override the general #subclass: method in your User class to set the same marker as the receiver.

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.

MATLAB OOP, can I call calling class methods?

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)

Are scopes in rails class or instance methods?

This is a question from a rails noob trying to understand concerns and scopes.
I always thought scopes were class methods in rails but then the other day I saw this code from DHH:
module Visible
extend ActiveSupport::Concern`
module ClassMethods
def visible_to(person)
where \
"(#{table_name}.bucket_id IN (?) AND
#{table_name}.bucket_type = 'Project') OR
(#{table_name}.bucket_id IN (?) AND
#{table_name}.bucket_type = 'Calendar')",
person.projects.pluck('projects.id'),
calendar_scope.pluck('calendars.id')
end
end
end
So the way the visible method is used is like so:
current_account.posts.visible_to(current_user)
This is what is confusing me. Self here is a collection of posts so we are acting on instances whereas the visible method seems to be meant to be used as a class method. Isn't david trying to call a class method as a dynamic scope? Could someone please clarify?
Class methods on classes which inherit ActiveRecord::Base can be used also as scopes (on ActiveRecord Relation objects).
Since the module Visible was meant to be mixed into a model which inherits ActiveRecord::Base, its class method visible_to can be used also as a scope.
If this did not clear the issue, you can implement a scope which gets all adult users (age > 20) in the following ways:
class User < ActiveRecord::Base
scope :adult, lambda { where("age > ?", 20) } # with a scope
class << self
def adult # with class method
where("age > ?", 20)
end
end
end
And use it exactly the same with User.adult