見出し画像

PHPでオブジェクト指向に再入門するもん

昔何回も読み直したはずなんですが,未だに「これどういう風に書いたほうがいいんだろう」となるときがあるのでオブジェクト指向周り中心に読み直しましたという備忘録です.改めて読み直してみて頭の中を整理できました.

※JavaとPHPの両方でほぼ同じニュアンスで用いられているはずなので,本とPHPのドキュメントを見ながら書いています.ソースコードは全てPHPです

あと,

も読みたいんですが,Javaなので参考書代わりに.

5章​

オーバーロード
メソッド名が同じだけど,引数が異なるってやつ.毎度オーバーライド(後述)と間違えるんですが何かいい覚え方はないんでしょうか.

PHPであんまり使ったことないなと思って調べてみたら,どうやらPHPにおけるオーバーロードの意味は少し異なるようです(何故).

PHP におけるオーバーロード機能は、 プロパティやメソッドを動的に 作成する ための手法です。
...
注意: PHP における オーバーロード の解釈は、他の多くのオブジェクト指向言語とは異なります。 一般的に「オーバーロード」とは、 「名前は同じだけれども引数の数や型が異なるメソッドを複数用意できる」 という機能のことを指します。

↓を試してみたら PHP Fatal error: Cannot redeclare add() エラーになりました.PHPで一般的なオーバーロードはできないぽいです.

<?php

/**
* @param int $x
* @param int $y
*/
function add(int $x, int $y): void
{
   print($x + $y);
}

/**
* @param string $x
* @param int $y
* @param int $z
*/
function add(string $x, int $y, int $z): void
{
   print($x);
}

add(10, 20);

add('string', 20, 10);

値渡しと参照渡し

値渡しは$x=10っていうのがあったら10を渡して,参照渡しはアドレスを渡します.C++の理解が浅はかなんですが,参照渡しとポインタ渡しはちょっと違うみたいですね(知らんけどw).

PHPだとリファレンス渡しというみたいです.なんとかってギリシャ文字を使うのかと思ってコピペしてみたら&(アンパサンド)でした.

<?php

/**
* @param int $var
*/
function addFive(int $var): void
{
   $var += 5;
}

$x = 10;
addFive($x);
print($x);

だと結果は出力は10のままで

/**
* @param int $var
*/
function addFive(int &$var): void
{
   $var += 5;
}


$x = 10;
addFive($x);
print($x);

だとアドレスが渡されて10+5で出力は15になりました.

7章

オブジェクト指向

そもそもオブジェクト指向とは何か?というのを今一度確認しておくと,「部品化する考え方」のこと.

8章

クラスとオブジェクトとインスタンス

クラスはオブジェクトの設計図で,クラスから生成されるのがオブジェクト(またはインスタンス),なんですが結構曖昧でクラスのこともオブジェクトと指す場合もあるみたいです.確かに雰囲気で話してる部分は心当たりあります.

10章

継承

たいだいの言語で extends と書いて継承している気がします.継承元になるクラスをスーパークラスや親クラスと呼び,継承するクラスがサブクラスや子クラスと呼ばれます.

オーバーライド

親クラスで定義されたメソッドを子クラスで再定義(上書き)することです.

11章

抽象クラス

たいだいの言語で abstract と書いて抽象クラスを表している気がします.抽象クラスは継承されないと使いところがないもので,間違ってインスタンス化されると困るようなものを抽象クラスにします.

抽象メソッド

抽象クラスと似てて,オーバーライドされないと使えないメソッドです.こいつもだいたい abstract がついている気がします.

interface

たいだいの言語で implements と書いてinterfaceを利用している気がします.特に抽象度が高い抽象クラスはinterfaceとして扱うみたいです(これ結構曖昧).イメージとしては抽象クラスの抽象クラス.interfaceのメソッドは全て抽象クラスになります.

個人的にinterfaceにするべきか抽象クラスにするべきかって結構悩んだりします.

抽象クラスの抽象クラスといっても,しょせんは抽象クラスなので,PHPだとimplementsつけてメソッドをオーバーライドすれば使えます.

class Sample implements Template

抽象クラスと違い,interfaceだと複数のinterfaceを継承する多重継承ができます.あまり見たことはないですが

class Sample implements Template1, Template2, Template3

extendsとimplementsの両方を使うと

class SampleClass extends SampleAb implements SampleIn

スクリーンショット 2021-05-15 15.38.32

といった具合になります.コード読んでいると分からなくなってきますが,図にしてみると,どのメソッドがSampleClassで使われるかがよくわかりました.

13章

アクセス修飾子

private ... 自分自身のクラスのみ
protected ... 自分を継承した子クラス
public ... すべてのクラス

どのアクセス修飾子を使うか悩むところですが,本では以下のパターンがスタンダードとして紹介されていました.

フィールドは全て private
メソッドは全てpublic
※クラスは全てpublic

ちな,フィールドはクラスのメンバ変数のことです(PHPだと).

※PHPでクラスにアクセス修飾子を付けているのをあまり見ないので調べてみましたが,どうも付けれない?ような気がします.Javaはできるみたいですが

14章

静的メンバ

静的メンバとは static が付けられているフィールドやメソッドのことです.

静的フィールドはインスタンスごとに1つずつではなく,クラスに1つだけ用意されます.また,静的フィールドと静的メソッドはインスタンス化なしでアクセス可能です.

正しいか非常に怪しいですが,内部的には静的フィールドなどはあらかじめ参照先として1つだけブロックを確保しているから同じものを参照できる...みたいだった気がします(知らんけどw)

この記事が気に入ったらサポートをしてみませんか?