Question regarding subclassing - objective-c

This is probably asked before but I have no idea what to search for. This is my hierarchy now: NSObject > FirstSubclass > SecondSubclass. But I'm going to implement a new feature in my app which requires changing a few details in FirstSubclass when a certain condition is met. So actually I would need a subclass between FirstSubclass and SecondSubclass to overwrite FirstSubclass' behavior. I do not need to overwrite things in SecondSubclass itself but I need some kind of super for all different SecondSubclass subclasses I have. I could change everything in FirstSubclass to use "if then statements" but first I wanted to be sure if there wasn't another option. Do I need a "protocol" for this? Like in SecondSubclass : FirstSubclasslass <WeirdThingIDontKnow> ?

It sounds like you need ducktyping. In objective c it can be accomplished by using respondsToSelector, performSelector or NSInvocation. This can simplify a class hierarchy a lot.

Create a new object that derives from FirstSubclass (say InBetweenSubClass) and overrides the necessary methods of FirstSubclass. Then change SecondSubclass to derive from InBetweenSubClass instead of FirstSubclass.
There is no "override" equivalent in Objective-C, you just implement a method with the same signature and that method of the base class is overridden. You can do something like this as well, if special condition is met, use new method, otherwise use the method of the base (super) class:
-(void) test
{
if (self.specialcondition)
{
[self newTest];
}
else
{
[super test];
}
}

Related

Objective C Helper Methods

Novice here attempting to understand inheritance. If I initialize a new object with several properties and I want other classes to help assign values to those properties, do I need to create instances of those other classes? Visualized:
-(ObjA *)init{
self = [super init];
self.property1 = [method from Class A];
self.property2 = [method from Class B];
self.property3 = [method from Class C]; etc...
return self;
}
In other words, assuming Class A, B, and C need to know what Object A is, would I need to make those class methods instance methods and initialize each object? Is there another way to go about this? Thank you in advance for your help.
In other words, assuming Class A, B, and C need to know what Object A
is
NO.
You can simply call a method from ClassA/B/C etc. But the return type must match with respective property.
Let, the property1 is for kind NSString then your ClassA method must be
-(NSString *)methodClassA{
...
return someStringValue;
}
Then you need to use:
ClassA *objClassA=[ClassA new];
self.property1=[objClassA methodClassA];
Or you can go with class method by this:
+(NSString *)methodClassA{
...
return someStringValue;
}
And using it as:
self.property1=[ClassA methodClassA];
assuming Class A, B, and C need to know what Object A is
The initialization code of an object should be self contained, unless it is using functionality owned by a different object, in which case the object acts as a client of that functionality. That is, objectA acts as client of A,B,C (as seen in your code).
But this doesn't imply that A,B,C need to know (have a dependency on) objectA. By doing that, you are saying that they don't have a reason to exist on their own.
In general,
Every class or method should have one encapsulated purpose. This makes it easy to understand, change, and test in isolation. It's a common pattern to create classes whose sole purpose is to encapsulate information to create a different class, but to split that in three different classes is beyond weird (as in, I can't imagine an example of that).
An object shouldn't be allowed to exist in an unusable state, nor should it require non essential information when it is created. Does objectA require those properties to function? if it does, your code is right, if it doesn't, the initializer is providing too much information and making it less reusable.
Try to rethink your doubt with a real (instead abstract) example. You may end up making sense of it yourself.

"Decorate" several classes with a specific method in Obj-C

I'm not yet that into design patterns so "Sorry!" to bother you with such a question, that might be obvious.
The thing is, I have several classes: Show, Segment, Command. These three classes are totally different, except the one thing: They all have an NSArray called schedules, which contains ScheduleItem classes.
In my workflow I need to check, if the current time matches a scheduleItem to set the Show,Segment or Command active. So, I'd like to have a method on all these three classes called isActive(). Since this method does the same for all current and future classes, I'm looking for a way to implement the isActive method just once, and reuse it in those classes.
Is there a nice way doing this?
To remember, those classes have absolutely nothing in common, except the schedules array. So, I'd like to avoid subclassing. But you can convince me otherwise.
You can create smth like this
#interface ScheduleCollection : NSObject {
NSArray* schedules;
}
#property NSArray* schedules;
/**
Return true if matches.
*/
-(BOOL) match:(ScheduleSclass); //or call it isActive or whatever you like
#end
Then replace schedules array in Show, Segment, Command with ivar of this class. If you need to compare time just get the property and call match:
Show* show = ...;
BOOL m = [show.schedules match: my_time];
There's really no design pattern for this except generic inheritance (shared base class with the method). You can't add it as a category for all three, as they don't share a base class.
If you want to avoid introducing a base class, you can use the fact that type id is a typeless object, and you can invoke any method on it at runtime. Only it will fail if the actual objec doesn't have the method...
On each of the objects, create a method called getSchedule like this:
- (NSArray*) getSchedule {
return schedule;
}
Then just create this method somewhere else
-(BOOL) isActive:(id)anyObjectWithGetScheduleAnyOtherWillFailWithSelectorNotImplemented
{
// You could do an explicit check to determine if the object passed in implements
// getSchedule, but I skipped it here.
NSArray* schedule = [anyObjectWithGetScheduleAnyOtherWillFailWithSelectorNotImplemented getSchedule];
<your implementation here>
}
In my opinion, you would be better off just introducing a shared base class, as it's a lot clearer and won't really take that much more work. But if you have good reasons not to, this will also do the job.

