実現したいこと
php のクラス継承で、子クラスは親クラスの定数を一部しか使えないよう制限したいです。
現状と問題
以下のように PrivateItemKind と SharedItemkind などがあり、一方にしかない値 (TAG_KIND_ID) があります。
しかし以下のようにすると、BOOK_KIND_ID の値が 2 だったり 1 だったり、ズレることになりますよね。(TAG_KIND_ID は PrivateItemKind でしか使わないため、ID の連番を詰めると BOOK_KIND_ID の値がズレる。)
このズレれをうまく解消する方法を知りたいです。
php
1class PrivateItemKind 2{ 3 const TAG_KIND_ID = 1; 4 const BOOK_KIND_ID = 2; // BOOK_KIND_ID の値が 2 5 const USER_KIND_ID = 3; 6} 7 8class SharedItemkind 9{ 10 const BOOK_KIND_ID = 1; // BOOK_KIND_ID の値が 1 11 const USER_KIND_ID = 2; 12}
解決策
解決策A
まず素朴に考える解決策は、以下のように定数名に接頭辞をつけ区別することです。これなら「同じ定数名なのに値が違う」という上記のズレは生じません。
php
1class PrivateItemKind 2{ 3 const PRIVATE_TAG_KIND_ID = 1; 4 const PRIVATE_BOOK_KIND_ID = 2; 5 const PRIVATE_USER_KIND_ID = 3; 6} 7 8class SharedItemkind 9{ 10 const SHARED_BOOK_KIND_ID = 1; 11 const SHARED_USER_KIND_ID = 2; 12}
しかし「本というアイテム種別」という同じ意味なのに、プライベートなのかシェアされたのかという違いによって異なる定数名にすることに違和感を覚えます。(そうすることが一般的なら、私の違和感は初心者特有のものでしょうから受け入れたいと思いますが、いかがでしょうか?)
解決策B
続いての解決策の方が筋が良さそうかと思い本質問のタイトルとさせていただきました。
つまり、親クラス ItemKindMaster で定数を宣言し、子クラスは必要な値のみ宣言するという方法です。
php
1abstract class ItemKindMaster 2{ 3 const TAG_KIND_ID = 1; 4 const BOOK_KIND_ID = 2; 5 const USER_KIND_ID = 3; 6} 7 8class PrivateItemKind extends ItemKindMaster 9{ 10 // 必要な値のみ宣言する 11 const TAG_KIND_ID = parent::TAG_KIND_ID; 12 const BOOK_KIND_ID = parent::BOOK_KIND_ID; 13 const USER_KIND_ID = parent::USER_KIND_ID; 14} 15 16class SharedItemkind extends ItemKindMaster 17{ 18 // 必要な値のみ宣言する 19 const BOOK_KIND_ID = parent::BOOK_KIND_ID; 20 const USER_KIND_ID = parent::USER_KIND_ID; 21}
こちらの方法でも「同じ定数名なのに値が違う」という上記のズレは生じなくなるのでよさそうかと思ったのですが、
しかし (ItemKindMaster を継承しているので当たり前ですが)、以下のように呼べてしまいました。
SharedItemkind には TAG_KIND_ID を持たせたくないのに、これでは困ります。
php
1echo SharedItemkind::TAG_KIND_ID;
そこで改めて質問になります。子クラスは親クラスの定数を一部しか使えないよう制限したい (SharedItemkind は TAG_KIND_ID を持たせたくない) のですが、どうすべきでしょうか?
バージョン
php 8.2 です。
補足
もしかして以下のように、null を再代入し、使えないことを明示する。という解決策がベストでしょうか?
php
1abstract class ItemKindMaster 2{ 3 const TAG_KIND_ID = 1; 4 const BOOK_KIND_ID = 2; 5 const USER_KIND_ID = 3; 6} 7 8class PrivateItemKind extends ItemKindMaster 9{ 10 const TAG_KIND_ID = parent::TAG_KIND_ID; 11 const BOOK_KIND_ID = parent::BOOK_KIND_ID; 12 const USER_KIND_ID = parent::USER_KIND_ID; 13} 14 15class SharedItemkind extends ItemKindMaster 16{ 17 const TAG_KIND_ID = null; // 使えないことを明示する 18 const BOOK_KIND_ID = parent::BOOK_KIND_ID; 19 const USER_KIND_ID = parent::USER_KIND_ID; 20}
回答2件
あなたの回答
tips
プレビュー