繁体   English   中英

Objective-C中的子类化和继承

[英]Subclassing and inheritance in objective-c

我有一个名为AbstractBook的类,它具有一个属性:

@property(strong) AbstractPage *page;

现在说我有一个AbstractBook的子类WhiteBookAbstractPage的子类WhitePage 我希望WhiteBook类继承page对象,但是在此类中,我希望它成为特定的WhitePage类而不是AbstractPage

因此,在WhiteBook ,我只是将该属性重新声明为WhitePage

@property(strong) WhitePage *page;

但是,我收到警告: WhitePage is incompatible with AbstractPage inherited from AbstractBook. 什么是实现我要去的正确方法?

从根本上说,您想做的事是不可能的。 不要忘记这一点:

@property(strong) AbstractPage *page;

声明一个getter 和setter

通常来说(这通常是面向OO编程的,而不仅仅是Objective-C),覆盖获取器返回超类实现的返回类型的子类没有问题,因为这不会破坏API约定。 在您的情况下, WhitePage的实例也是AbstractPage

但是,二传手是不同的。 您不能限制参数的类型,因为您的子类必须在使用AbstractBook任何地方都可以使用,因此,在认为它是AbstractBook事物上调用setter的代码有权传递任何 AbstractPage子类的实例,因为这就是API所说的。

我想我要做的是在AbstractBook添加一个名为

-(bool) isLegalPage: (AbstractPage) aPage;

在基类中始终返回true,但仅对WhiteBook白页返回true。 然后,我将按以下方式手动实现setter:

-(void) setPage: (AbstractPage*) aPage
{
    if (![self isLegalPage: aPage])
    {
        // throw an exception or do other error notification
    }
    else
    {
        Do the assignment according to reference count/ARC/GC model
    }
}

请说明,如果页面不合法,setter将抛出异常,并且人们应该使用isLegalPage:方法对此进行测试。

替代ID具有只读属性,并且在基类和子类中使用不同的setter,或者在基类中根本没有setter。

在Objective C中没有属性类型的协方差 ,因此,如果要让某个属性返回AbstractPage的子类,则需要在WhiteBook子类中定义一个单独的属性,例如whitePage 您也可以从page属性返回相同的值,它将起作用。 而且,如果您的用户在AbstractPage*上调用方法,他们甚至不需要将其WhitePage*WhitePage*

切记要编程到接口而不是实现。

======================

选项1

如果您的白皮书确实是AbstractBook的后代,则不需要使WhiteBook具有一个称为“ page”的新属性,因为您的AbstractBook已经声明它是免费的。

只要WhitePage从AbstractPage继承,您就应该能够将页面对象转换为WhitePage。 然后,您将获得AbstractPage的所有原始功能以及WhitePage的所有功能。

因此,您无需在Whitebook中重新声明页面。 如果您转到Whitebook.h文件并删除此行

@property(strong) WhitePage *page;

然后进入您的Whitebook.m文件并键入self.page,您应该不会收到任何编译警告。 然后,您可以将页面转换为WhitePage,并且应该不错。

警告:这意味着您将需要在使用页面的任何地方将其转换为WhitePage,这是不理想的。

======================

选项:2

您也可以尝试按原样保留代码,但请确保再次在WhiteBook中合成“ page”属性。

======================

选项:3

您也可以尝试保留代码,但请确保对WhiteBook中的“页面”道具使用@dynamic。 然后自己实现getter,并返回WhitePage而不是AbstractPage。

如何用更具体的类型覆盖超类的属性?

一般来说,如果你使用@synthesizeAbstractBook@dynamic在你的WhiteBook类,(除非,当然,你可以使用它应该正常工作AbstractPage合成方法来分配非WhitePagepage )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM