質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

インターフェース

インターフェイスという用語はハードウェア・ソフトウェアの両方に使うことができます。 一般的に、インターフェイスは内部処理の詳細を見せないように設定されます。オブジェクト指向プログラミングにおいて、インターフェイスはabstractクラスとして定義されます。

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

継承

継承(インヘリタンス)はオブジェクト指向プログラミングに存在するシステムです。継承はオブジェクトが各自定義する必要をなくし、継承元のオブジェクトで定義されている内容を引き継ぎます。

受付中

クラスの設計における継承やインターフェースの使い方(例あり)

nuu
nuu

総合スコア0

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

インターフェース

インターフェイスという用語はハードウェア・ソフトウェアの両方に使うことができます。 一般的に、インターフェイスは内部処理の詳細を見せないように設定されます。オブジェクト指向プログラミングにおいて、インターフェイスはabstractクラスとして定義されます。

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

継承

継承(インヘリタンス)はオブジェクト指向プログラミングに存在するシステムです。継承はオブジェクトが各自定義する必要をなくし、継承元のオブジェクトで定義されている内容を引き継ぎます。

1回答

0評価

0クリップ

314閲覧

投稿2022/01/27 03:30

編集2022/01/27 17:29

うまく継承やインターフェースを使いたいのですが、継承やインターフェースをどのように使うべきか、また使うべきか使わないべきなのかの判断に苦しんでいます

例えば以下のような例を考えます
あるサブスクサービスでは、ユーザーが以下のようなプランを結び、契約したプランに応じたサービスを受けられるとします。プランは複数種類契約可能です。

プランA ラーメンプラン
毎週月曜日の昼にラーメンを宅配します
ラーメンはお店の器に入れられて宅配されるので、食べ終わったらその器を返す必要があります
器をとりにきて欲しい場合はオプションで申し込むことができますが、別途お金がかかります

プランB 牛丼プラン
毎週月曜日の昼に牛丼を宅配します
紙の入れ物に入れて宅配されるので器を返す必要はありません

プランC 健康チェックプラン
毎月の第1月曜日に、健康のプロがユーザーと1時間面談する時間を設けてくれます
そこでユーザーは健康に関するいろいろなことを相談できます。
開始時間は設定することができます。

見ての通り、同じプランという括りであってもAとBは器回収の有無という違いがありますし、Cに関しては全くの別物という感じがします。

しかしこれを全部同じようにプランという括りで見たいこともあるはずです。例えば、あるユーザーがどんなプランを契約しているのか、というのを考えるときにUserオブジェクトがPlanオブジェクトの集まりを持っていて、それぞれ同じように参照できると便利そうです。

このアイディアを以下のような感じでコードで書きました

PHP

abstract class Plan{ public string $planName; public function planName(){ return $this->planName; } abstract public function totalPrice(); } class ramenPlan extends Plan{ public string $planName = 'ラーメンプラン'; public int $number; public bool $collectFlg;//器回収フラグ public function __construct($number,$cllectFlg=false){ //プロパティに代入 } public funtion totalPrice(){ //計算 } } class beafBowlPlan extends Plan{ public string $planName = '牛丼プラン'; public int $number; public function __construct($number){ //プロパティに代入 } public funtion totalPrice(){ //計算 } } class healthConsultationPlan extends Plan{ public string $planName = '健康チェックプラン'; public string $startTime;// 開始時間 public function __construct($startTime){ //プロパティに代入 } public funtion totalPrice(){ //計算 } public function nextSchedule(){ // 次回は何日の何時から何時までかを返す } } class user { public string $name; public array $plans; public function __construct($name,$plans){ //プロパティに代入 } public function nextHealthConsultationSchedule(){ // plansの中を調べてhealthConsultationPlanがあればnextScheduleメソッドを使用 // なければnullを返す } }

自分がこれを使いにくいと思っている点があります。
1つめは、どのPlan子クラスも持っているプロパティが異なり、またそれに伴ってコンストラクタが異なるという点です。
自分がネットで見る例だとほとんどが親クラスと子クラスでは持っているプロパティは同じだし、せいぜいが振る舞いの結果が異なるくらいです。
しかし自分の例では違います。これでは同じようにPlanクラスとして各Planを作成しようと思っていても、結局これらのPlanクラスを使用する側(例えばDatabaseからデータを抽出して各Planを作成するようなクラス)ではramen,beefBowl,healthConsultationの何を作るのかを何らかの方法を用いて判断しないといけません。なぜならどのPlanクラスを作成するかによって、コンストラクタに渡すものが異なるからです。

2つめに、プランCが、他のクラスが持っていないnextScheduleメソッドを持っている問題です。
これはUserのnextHealthConsultationScheduleメソッドで使用されます。ただプランCを契約していないUserにとって、nextHealthConsultationScheduleメソッドは全くいらないメソッドです。プランCを契約していないUserがこのメソッドを使用できるようなクラスの作り方でいいのでしょうか。何だか気持ち悪く感じます。

このような問題を考えるとき、どのようにクラスを設計すれば上記のような問題点を解決した上で、なおかつ冒頭で述べたように同じようにプランという括りで見ることができるでしょうか。
よければご意見お聞かせいただければと思います。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

m.ts10806

2022/01/27 03:39

言語によって方言や癖、仕様のちがいがあるのでPHPを例題にするのでしたら質問タグにも「PHP」があったほうが良いと思います。
Zuishin

2022/01/27 03:39

プラン一つ一つにクラスを作るべきではなく、委譲を使うべきケースだと思います。
nuu

2022/01/27 05:33 編集

m.ts10806様 ご指摘ありがとうございます!PHPタグを追加しました。 Zuishin様 回答ありがとうございます!例えばどのような形で作るとよいでしょうか...
Zuishin

2022/01/27 04:54

器を返す、商品を宅配する、面談すると言った各サービス・条件の個々をクラスにし、プランは名称とそれらの条件の集合を保持し、金額を算定するクラスにします。
nuu

2022/01/27 04:59

Zuishin様 ありがとうございます! >>器を返す、商品を宅配する、面談すると言った各サービス・条件の個々をクラスにし これらをクラスにすることは思いつきませんでした、考えてみようと思います!

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

インターフェース

インターフェイスという用語はハードウェア・ソフトウェアの両方に使うことができます。 一般的に、インターフェイスは内部処理の詳細を見せないように設定されます。オブジェクト指向プログラミングにおいて、インターフェイスはabstractクラスとして定義されます。

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

継承

継承(インヘリタンス)はオブジェクト指向プログラミングに存在するシステムです。継承はオブジェクトが各自定義する必要をなくし、継承元のオブジェクトで定義されている内容を引き継ぎます。