3

AbstractBookプロパティを持つ というクラスがあります。

@property(strong) AbstractPage *page;

ここで、 called のサブクラスとAbstractBookcalledWhiteBookのサブクラスがあるAbstractPageとしWhitePageます。クラスにオブジェクトWhiteBookを継承させたいのですが、このクラスではではなく特定のクラスにしたいのです。pageWhitePageAbstractPage

では、WhiteBookプロパティをWhitePage次のように再宣言しました。

@property(strong) WhitePage *page;

ただし、警告が表示WhitePage is incompatible with AbstractPage inherited from AbstractBook.されます。目的を実装する正しい方法は何ですか?

4

4 に答える 4

5

やりたいことは基本的に不可能です。これを忘れないでください:

@property(strong) AbstractPage *page;

getterと setter を宣言します。

一般的に言えば (Objective-C だけでなく、一般的なオブジェクト指向プログラミングの場合)、オーバーライド ゲッターがスーパー クラス実装の戻り値の型のサブクラスを返すことに問題はありません。これは API コントラクトを破らないためです。あなたの場合、のインスタンスWhitePageAbstractPageです。

ただし、セッターは違います。AbstractBookサブクラスは anが使用されている場所ならどこでも使用できる必要があるため、パラメーターの型を制限することはできAbstractBookません AbstractPage APIは言います。

私がすることは、次のAbstractBookようなメソッドを呼び出すことだと思います

-(bool) isLegalPage: (AbstractPage) aPage;

基本クラスでは常に true を返しますが、 のホワイト ページに対してのみ true を返しますWhiteBook。次に、次のようにセッターを手動で実装します。

-(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
    }
}

ページが正当でない場合にセッターが例外をスローすること、およびisLegalPage:メソッドを使用してこれをテストする必要があることを文書化します。

読み取り専用プロパティを持ち、基本クラスとサブクラスで異なるセッターを使用するか、基本クラスにセッターをまったく持たない代替 ID。

于 2012-07-23T16:11:39.463 に答える
3

Objective C にはプロパティ タイプの共分散がないため、 のサブクラスを返すプロパティが必要な場合は、サブクラスでAbstractPage別のプロパティ、たとえば を定義する必要がありwhitePageますWhiteBookpageプロパティからも同じ値を返すことができ、それは機能します。さらに、ユーザーが でメソッドを呼び出す場合、メソッドをAbstractPage*にキャストする必要さえありませんWhitePage*

于 2012-07-23T15:20:36.833 に答える
2

実装ではなく、インターフェイスにプログラムすることを忘れないでください。

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

オプション1

Whitebook が本当に AbstractBook の子孫である場合、WhiteBook に「ページ」と呼ばれる新しいプロパティを持たせる必要はありません。

WhitePage が AbstractPage を継承している限り、ページ オブジェクトを WhitePage としてキャストできるはずです。次に、AbstractPage のすべての元の機能に加えて、WhitePage の機能を取得します。

そのため、ホワイトブックでページを再宣言する必要はありません。Whitebook.h ファイルに移動して、この行を削除すると

@property(strong) WhitePage *page;

次に、Whitebook.m ファイルに移動し、self.page と入力します。コンパイルの警告は表示されません。次に、ページを WhitePage としてキャストできます。これで準備完了です。

警告: これは、ページを使用するたびに WhitePage としてページをキャストする必要があることを意味しますが、これは理想的ではありません。

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

オプション: 2

コードをそのままにしておくこともできますが、Wh​​iteBook で「ページ」プロップを再度合成するようにしてください。

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

オプション: 3

コードをそのままにしておくこともできますが、Wh​​iteBook の「ページ」プロップには必ず @dynamic を使用してください。次にゲッターを自分で実装し、AbstractPage の代わりに WhitePage を返します。

于 2012-07-23T15:22:43.313 に答える
0

スーパークラスのプロパティをより具体的な型でオーバーライドする方法は?

通常、クラスとクラスで使用@synthesizeする場合、正常に動作するはずです (もちろん、合成メソッドを使用して非toを割り当てない限り)。AbstractBook@dynamicWhiteBookAbstractPageWhitePagepage

于 2012-07-23T15:05:23.857 に答える