このブログは未経験からのエンジニア転職やプログラミングの勉強方法などを発信する、現役エンジニアによるエンジニアのためのトータル技術ブログです。ブログとご一緒にSNSのフォローもよろしくお願いします。

Twitterをフォローする

【PHP】アクセス修飾子の違い【Public,Protected,Private】

PHP
スポンサーリンク

こんにちは、あっきー(IwswAkht)です。

今回はPHP、Laravelをベースとしたアクセス修飾子の違いについて書いていきます。
本記事を読むことで以下の項目を学ぶことができます。

  • オブジェクト指向におけるアクセス修飾子の適切な設定がわかる(多言語応用可能)
  • より可読性の高いコードを書くことができる
  • より安全性の高いプログラムとすることができる

アクセス修飾子って何?という方におすすめでどのように使って、どのようなメリットがあるのかを解説していこうかと思います。

より良いプログラムを書くための手助けになれば幸いです。

スポンサーリンク

さいしょに

アクセス修飾子にはprivate、protected、publicの3つが使用できます。

それぞれ以下の特徴があります。

  • public→どこからでもアクセス可能。アクセス修飾子の省略が可能
  • protected→クラス自身と継承クラスからのアクセスが可能
  • private→クラス自身からアクセス可能。継承クラスからでもアクセス不可

クラスや継承という言葉でイメージしづらい場合は以下のようなイメージで考えてみてください。

  • public→誰でもいける場所
  • protected→家族と親戚しか行けない場所
  • private→家族しか行けない場所

次に設定する優先順位は以下になります。

private > protected > public

はじめにアクセス修飾子は出来る限りprivateにできないか検討した上で、protected→publicと順番に設定するイメージです。

PHP、Laravelなどのプロジェクトにアサインする中でアクセス修飾子にとりあえずpublicを使用してるとか結構あるあるです。

アクセス修飾子を全てpublicにしてもプログラム上は確かに問題ないですが、後から大変になるケースがほとんどです。

そこでなぜアクセス修飾子になるべくpublicを設定しない方が良いのかをみていきます。

アクセス修飾子をpublicにしないメリット

結論から言いますとコードの可読性が高くなる。これに尽きます。

ミニマムなサービスのプラグラムならそれほどかもしれませんが、大規模なサービスで複数のクラスが使用される肥大化してきたプログラムの中でクラス内のメソッド全てのアクセス修飾子が全てpublicで設定されている。

そんなクラスのコードを修正してください。なんて言われたら僕だったらちょっと嫌だなって思います。

publicは言葉の通りどこからでもアクセス可能で一見便利ですが、逆を返せば「どこからでもアクセスできるの=どこでどう使われてるのかがわかりづらい

という側面があります。

そんな中で適切にprivateやprotectedなどのアクセス修飾子が設定してあったら、このメソッドはクラス内、または継承クラスまでで完結しているんだなとアクセス修飾子をみただけでパッとわかります。

これだけでも初めてコードを読む側からしたらだいぶありがたいものです。

修正するために見るべきコード、影響範囲を確認する箇所が一気に絞れるわけですから。

この小さな積み重ねが後々のコード負債を防げると思います。

たかが修飾子と思わず、適切な修飾子を設定できるようにしっかり理解していきたいものですね。

サンプルコード

サンプルコードを見ながら挙動を確認してみます。実行環境は以下になります。

  • PHP 7.4.7
  • Laravel 8.44.0

まずは必要なファイルを作成していきます。以下のコマンドを実行してください。

ターミナル

それぞれ以下の編集をします。

app/Classes/Family.php

app/Classes/Relatives.php

app/Http/Controllers/sampleController.php

private

先ほどのアクセス修飾子の説明をした時の例を踏襲して家族、親戚、他人というカテゴリーでサンプルを作ってみました。

LaravelではアクションのはじめはほとんどがControllerを経由しますので、別のクラスでアクセス修飾子にprivateを設定するとControllerは別クラスからのアクセスになりますので直接メソッドを実行できません。

なので、家族しか持たない家の鍵という例でsampleControllerからFamilyクラスのfamilyKey()というpublicのメソッドにアクセスします。

メソッドの中で鍵を使って家に帰るためのhome()が実行されます。
これで同じクラス内でのやりとりになりますのでアクセス修飾子がprivateでも実行が可能になります。

そのあとは直接アクセス修飾子がprivateなhome()メソッドに直接アクセスするとエラーが出る例がsampleControllerに記載されています。

protected

次にアクセス修飾子protectedに継承先からアクセスする例があります。

親戚であるRelativesクラスからcall()を実行してまずは遊びに行っていいか家族に確認をとります。
確認が取れたらgoToPlay()メソッドからparent::visitRelatives()で継承元のクラスのメソッドにアクセスします。

そのあとは継承クラスを経由しないで直接visitRelatives()にアクセスするとエラーになる例が記載されています。

ゲッターとセッター

先ほどはじめにアクセス修飾子は出来る限りprivateにできないか検討すると言いました。
また、サンプルコードの箇所でLaravelではアクションのはじめはほとんどがControllerを経由しますとも言いました。

そうすると別クラスのメソッドにアクセス修飾子privateを設定するのはあまり現実的ではないですね。

そんな時よく使われる手法がゲッターとセッターです。まとめてアクセサメソッドとも言われます。

まずは簡単なサンプルをみてみます。先ほど作ったsampleController.phpFamily.phpに以下の編集を加えます。

app/Classes/Family.php

app/Http/Controllers/sampleController.php

プロパティはprivateにして、プロパティを取得するメソッドと変更するメソッド(アクセサメソッドのゲッター、セッター)を作成し、そのメソッドでプロパティの処理を記述するやり方です。

サンプルのコードの例は家族の引っ越しを例にしています。
プロパティの初期値に現在の住所を設定。privateなので直接参照はできません。

住所を参照するためにgetAssress()を経由して住所を取得します。市役所から住民票をとるみたいなイメージですかね。

住所を変更したい場合は、setAssress()を経由して住所を変更します。不動産に行ったり転出の手続きをしないと引っ越してはできませんよね。そんなイメージです。

PHPに限らずこのプロパティをprivateにして、他のクラスから参照や変更を禁止する。参照、変更するためにはアクセサメソッドを経由して行う方法は他のプログラミング言語でも共通して使えます。

これがいわゆるカプセル化というものです。

staticについて

最後にstaticについてふれておきます。

ここまでのコードはpublic function メソッド名()と書いてましたがpublic static function メソッド名()みたいな書き方をみたことある人多いのではないかと思います。

これがstaticです。メソッドだけでなくプロパティにもstaticは使用することができます。

staticの最大の特徴はインスタンス化しないでもそのままメソッドを実行できることです。

インスタンス化とはsampleController.phpnew Family()と記述している箇所です。

staticを使うことのメリット・デメリット、その使いどころをリスト化すると以下になります。

  • インスタンス化しない分メモリ消費を抑える
  • 共通のメソッドを定義できる
  • 共通のプロパティを定義できる
  • 複数クラス間で共通の定義を共有できる
  • 1つのクラスでプロパティを変更したら他に使用してる箇所すべてに影響する
  • 利用用途が確定しているクラス
  • メソッド単体で完結していてインスタンスの状態により影響が出ない場合

こんな感じでしょうか。ちょっとした共通処理とか定数をおいときたいとかはstaticとするのが良いです。

ただ個人的にはその挙動を理解しきってない状態で使うと不具合が出やすくなります(加えてstaticでの不具合は根が深くなりやすい)のでわからないうちは避けるのが無難かと思います。

簡単なサンプルを載せるとこんな感じです。

app/Classes/Family.php

app/Http/Controllers/sampleController.php

それぞれ、苗字、結婚記念日、貯金残高という例でインスタンス化せずに参照しています。

貯金残高(deposits)はアクセス修飾子がprivateなのでconfirmDeposits()でアクセスできて、直接$depositsでアクセスするとエラーになることが確認できます。

さいごに

さいごまで読んでいただきありがとうございます。

PHPにおけるアクセス修飾子の使い方の違いについてまとめてみましたがいかがでしたでしょうか。

プログラミングをする上で基本的な部分ではありますが、最近はフレームワークからプログラミングを始めましたという方を見るとあまりこの辺を意識しないでコーディングしてる人も少なくない印象を受けました。

言語自体の理解を深めるのもプログラミングをする上では非常に大切な要素です。

この記事がどなたかに少しでも役に立ったのならば幸いです。

この記事を気に入っていただけましたらTwitterでもプログラミングに関してのツイートをリアルタイムでしていますので
ご一緒にフォローもお願いします。

IT転職ならレバテック!

僕は未経験からSESの企業にエンジニアとして転職し、その後はフリーラン、現在は受託開発企業に転職しました。

エンジニアとしていろいろな働き方を経験し、いろいろな転職サイトや転職エージェントの方にお話を伺いました。

その経験の中でだいじだと感じたことは、ITに特化した転職エージェントのサービスを利用することです。

幅広い業界に対応した転職エージェントはIT転職に特化したエージェントと比べると紹介先の数が少ないです。

そのため希望してない紹介先に転職し、思ってたのと違うとなることもあります。

そうならないためにエンジニアを目指すなら必ずIT特化の転職サービスを登録し、たくさんの選択肢の中から自分が行きたいと思う企業を探してください

僕はフリーランスでの案件探し、受託開発企業の転職の時もレバテックのかたに紹介していただきました。

とても満足できましたので皆さんもぜひ利用してみてください!

\無料のIT系転職サービス/

/優良案件がたくさん\

スポンサーリンク
あっきー

元キャバクラ店長から未経験でエンジニアに転職した異端児。

自分の経験を元に、エンジニア転職や未経験からでも挫折しないプログラミングの勉強方法の発信をしてます。

あっきーをフォローする
PHP
\良い記事だったらシェアしてね!/
スポンサーリンク
駆け出しエンジニアのつぶやき