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

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

ただいまの
回答率

90.01%

php 継承関係について

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 574

お世話になっております。
PHPの継承の関係について質問させてください。

ある理由がありまして、継承先から継承元にメソッドを渡したいのですがどうしたら良いでしょうか。
元のファイル(hoge.php)に書き込みを入れたくないのが理由です。

hoge.php

HogeClass
{
  public function hoge()
  {
    //処理
  } 
}

fuga.php

require_once hope.php;

FugaClass extends HogeClass
{
  public function fuga(){
    //ここの処理をHogeに持っていきたい。
  } 
}

継承についても理解が足りなく。初心的な質問で申し訳無いのですが、ご教授いただければ幸いです。

よろしくお願いいたします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

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

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

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

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

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

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

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

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+4

多少Hogeに手を加えることになりますが、1行で済みます。
traitを使いましょう。

http://php.net/manual/ja/language.oop5.traits.php

trait Fuga {
    function proc() {
        echo $this->text; // このthisはtraitをuseしたクラスのインスタンス(つまりHogeのインスタンス)となるので、textが参照可能
    }
}
class Hoge {
    use Fuga; // trait Fugaの記述がこのクラスに埋め込まれる
    protected $text = 'hoge';
}


$hoge = new Hoge();
$hoge->proc(); // trait Fugaのprocが呼ばれ、Hogeのtextが参照されhogeと出力される。

 追記

Hogeが別のクラスを継承していてもtraitは使えますが、メソッドやプロパティの名前の衝突等に気を使う必要があります(もちろん継承していようがいまいが衝突には注意する必要があります)。

trait Fuga {
    function procA() {
        echo $this->text;
    }
}
class Piyo {
    function procA() {
        echo 'ここの処理はtraitに同名のメソッドがあるのでオーバーライドされる';
    }
    function procB() {
        echo 'piyo piyo';
    }
}
class Hoge extends Piyo {
    use Fuga; // procAがオーバーライドされる
    protected $text = 'hoge';
}


$hoge = new Hoge();
$hoge->procA(); // trait Fugaのprocが呼ばれ、Hogeのtextが参照されhogeと出力される。
$hoge->procB(); // procBはtraitの影響を受けず、piyo piyoと出力される。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/15 11:40

    ご回答ありがとうございます。

    traitというものを初めて聞きました。これは便利そうですね。
    一つだけ質問ですが、下記サイト
    http://qiita.com/sasakure-kei@github/items/212637b2f32197441a3a
    を見たのですが、
    Hogeがもしextendsで他のclassを継承していても、
    その他のclass内のメソッドをtrait内で呼び出せばHoge内で使用出来るということでよろしいでしょうか。

    キャンセル

  • 2017/08/15 11:52

    回答に追記しておきました。
    Hogeがどんな継承をしていてもtraitは使用可能ですが、うっかり同名のメソッドでオーバーライド等が起きないよう注意する必要があります。そのへんの使い方も公式リファレンスに載っているので確認してください。

    キャンセル

  • 2017/08/15 11:54

    ちょっと質問に対する回答がずれていましたね。
    Hogeが継承しているPiyoが持っているprocPiyoがあったとして、Fuga内で$this->procPiyo()と書くことができるかという質問ですよね。できます。

    キャンセル

  • 2017/08/15 11:57

    ありがとうございます!
    その方法で実践して見ます!

    キャンセル

+3

ごめんなさい、私の理解が間違っているかもしれませんが
ロジックが破綻しているように見受けられます。

hogeからfugaを「勝手に」拡張したものが元のhogeに影響を与えては問題では?
結局fugaの拡張をしたら、hoge側にもそれなりの編集手続きがないと
参照できないでしょう

 追記

class FugaClass{
  public static function fuga(){
    print "fuga";
  } 
}
class HogeClass extends FugaClass{
  public static function hoge()
    {
      print "hoge";
    }
}
HogeClass::fuga();

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/15 11:07

    もしくは普通にfugaをインスタンスにして参照すればよいでしょう

    キャンセル

  • 2017/08/15 11:20

    >そうなるとむしろHogeをFugaの拡張にするとかでは?
    すみません、少し説明が足りなかったのですが、前提条件としてHogeは他のclassを継承しています。
    2重継承はできるのでしょうか。

    >もしくは普通にfugaをインスタンスにして参照すればよいでしょう
    初心者的質問で申し訳ないのですが、これは二重にHogeが呼び出されて、動作が重くなったりはしないのでしょうか。

    キャンセル

  • 2017/08/15 11:58

    コメントありがとうございました。

    キャンセル

+1

HogeClass
{
  public function hoge()
  {
    //処理
  } 

  public function fuga(){
    //ここの処理をHogeに持っていきたい。
  } 
}


FugaClass extends HogeClass
{

}

fugaをHogeに移動させてはどうでしょうか?
ただしこの場合、Hogeを継承している他のClassでもfugaメソッドが利用できてしまいます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/15 11:23

    >それともfugaメソッドはどうしてもFugaクラスにないと困るということでしょうか?
    Hogeクラスには直接処理は記入をしたくなく、呼び出し程度の記入に収めたいのですが、
    そういうロジックの書き方は少しおかしいでしょうか。

    キャンセル

  • 2017/08/15 11:31

    なるほどです。いまさら質問なのですが「//ここの処理をHogeに持っていきたい。」というのは
    Hogeクラスからfugaメソッド内で行っている処理を実行したいということですよね?

    であれば、共通クラスを作って、その処理を新たに作成し
    HogeクラスからもFugaクラスからも共通クラスのメソッドを呼んではどうでしょうか?

    キャンセル

  • 2017/08/15 11:58

    コメントありがとうございました。

    キャンセル

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

  • ただいまの回答率 90.01%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる