创建更好的面向对象设计

Ker*_*rog 2 objective-c ios

我有以下课程:

Teacher
Student
Class (like a school class)
Run Code Online (Sandbox Code Playgroud)

它们都来自具有以下代码的KObject:

- initWithKey
- send
- processKey
Run Code Online (Sandbox Code Playgroud)

Teacher,Student Class都使用来自KObject父类的函数processKey和initWithKey.他们实现了自己的发送版本.我遇到的问题是KObject不应该被实例化.它更像是一个抽象类,但在objective-c中没有抽象类概念.它仅对允许子类访问一个属性和两个函数有用.

我能做什么才能使KObject无法实例化,但仍允许子类访问KObject的函数和属性?

Jas*_*ues 5

抽象类在Objective-C中非常常见,而类集群 --Cocoa中广泛使用的模式 - 是抽象工厂模式的变体.

然而,正如您所指出的,没有语言工具可以将方法或类明确地划分为抽象 - 这通常在文档中完成.如果您需要额外的安全性以确保不以非预期的方式使用课程,您可以执行以下操作:

初始化:

//Invocation of the initializer in a sub-class will not raise the exception. 
if ([self class] == [MyAbstractClass class]) 
{
   [NSException raise: . . . class is abstract - use subclass. 
}
Run Code Online (Sandbox Code Playgroud)

方法:

- (BOOL)someAbstractMethod
{
    [NSException raise:NSInvalidArgumentException format:@"%@ is abstract", 
        NSStringFromSelector(_cmd)];
    return NO;
}
Run Code Online (Sandbox Code Playgroud)

协议与抽象基础

我不同意声明"在其他答案中使用协议更好".虽然可以将抽象基类与协议组合在一起,但它不一定更好.

何时使用协议

使用协议指定集成合同 - 就像插件架构一样.一个例子是"媒体播放器",其中电影音频流的"播放"的实现将是完全不同的.

何时使用抽象基类(或类集群)

当共享类层次结构之间的某些行为时,使用抽象基类,并且某些实现细节在特定子类型之间有所不同..在此处使用协议不一定更好,除非您希望传达这组方法可以替换为另一个实现的意图.

类集群:

对于类集群,获取其中一个子类型的实例的工厂方法在基类本身上.有时,这会产生可读性和内聚性良好的代码.(可能与您的具体示例无关,但与Objective-C中的抽象类有关的一个有趣点)