While hearing talk around the objective-c programming community, I hear the term "override" thrown around a lot. I'm fairly familiar with general object oriented programming terms, but from an iOS and Objective-c standpoint, the definition is a little unclear to me. According to Wikipedia:
Method overriding, in object oriented programming, is a language
feature that allows a subclass or child class to provide a specific
implementation of a method that is already provided by one of its
superclasses or parent classes.
Cool. That makes sense. But what throws me off is... isn't that the whole point of the "family relationship", where the subclass inherits all of the public methods and variables of it's superclass. The standard "hierarchy" model. That has never quite made sense to me. I hear some of the senior developers say things such as "Once he said it's okay to override a category I was done listening".
That got me to thinking, I should probably get a better grasp on what exactly overriding is. Could someone explain it in greater detail related specifically to Objective-C / Cocoa Touch?
This is very common in all OOP languages.
Often times a base class will provide a default (i.e. simple, unexciting) implementation for a method. Then, derived classes will override that default implementation and provide a specific (i.e. more interesting) implementation.
Consider an Animal base class that exposes a Speak() method. Well there is no common way that animals speak, so that default implementation would probably just do nothing.
A Dog class, which is derived from Animal, can override Speak() to actually make a barking sound, which is more appropriate than the default mute case.
Your quote from your senior seems to me like it's mis-heard or -remembered. I'd bet it was "...it's okay to override a method in a category I was done..."
Using a category to "override" a method on the same class is a Bad Idea: the original method is clobbered and cannot be called. In addition, if the original method was itself implemented in a category, then which version is actually used is undefined. This is not the same as overriding an inherited method (thus my scare quotes).
Overriding an inherited method works as expected: a class defines a method which was already defined in one of its ancestors. When the method is called on an instance of the subclass, the redefined code is run. The class itself can invoke the non-overridden version by using the super keyword as the receiver of the appropriate message.
Related
We have an app that makes fairly extensive use of TIniFile. In the past we created our own descendant class, let's call it TMyIniFile, that overrides WriteString. We create one instance of this that the entire app uses. That instance is passed all around through properties and parameters, but the type of all of these is still TIniFile, since that is what it was originally. This seems to work, calling our overridden method through polymorphism, even though all the variable types are still TIniFile. This seems to be proper since we descend from TIniFile.
Now we are making some changes where we want to switch TMyIniFile to descend from TMemIniFile instead of TIniFile. Those are both descendants of TCustomIniFile. We'll also probably be overriding some more methods. I'm inclined to leave all the declarations as TIniFile even though technically our class is no longer a descendant of it, just to avoid having to change a lot of source files if I don't need to.
In every tutorial example of polymorphism, the variable is declared as the base class, and an instance is created of the descendant class and assigned to the variable of the base class. So I assume this is the "right" way to do it. What I'm looking at doing now will end up having the variables declared as, what I guess you'd call a "sibling" class, so this "seems wrong". Is this a bad thing to do? Am I asking for trouble, or does polymorphism actually allow for this sort of thing?
TIniFile and TMemIniFile are distinct classes that do not derive from each other, so you simply cannot create a TMemIniFile object and assign it to a TIniFile variable, and vice versa. The compiler won't let you do that. And using a type-cast to force it will be dangerous.
You will just have to update the rest of your code to change all of the TIniFile declarations to TCustomIniFile instead, which is the common ancestor for both classes. That is the "correct" thing to do.
The compiler is your friend - why would you lie to it by using the wrong type ... and if you do lie to it why would you expect it to know what you want it to do?
You should use a base class that you derive from, like TCustomIniFile. I would expect compile issues if you are trying to make assignments which are known at compile time to be wrong.
The different classes have different signatures so the compiler needs to know which class it is using to call the correct method or access the correct property. With virtual methods the different classes setup their own implementation of those methods so that the correct one is called - so using a pointer to a base type when you call the virtual method it calls that method in the derived type because it is in the class vtable.
So if the code does compile, it's very likely that the compiler will not be doing the right thing ...
Many CocoaPod and native iOS libraries use protocols that they name either CustomClassDelegate or CustomClassDataSource as a means to do some setup or customization. I was wondering when I should use this programming model, because it seems like I could accomplish much of this with properties.
Example
If I define a custom class called SmurfViewController that has a SmurfLabel, is it better practice to store the smurfLabel as a private property and have a public computed property called smurf that looks like this:
private var smurfLabel = UILabel()
public var smurf: String {
get {
return smurfLabel.text
}
set(text) {
smurfLabel.text = text
}
}
or should I define a SmurfDataSource that has a public function that looks like this:
func textForSmurfLabel() -> String {
return "smurfText"
}
When should I use what here?
You should just use a property for that. Delegates and Datasources are for different controllers/Objects to speak to one another when the alternative is to instantiate the controller/object from the navigationStack/view hierarchy. A Delegate forms a specific communication between the two that allows for clear knowledge in what their relationship is while keeping them decoupled (assuming you try to keep it that way). I disagree with the article that says callbacks are "better". They are amazing and I advise using them often, but just understand that most options that swift provides you with have a place where they work best.
I might be slightly bias, but Swift is an amazing language with OOP being a backbone and everything it has was well put together in order to provide the correct tools for each situation you find yourself in.
I often find myself using both of those tools and one other more customizable option in my more advanced setups where I have an overseeing viewController that manages many child controllers. It has direct access to all of them that are active but if any of its children communicate with it, it is through delegates. Its main job is just to handle their place on the screen though, so I keep everything manageable.
Delegates and data sources are more appropriate for offloading behaviors to other entities, not simple values. In other words, if your type just needs a value for something, you are correct that it makes more sense to expose that as a property that can be set from the client code.
But what should happen (for example) when a user taps a specific table view cell is a behavior that shouldn't be hard coded into UITableView. Instead, for flexibility, any implementation of that behavior can be created in a delegate and called by the UITableView when appropriate.
In general, think of delegation as a way to make subclassing unnecessary, because the methods you would normally override in a subclass are instead moved into a protocol that can be implemented by ANY type, not just a subclass of the base type. And instead of calling internally implemented methods to get certain behaviors, your type is simply calling those behaviors on an external collaborating class (the delegate).
So perhaps the best guideline for when to use a data source or delegate is the question: "Would I need to subclass this class in order to change this value or behavior in the future". If the answer is no, because you can just set a property from client code, then don't use delegation. If the answer is yes, then offload that behavior to a delegate or data source instead of forcing future programmers to subclass your class to make it work for their use case.
Delegate is an interface for the undefined activities.
so when you make a SDK or framework, you must provide an interface so that users can write a proper code for the interfaces' expecting activity.
i.e, Table View needs a datasource to show it's contents, but the apple's library developers doesn't know the content whatever contents their library users will use. so they provided an interface like datasource, delegate.
and in the library, they just call this methods. that's the way the library should be made.
But in your code, the label is defined very explicitly as well as it's in the current view, and you don't need to make an interface for an undefined activity.
if you want know more about this kind of coding style, you need to do some researches on Software Design Pattern.
https://en.wikipedia.org/wiki/Observer_pattern
https://en.wikipedia.org/wiki/Delegation_pattern
https://en.wikipedia.org/wiki/Software_design_pattern
I love apple's sdk very much, because they used all the needed design patterns very properly.
When my constructors are pure arguments-to-propeties setters then I'm not sure where to put other code that a class needs to properly work.
For example in JavaScript I'm programming a WindowMessageController that processes message events on the window object.
In order for this to work, I must somewhere attach the handler:
var controller = this;
this.applicableWindow.addEventListener("message", function(event) {
controller.messageAction(event.data);
}
Where does this stuff correctly belongs?
in the constructor
in the .initialize() method - introduces temporal coupling
in the WindowMessageControllerFactory.create(applicableWindow) - quite a distant place for so central piece of code. This means that even such a small class would be split into two pieces.
in the composition root itself - this would multiply its size when doing all the time
in some other class WindowMessageRouter that would have only one method, the constructor, with this code
EDIT
This case seems special because there is usually only one instance of such a controller in an app. However in more generalized case what would be the answer if I was creating an instances of Button class that would wrap over some DOM <button /> element? Suddeny a
button = buttonFactory.create(domButtonEl);
seems much more useful.
Do not put any real work into constructors. Constructors are hardly mockable. Remember, seams aka methods are mockable. Constructor are not mockable because inheritance and mocking.
Initialize is a forbidden word, to much general.
Maybe, but you can implement factory as a static method of class too, if you are scared of many classes ,)
Composition root is just an ordinary factory. Except it is only one, because your app probably have just one entry point ,)
Common, we are using Javascript. If you need just one factory method, why you need class for it? Remember, functions are first class objects.
And for edit. There is nothing special on singetons, unless they do NOT control own lifecycle.
Golden rule: Always (almost ,) do separation between app wiring and app logic. Factories are wiring. Just wiring, no logic, therefore nothing to test.
I would place this code into initialize(window) method but this method cannot be part of WindowMessageController's public API - it must be visible and called by direct users (so composition root and tests) only.
So when DI container is returning WindowMessageController instance then it is container's responsibility that initialize method has been called.
Reply to EDIT: Yes, this factory seems to be the best way for me. Btw. don't forget that the factory should probably have a dispose method (i.e. unbinds the event handler in case of button)...
I think you need to create a Router class that will be responsible for events distribution. This Router should subscribe to all the events and distribute them among the controllers. It can use some kind of the message-controller map, injected into constructor.
I'm currently working on a Rails project, and have found times where it's easiest to do
if object.class == Foo
...
else if object.class == Bar
...
else
...
I started doing this in views where I needed to display different objects in different ways, but have found myself using it in other places now, such as in functions that take objects as arguments. I'm not precisely sure why, but I feel like this is not good practice.
If it's not good practice, why so?
If it's totally fine, when are times that one might want to use this specifically?
Thanks!
Not sure why that works for you at all. When you need to test whether object is instance of class Foo you should use
object.is_a? Foo
But it's not a good practice in Ruby anyway. It'd much better to use polymorphism whenever it's possible. For example, if somewhere in the code you can have object of two different classes and you need to display them differently you can define display method in both classes. After that you can call object.display and object will be displayed using method defined in the corresponding class.
Advantage of that approach is that when you need to add support for the third class or a whole bunch of new classes all you'll need to do is define display method in every one of them. But nothing will change in places where you actually using this method.
It's better to express type specific behavior using subtyping.
Let the objects know how they are displays. Create a method Display() and pass all you need from outside as parameter. Let "Foo" know to display foo and "Bar" know how to display bar.
There are many articles on replacing conditionals with polymorphism.
It’s not a good idea for several reasons. One of them is duck typing – once you start explicitly checking for object class in the code, you can no longer simply pass an instance of a different class that conforms to a similar interface as the original object. This makes proxying, mocking and other common design tricks harder. (The point can be also generalized as breaking encapsulation. It can be argued that the object’s class is an implementation detail that you as a consumer should not be interested in. Broken encapsulation ≈ tight coupling ≈ pain.)
Another reason is extensibility. When you have a giant switch over the object type and want to add one more case, you have to alter the switch code. If this code is embedded in a library, for example, the library users can’t simply extend the library’s behaviour without altering the library code. Ideally all behaviour of an object should be a part of the object itself, so that you can add new behaviour just by adding more object types.
If you need to display different objects in a different way, can’t you simply make the drawing code a part of the object?
I am dealing with a large codebase that has a lot of classes and a lot of abstract methods on these classes. I am interested in peoples opinions about what I should do in the following situation.
If I have a class Parent-A with an abstract method. There will only be 2 children. If Child-B implements AbstractMethodA but Child-B does not as it doesnt apply.
Should I
Remove the abstract keyword from parent and use virtual or dynamic?
Provide a empty implementation of the method.
Provide an implementation that raises an error if called.
Ignore the warning.
Edit: Thanks for all the answers. It confirmed my suspicion that this shouldn't happen. After further investigation it turns out the methods weren't used at all so I have removed them entirely.
If AbstractMethodA does not apply to Child-B, then Child-B should not be inheriting from Parent-A.
Or to take the contrapositive, if Child-B inherits from Parent-A, and AbstractMethodA does not apply to the child, then it should not be in the parent either.
By putting a method in Parent-A, you are saying that the method applies to Parent-A and all its children. That's what inheritance means, and if you use it to mean something different, you will end up in a serious dispute with your compiler.
[Edit - that said, Mladen Prajdic's answer is fine if the method does apply, but should do nothing for one or more of the classes involved. A method which does nothing is IMO not the same thing as a method which is not applicable, but maybe we don't mean the same thing by "doesn't apply"]
Another technique is to implement the method in Child-B anyway, but have it do something drastic like always returning failure, or throw an exception, or something. It works, but should be regarded as a bit of a bodge rather than a clean design, since it means that callers need to know that the thing they have that they're treating as Parent-A is really a child-B and hence they shouldn't call AbstractMethodA. Basically you've discarded polymorphism, which is the main benefit of OO inheritance. Personally I prefer doing it this way over having an exception-throwing implementation in the base class, because then a child class can't "accidentally" behave badly by "forgetting" to implement the method at all. It has to implement it, and if it implements it to not work then it does so explicitly. A bad situation should be noisy.
If implementation in descendants is not mandatory then you should go for 1+2 (i.e. empty virtual method in ancestor)
I think that, generally speaking, you shouldn't inherit from the abstract class if you are unable to implement all of the abstract methods in the first place, but I understand that there are some situations where it still makes senseto do that, (see the Stream class and its implementations).
I think you should just create implementations of these abstract methods that throw a NotImplementedException.
You can also try using ObsoleteAttribute so that calling that particular method would be a compile time error (on top of throwing NotImplementedException of course). Note that ObsoleteAttribute is not quite meant to be used for this, but I guess if you use a meaningful error message with comments, it's alright.
Obligatory code example:
[Obsolete("This class does not implement this method", true)]
public override string MyReallyImportantMethod()
{
throw new NotImplementedException("This class does not implement this method.");
}
make it virtual empty in base class and override it in children.
You could use interfaces. Then Child-A and Child-B can both implement different methods and still inherit from Parent-A. Interfaces work like abstract methods in that they force the class to implement them.
If some subclasses (B1, B2, ...) of A are used for a different subset of its methods than others (C1, C2, ...), one might say that A can be split in B and C.
I don't know Delphi too well (not at all :) ), but I thought that just like e.g. in Java and COM, a class can 'implement' multiple interfaces. In C++ this can only be achieved by multiply inheriting abstract classes.
More concrete: I would create two abstract classes (with abstract methods), and change the inheritance tree.
If that's not possible, a workaround could be an "Adapter": an intermediate class A_nonB_ with all B methods implemented empty (and yielding a warning on calling them), and A_nonC_. Then change the inheritance tree to solve your problem: B1, B2, ... inherit from A_nonC_ and C1, C2,... inherit from A_NonB_.