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

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

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

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

継承

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

Q&A

解決済

2回答

1054閲覧

php 継承が必要なのか

yuuyu

総合スコア1139

PHP

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

継承

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

0グッド

0クリップ

投稿2020/05/02 13:18

phpでもclassやclassの継承を使えるということで、これらを使ってプログラムを作ろうと思ったのですが、少し疑問点があったので質問させていただきます。

目標

異なるクラスをまとめて操作する。

想像しているソースコード

php

1class A{ 2 function Fa(){ 3 } 4} 5 6class B extends A{ 7 function Fa(){ 8 echo "class B, function Fa called."; 9 } 10} 11 12class C extends A{ 13 function Fa(){ 14 echo "class C, function Fa called."; 15 } 16}

これのBやCをまとめて配列に入れ、forループにてFaを呼び出す。

この先をC言語っぽく書くと、

C言語っぽいphp

1A[] $val; //変数宣言 2$val[0] = new B(); 3$val[1] = new C(); 4for($i = 0; $i < count($val); $i++){ 5 $val[0]->Fa(); 6}

(もちろん、Aという変数宣言ができないことは承知です。)
という形でループして呼び出すと思います。

実際のソースコード

それで、色々と試行錯誤していたところ、

php

1class B{ 2 function Fa(){ 3 echo "class B, function Fa called."; 4 } 5} 6 7class C{ 8 function Fa(){ 9 echo "class C, function Fa called."; 10 } 11} 12$val = []; 13$val[0] = new B(); 14$val[1] = new C(); 15for($i = 0; $i < count($val); $i++){ 16 $val[0]->Fa(); 17}

別に継承しなくても上記で動くと思います。

###質問
1. 似たようなクラスで共通の関数名があるだけの場合、継承は必要ないのでしょうか?

2. 継承なしの場合、Faが定義されていないとエラーが起きると思います。
また継承されていても、スペルミス等でFaが異なる名前で呼ばれていた場合は意図しない関数が呼ばれることになります。
これを阻止するために、関数宣言を必須化することは可能でしょうか?(継承ありstrict有りでも別にエラーは出なさそうです)

###環境
php 7.4.4

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

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

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

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

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

guest

回答2

0

ベストアンサー

1. 似たようなクラスで共通の関数名があるだけの場合、継承は必要ないのでしょうか?

要件次第です。
親クラスの関数の処理で不足している場合は同じ関数名で定義する「オーバーライド」という手法がとられることが良くあります。
「この子クラスだけ処理内容をちょっと改変したい」とか「この子クラスだけ別の引数もとりたい」ようなときに利用されますが、利用用途も様々なので「要件次第」となります。

これを阻止するために、関数宣言を必須化することは可能でしょうか?(継承ありstrict有りでも別にエラーは出なさそうです)

「親クラスをどうするか」ですけど、「抽象化」で可能です。

抽象クラスから継承する際、親クラスの宣言で abstract としてマークされた 全てのメソッドは、子クラスで定義されなければなりません。

php

1<?php 2abstract class A { 3 abstract protected function test(); 4} 5class B extends A{ 6 function test(){ 7 8 } 9}

ただし、PHPマニュアルにあるように、

abstractとして定義されたクラスのインスタンスを生成することはできません。

abstractとして定義されたメソッドは、そのメソッドの外観を宣言するのみで、 実装を定義することはできません。

これも「どのようなクラス設計をするか」によってくるので「こういうときは必ず抽象化」のようなルールも「作る側」が考えることになり「要件次第」となります。

なので・・・

これらを使ってプログラムを作ろうと思ったのですが、

この考え方は逆です。
「要件を満たすために必要だから継承を導入する」ので、
まずは設計が先だと思います。

学習のためのプログラムだとしても、やはり「継承が必要そうな設計」を考えてからの方が実用的です。

投稿2020/05/02 13:30

編集2020/05/02 13:42
m.ts10806

総合スコア80875

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

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

yuuyu

2020/05/02 13:43

解答ありがとうございます。 抽象化することで必須化できるのですね。 abstractをもう少し調べてみたところ、interfaceというものもあるらしく、 今回は関数名以外の共通項もなく、ただ単に雛形のように使用したかったので、class宣言も要らないinterfaceを使用しようかと思います。
m.ts10806

2020/05/02 13:46

interfaceはそもそも厳密にはクラスではないですね。 これはこれできちんと用途を理解して使わないとスパゲッティになるので注意です。 やはりきちんと設計してからでしょうね。 名前空間なども適切に覚えた方が良さそうです。
yuuyu

2020/05/02 14:19

interfaceはクラスではないみたいですね。でも今回はクラスに依存する必要は特になかったので大丈夫かな、と思います。 名前空間に関してはほとんど理解していないので、また調べてみようと思います。
guest

0

現代PHPでは継承はほとんど使わないと思っていい。
特に「共通化のための継承」は厳禁。
自分で作ったclassを親として継承使うことはほぼない。
ただしフレームワークのclassでは使うこともある。

共通化はどうするか→trait
PHP5.4でtraitが追加されるまでは継承しか方法がなかったから継承だっただけなので今はtraitで十分。

「関数宣言を必須化」にはinterface
PHPのinterfaceは意外と優秀なので今のPHPを使いこなすにはinterfaceが最重要。

投稿2020/05/02 13:57

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

yuuyu

2020/05/02 14:18

回答ありがとうございます。 今回は共通化を目的ではなく、関数名を複数のクラスで同一にしたかったので、traitまでは行かないかな、と思いました。ただこの先継承を使う場合は、traitの方がいいかもしれないですね。参考になります。 interfaceは今回の目的に合っていたので、こちらを使用することにします。 ちなみに、「意外と優秀」とのことですが、具体的に"意外"となるような機能は何でしょうか?調べても関数必須化、定数宣言以外での機能は見当たらなかったので、もしお時間があれば教えていただけるとありがたく思います。
m.ts10806

2020/05/02 14:27

yuuyuさん この方はプロフィールにあるように、回答後の対応は一切しない人なので、再質問してもほとんど返ってこないと思います。(言いたいことだけ言って去っていくので冷たい印象を持つ人もいるかもしれませんが、言ってることは確かだと個人的には思います) 「意外と」は「PHPにしては」という意味が含まれると推察されます(どうしても他の言語からすると見劣りする場面が多いから) interfaceもtraitも正しく使われて初めて真価を発揮するものなので、要点をきちんとおさえ、色々なテストプログラムを書いて理解を深めていくと良いと思います。
yuuyu

2020/05/02 15:41

m.ts10806さん そうなんですね、プロフィールみる習慣がなく、つい質問を返してしまいました、、、 「意外と」はそちらにかかっている感じだったのですね、なるほどです。 アドバイスありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問