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

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

新規登録して質問してみよう
ただいま回答率
85.50%
オブジェクト指向

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

継承

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

Q&A

4回答

1920閲覧

単体で用を成さない継承元クラスの設計は正しいですか?

退会済みユーザー

退会済みユーザー

総合スコア0

オブジェクト指向

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

継承

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

0グッド

2クリップ

投稿2015/12/31 17:44

※phpを例に挙げますが、言語に依存しない「思想」に関わる質問のため、多くの方に意見を頂けますと幸いです。

DBへクエリを発行する以下のコードを設計しました。

php

1class Database 2{ 3 public function execQuery($query) 4 { 5 mysql_query($query); 6 } 7} 8 9$db = new Database(); 10$db->execQuery('delete from DaijiNaTable'); // 危険なコードが実行可能!

コメントにあるように、この設計だとグローバルから好き勝手なクエリを実行できてしまうため、以下のように修正しました。

php

1class Database extends DatabaseQuery 2{ 3 public function execQuery() 4 { 5 mysql_query($this->getQuery()); 6 } 7} 8class DatabaseQuery 9{ 10 private $query; 11 public function select($table) 12 { 13 $this->query = "select * from `${table}`"; 14 } 15 public function getQuery() 16 { 17 return $this->query; 18 } 19} 20 21$db = new Database(); 22$db->select('DaijiNaTable'); 23$db->execQuery(); 24 25$dbq = new DatabaseQuery(); // 無意味だが実行可能。

実行可能なクエリに制限を与えられるため安全ですが、2つ気になることがあります。

1. DatabaseQueryをグローバルからインスタンス化することが出来ますが、無意味です。インスタンス化が出来ないよう、何らかの修正を加えるべきでしょうか?

2. DatabaseQueryは継承される前提で構想されており、単体では用を成しません。このような設計は正しいのでしょうか?

実務では簡単なプログラムしか組んでおらず、設計思想について理解したいため、ご指導頂けますと幸いです。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

例が適当でないと思うので、例のことは忘れることにして、一般論としては、

  1. オブジェクトを作っても無意味なクラスでは、インスタンス化が出来ないよう、何らかの修正を加えるべきでしょうか?

⇒はい。そう思います。言語によっては難しいこともあるかもしれませんし、簡単かもしれません。
難しい場合は、無理しなくてもいいかと思います。

  1. 継承される前提で構想されており、単体では用を成さないクラスを作ってもいいのでしょうか?

⇒はい。そう思います。
よく入門書で見かけるAnimalクラスの場合、実際に作るのはDogクラスやCatクラスのオブジェクトで、Animalクラスのオブジェクトを作ることは無いでしょう。

投稿2015/12/31 18:16

otn

総合スコア84423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

単にあるメソッドの実装だけを継承させたい(多態性が目的じゃ無い)のであれば、現在の流行りはMixinだと思います。PHPはトレイトが使えますので、トレイトにするのがいいじゃないでしょうか。

さて、これを一般的なオブジェクト指向にまで話を広げると複雑です。なぜなら、言語によってできる、できないがあるからです。Mixinはメジャーな言語では動的言語や比較的新しい言語でしか採用されていません。では、代わりに抽象クラスという意見もありますが、今度は抽象クラスが無い言語もあります。インターフェースや多重継承の有無、プロトタイプベースオブジェクト指向とかまで考えると、言語(例え同じ言語でもそれぞれのバージョン)によって正解が異なるような気がします。また、質問のコードの例を見ると、継承よりも委譲を使った方がいいのでは?とも思っています。

投稿2015/12/31 22:08

編集2015/12/31 22:10
raccy

総合スコア21733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

  1. DatabaseQueryをグローバルからインスタンス化することが出来ますが、無意味です。インスタンス化が出来ないよう、何らかの修正を加えるべきでしょうか?

既にいろいろな方から同様の意見が出ていますが、抽象クラスという概念があります。PHPでもマニュアルのクラスの抽象化という項目がありますので、参照していただくと理解が早いと思います。

言語ごとに異なる仕様になりますが、抽象クラス自体はインスタンスを作成できなくなるようにするための手法が用意されていることが多いと思います。設計の段階で抽象クラスとして定義するのであれば、インスタンス化できないように言語の仕様に沿ってコーディングするべきだと思います。言語的に抽象化ができない場合はその旨コメント化しておくなど、設計者の意図が伝わるようにしておく方がいいでしょう。

  1. DatabaseQueryは継承される前提で構想されており、単体では用を成しません。このような設計は正しいのでしょうか?

前述のように、抽象クラスというものがまさにそのもののクラスで、継承されることが前提の基底クラスです。今回の例に挙がっているデータベースアクセス以外でも割と使用されるテクニックです。

投稿2016/01/01 06:17

KoichiSugiyama

総合スコア3041

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

それは、ただの抽象クラスだと思います。

投稿2015/12/31 18:04

Stripe

総合スコア2183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問