开发者

Is it good style to declare methods in .h when they're intended to be overwritten by subclass?

开发者 https://www.devze.com 2022-12-10 12:56 出处:网络
I have a class which is intended to be abstract. This means: When someone subclasses it, a few methods MUST be overwritten.

I have a class which is intended to be abstract. This means: When someone subclasses it, a few methods MUST be overwritten.

But on the other hand, those methods are not intended to be called manually from anywhere except inside the abstract class (the superclass of the subclass).

Must I dec开发者_开发知识库lare these methods in .h anyways or can I just add comments in .h which say "you must overwrite -foo and -bar"? Or is there a better pattern to make abstract methods?


Related: Is there a way to create an abstract class in Objective C?

Objective-C doesn't actually have a way to declare a class as abstract. From Apple's Docs:

Abstract Classes

Some classes are designed only or primarily so that other classes can inherit from them. These abstract classes group methods and instance variables that can be used by a number of different subclasses into a common definition. The abstract class is typically incomplete by itself, but contains useful code that reduces the implementation burden of its subclasses. (Because abstract classes must have subclasses to be useful, they’re sometimes also called abstract superclasses.)

Unlike some other languages, Objective-C does not have syntax to mark classes as abstract, nor does it prevent you from creating an instance of an abstract class.

The NSObject class is the canonical example of an abstract class in Cocoa. You never use instances of the NSObject class in an application—it wouldn’t be good for anything; it would be a generic object with the ability to do nothing in particular.

The NSView class, on the other hand, provides an example of an abstract class instances of which you might occasionally use directly.

Abstract classes often contain code that helps define the structure of an application. When you create subclasses of these classes, instances of your new classes fit effortlessly into the application structure and work automatically with other objects.

So to answer your question, yes, you need to place the method signature in the header, and should implement the method in the base class such that it generates an error if called, like the related question's answer states.

You can also use a protocol to force classes to implement certain methods.

However you choose to implement the base class, clearly document in the header, as well as in your documentation, exactly what the class assumes and how to go about sub-classing it correctly.


Whenever possible write your code so that improper implementations fail to compile. If you cannot do that then you should try to generate a runtime error (at the very least in a debug build) if the subclass is not written correctly. Do not rely on comments because people will not read them.


You must declare your "protected" and "abstract" methods in a header file, but you can use separate categories to clearly indicate their purpose and intended use.

@interface MyBaseClass : NSObject {
}
- (void)foo;
@end

@interface MyBaseClass(ProtectedMethods)
- (void)bar;
@end

@interface MyBaseClass(AbstractMethods) // Subclasses must implement
- (void)internalBar;
@end

You can put everything in a single header, or you could put your protected and abstract declarations in a separate "protected" header, say MyClassProtected.h, meant to be included only by your subclass implementations. It depends on how badly you want "hide" your protected methods.

Your base class can log, assert, or throw when an abstract/pure-virtual method is called.


As other people have said, Objective-C does not support pure virtual classes.

You can enforce pure virtual behaviour at runtime though. The cleanest way to do this is by using the Objective-C runtime's _cmd and NSObject's -doesNotRecognizeSelector:

- (void)iMustBeImplementedInaSubclass;
{
    [self doesNotRecognizeSelector:_cmd];   // Pure virtual
}

As ben says you are probably better served by using a protocol to get your API design right.

0

精彩评论

暂无评论...
验证码 换一张
取 消