views:

391

answers:

6

For a subclass, is there way I can remove/stop methods from super class implementation?

(ie. nsstring has a method length. i want to stop "mystring" class from attaining the length method).

+1  A: 

Can't you simply override the method ?

krico
+6  A: 

You can override the method to call doesNotRecognizeSelector::

- (NSUInteger)length
{
    [self doesNotRecognizeSelector:_cmd];
}

But if you have to do this, you may want to rethink whether you really want to subclass in the first place. It may be better to use composition instead of inheritance if you only want to "inherit" specific behaviors/methods.

mipadi
@bbum is correct -- calling doesNotRecogniseSelector is madness.
pixel
@pixel: I noted essentially the same thing in the caveat at the end of my answer.
mipadi
+2  A: 

You override respondsToSelector: to return NO for the appropriate selectors and override the method to call doesNotRecognizeSelector:.

Chuck
+1  A: 

You can use doesNotRecognizeSelector:. From the documentation:

- (id)copy
{
    [self doesNotRecognizeSelector:_cmd];
}

However, there's a good chance that this is the Wrong Thing To Do. The interface for a class is a contract; it states that an instance that is a kind of that class (which includes subclass instances) will accept that message. When your MyString is passed as an NSString and it doesn't accept the length message, it's violating the contract and will likely cause the program to crash, since no one would think to handle an NSInvalidArgumentException from invoking length on an NSString.

outis
The example I gave was simplified from where I'd actually use it. I was thinking for something like a view where I don't want to allow the ability to add subviews using the addSubview method.
Devin Ross
If you were to override `-addSubView:` it would probably be a disaster. Other objects expect the method to exist on subclasses of NSView/UIView and will call it all over the place and you will get random exceptions thrown all over the place. The same goes for any publicly documented interface of any class.
JeremyP
+10  A: 

length is a primitive method in the NSString class cluster; pretty much every other method in NSString is implemented using calls to length.

Instead of going down this path of madness, make your class a subclass of NSObject. Without a length method, it isn't really a valid NSString subclass anyway.

bbum
+1  A: 

The better answer is "don't do that". Don't try removing methods, instead put an NSAssert(NO, @"don't call me") in your class's implementation, and never call it yourself.

If you must make a "thing that is like X but doesn't do Y", make a new class, and delegate behavior to an instance of the real X.

mdhughes