Write a method signature including the class name for documentation

Is there a language standard (or common practice) for describing an Objective-C method with the class name included?
For example, let's say I have the following pseudocode:
class Foo
{
void bar(int i);
}
and I want to write some documentation for it.
If this were Java, I would refer to the method as Foo.bar(). If it were C++, I would use Foo::bar. What is the right way to do this for Objective-C?
I know that I can use -(void) bar:(int)i, but this does not include the class (or protocol) name.
Usually it's -[Foo bar:]. There may be a plus sign instead of minus when the method is a class method.

cannot respond to warning in Objective C

I am getting a warning:
RS232Msg cannot respond to
"-initWithRS232MsgRawEncoded"
Code is
-(void)createMessage
{
RS232Msg* pMsg;
//pMsg = new RS232MsgRawEncoded(static_cast<int>nMessageNumber); in cpp
pMsg = [pMsg initWithRS232MsgRawEncoded:(int)nMessageNumber];
}
initWithRS232MsgRawEncoded is a derived class of RS232Msg.
and pMsg is a pointer to RS232Msg. The createMessage is a method that is declared in RS232Msg How to make it to access ?
If you defined initWithRS232MsgRawEncoded in a class derived from RS232Msg you cannot use that selector with RS232Msg*.
If I understand correctly what you are trying to do, you would like to add one more possibility of creating RS232Msg objects by initializing them with raw encoding.
You can do that in different ways. One is creating a sort of "factory" class (it would not be an orthodox factory as per GoF patterns, but that does not matter). This class can have a static function that is exactly your initWithRS232MsgRawEncoded.
Another option you have is define a category for RS232 and then add the initWithRS232MsgRawEncoded into it. Categories are a way to extend classes without the need of subclassing them. This is a skeleton of how you would go about it in your case:
#interface RS232 (MyRS232Extension)
(id)initWithRS232MsgRawEncoded:....;
#end
#implementationRS232 (MyRS232Extension)
....
#end

Null object pattern in Objective-C

In Java, it is very easy to code the following design:
public abstract class Pizza {
public static final Pizza.NULL = new Pizza() {
/* "null" implementations */
}
/* actual/abstract implmentations */
}
What is the preferred method to attain the same efficient scenario in Objective-C? I have been unable to find any documentation on the subject, and I have tried a couple different scenarios with static const, #define etc. but none of them seem to work out as well as the Java method above.
I would like to avoid writing a concrete NullPizza class that has a static method to obtain the singleton instance, as it seems more 'proper' for it to be some final property/field of the highest-level interface. (Pizza, in this case.)
Edit: While I understand how the NULL pattern specifically would be handled due to Obj-C's unique method of handling method calls to 'nil', what about other static common instances, such as Response.YES and Response.NO? (See comments for discussion.)
There is no need for this type of pattern in Objective-C because it is not considered a runtime error to message a nil instance of a class. If the method has a defined return type, there are defined returns from messaging a nil object (e.g., methods that return an integer return 0 when messaging a nil object).
There are two things which can help here. The first is nil, the Objective-C equivalent of the Java NULL pointer - it can actually receive messages and respond to them. It will always return nil if the return value is an object, and 0 if the return value is some primitive type. Therefore if the Null behaviour of your object is "do nothing" you can easily just use nil as the Null value.
The other thing which is helpful is for when you need to store a placeholder or null value in a container object - these usually throw exceptions if you attempt to add nil as a value. Instead you can use the singleton +[NSNull null], which does nothing except act as a "this space intentionally left blank" object.
With these two weapons at your disposal there should be no reason to write a null instance of a custom class :-)
For your Response.YES and Response.NO, I assume you have instances that you do want to change, rather than just making all Response properties read-only.
A common pattern in Cocoa is to have both immutable and mutable versions of a class (NSArray versus NSMutableArray). For your response example, it would make sense to have an immutable Response class that has the static YES and NO methods, and a MutableResponse subclass that exposes setters for those times where you do want objects to change them. Does this cover your second example?
I don't think there is an easy way to provide this implementation. You're asking for something that is a language feature of Java to be implemented in Objective-C - you can do it but you have to write the code that is in the Java runtime yourself - there is nothing to stop you doing this but it's not something the language has built in.
It's a bit like asking "How do I show a Windows style 'one menu per window" UI in Cocoa' - you can do it but it's not provided for free from the framework. Or, "how can I easily implement Objective-C's nil pointer handling in Java?"
If you really want to see this type of functionality I think you should follow the NSArray/NSMutableArray design pattern. Declare a superclass that can handle all of your special cases:
#interface NullPizza : NSObject
{
}
- (BOOL)areYouANullPizza;
#end
and then subclass with your real Pizza and include a newNullPizza class method (which is just syntax sugar):
#interface Pizza : NullPizza
{
}
+ (Pizza*)Null;
#end
#implementation Pizza
+ (Pizza*)newNullPizza
{
return [[NullPizza]alloc init]; // Singleton code left as an exercise.
}
- (BOOL)areYouANullPizza;
{
return NO;
}
#end
Note that if you wanted to implement a +(Pizza*)NULL method on Pizza you should autorelease the new NullPizza you create.
Disclaimer, I typed this code straight into SO. I'd be surprised if it compiles but you get the idea.