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

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

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

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

オブジェクト指向

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

Q&A

解決済

1回答

381閲覧

サブクラスで抽象メソッドを定義する場合にスーパークラスでそれを宣言する必要性について

KIYZ

総合スコア17

PHP

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

オブジェクト指向

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

0グッド

0クリップ

投稿2018/06/15 13:05

編集2018/06/15 13:51

該当のソースコード

php

1<?php 2 3abstract class Shape { 4 protected $color; 5 6 // サブクラスで共通にするプロパティー 7 public function __construct ($color = 'red') 8 { 9 $this->color = $color; 10 } 11 12 // サブクラスで共有できるメソッド 13 public function getColor () 14 { 15 return $this->color; 16 } 17 18 abstract protected function getArea(); // 何故宣言する必要がある? 19} 20 21class Square extends Shape { 22 protected $length = 4; 23 24 // 各形によって計算方が違うため、サブクラスに定義している 25 public function getArea() 26 { 27 return pow($this->length, 2); 28 } 29} 30 31class Triangle extends Shape { 32 protected $base = 4; 33 protected $height = 5; 34 35 // 各形によって計算方が違うため、サブクラスに定義している 36 public function getArea() 37 { 38 return .5 * $this->base * $this->height; 39 } 40} 41 42class Circle extends Shape { 43 protected $radius = 5; 44 45 // 各形によって計算方が違うため、サブクラスに定義している 46 public function getArea() 47 { 48 return M_PI * pow($this->radius, 2); 49 } 50} 51 52// インスタンス化するクラス名の部分を変えるだけで該当する形の面積が返ってくる 53echo (new Square)->getArea();

疑問

サブクラスで抽象メソッドを定義する場合、スーパークラスでそのことを宣言するのが一般的のようですが、
上記のようなコードの場合、サブクラスで定義する抽象メソッド(getArea())をスーパークラスで宣言(abstract protected function getArea();)しなかったとしても、最終行のechoの実行で問題は生じないかと思います。
ではなぜ宣言する必要があるのでしょうか。
必要性や目的をご教授下さい。よろしくお願い致します。

補足情報

PHP 7.0.30

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

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

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

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

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

guest

回答1

0

ベストアンサー

実装を強制できるからです

class Square extends Shape {}としたときに、SquareがabstractなgetAreaを実装していなかったら、エラーになります。
一方、ShapeでabstractなgetAreaをもっていなかったら、extends ShapeなCircleがgetAreaを持たなくても(実装を忘れても)、CircleのインスタンスのgetAreaが呼び出されるまで、エラーに気付かない、ということが起こります。

従って提示なさっておられるような、extendsをしていないコードでは意味はないでしょう。

投稿2018/06/15 13:44

papinianus

総合スコア12705

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

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

KIYZ

2018/06/18 12:45 編集

ご回答誠にありがとうございます。 本来、質問のコードのサブクラスは クラス名 extends Shape {} と書くつもりでしたが、書き忘れてしまった状態で質問してしまいました(修正済み)。意図が分かりにくい質問になってしまい申し訳ありません。 つまりスーパークラスで抽象メソッドを宣言する行為はプログラムを実行する上では必須ではないが、誤ってプログラム内で矛盾を生じさせてしまわないようにするための、(バグ対策のような?) "習慣" のようなものということでしょうか? お返事頂けると大変助かります。よろしくお願い致します。
papinianus

2018/06/18 13:07

> つまりスーパークラスで抽象メソッドを宣言する行為はプログラムを実行する上では必須ではないが phpにおいては「動く」という意味ではたしかに"必須"ではないですね。 > 誤ってプログラム内で矛盾を生じさせてしまわないようにするため 矛盾というかミスというかバグというか。提示された例ではクラス定義がほとんどで、実行しているのは`echo (new Square)->getArea();`だけですよね?このとき抽象メソッドがなければ、CircleやTriangleでgetArea()を書き忘れていても、気付かないわけです。後日(new Triangle())->getArea()としたときに「あれ、昨日まで動いていたのに動かなくなった」と思うわけですが、実際には最初に作ったときのバグがその時明らかになったにすぎないのです。 これはバグが"実行時"=ランタイムにエラーとしてあらわれていることになり、一方抽象メソッドを書き(呼び出していなくても)エラー検知されるのはいわば"コンパイル時"にエラーが検知できていることになります(phpはコンパイルとは言わないので比喩です)。あるいはエラーを静的に分析できているとも言えます(IDEによっては実行前に教えてくれるものもあるかもしれない)。 こういうのはコード量が多くなればなるほど、見つけにくいものになります。$shapes[$i]->getArea()という行でgetArea()はないというエラーがでてしまうと、$shapesの配列がおかしいのか、$iのインデクスがおかしいのか、など疑う箇所が多くなってきます。特定の図形で実装を忘れていることを見付けるのは(可能でしょうが)面倒になると思います。 オブジェクト指向に"習慣"という言葉はあわないような気がします。設計思想、設計技法だと思います。
KIYZ

2018/06/19 12:18

お陰様で抱いていた疑問が全て解消されました。 大変詳しくご説明頂いたことに心より感謝申し上げます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問