型演算子instanceofを使ってクラスのチェックをする【PHP】

エディタPHP

こんにちは。いっとくです!

プログラミングは奥が深い。

色々できるようになったと思っても、もっと高度な方法ってのはいくらでもあるもんです。

本当に機能が多すぎて調べて動きはわかったけど何が便利なの??っていう機能がいっぱいあります。

僕にとってその一つがinstanaceofという型演算子ってやつ。

今回はそんなよくわからないinstanceofの使い方についてまとめてみました。

スポンサーリンク

instanceofの基本的な動き

まず大事なのはinstanceofがどんな動きをするのかということなので、実際のコードで動きをみてみましょう。

<?php

class Car
{
    protected function run() {
        echo '時速80kmで走ります';
    }
}

class Book
{
    protected function read() {
        echo '1ページ目です';
    }
}

$car = new Car();
var_dump($car instanceof Car); //true
var_dump($car instanceof Book); //false

こんな感じで、instanceofの左辺にある要素が右辺のクラスだったらtrueを返し、違う場合はfalseを返します。

要するに、数字とか文字を===とかで比較していたけど、インスタンスを比較するときはその記号がinstanceofに変わっただけって感じですね。

また、そのクラスだけでなく、そのクラスの親クラスやインターフェースを継承しているかどうかもチェックすることができます。

<?php

class Car
{
    protected function run() {
        echo '時速80kmで走ります';
    }
}

class SelfDrivingCar extends Car
{
    private function selfDrive() {
        echo '自動で運転します';
    }
}

$car = new SelfDrivingCar();
var_dump($car instanceof Car); //true
//$carはSelfDrivingCarのインスタンスだが、親クラスがCarなのでtrueが返る

interface SuperEngine
{
    public function runFaster();
}

class SportsCar implements SuperEngine {
    public function runFaster() {
        echo '時速200kmで走ります';
    }
}
$sportsCar = new SportsCar();
var_dump($sportsCar instanceof SuperEngine); //true
// $sportsCarはSportsCarのインスタンスだが、SuperEngineインターフェースを実装しているのでtrueが返る

親クラスが抽象クラスになっている場合も同様にinstanceofでチェック可能!

なるほど、挙動はわかった。

さて、、、これをどう使ったら僕は嬉しくなるんだい??

instanceofの使い方を考える

instanceofは渡された値が特定のクラスであるかやインターフェースの機能を持っているかどうかを確かめることができます。

ということは、、、渡された値のクラスの内容によって条件分岐ができる??

<?php

interface SelfDrive
{
    public function selfDrive();
}

interface SuperEngine
{
    public function runFaster();
}

class Car implements SelfDrive
{
    public function selfDrive() {
        echo ' 自動で走ります';
    }
}

class SportsCar implements SuperEngine {
    public function runFaster() {
        echo '時速200kmで走ります';
    }
}

$num = rand(1, 2);
if ($num === 1) {
    $car = new Car();
} else {
    $car = new SportsCar();
}

function selectRoad ($car) {
    if ($car instanceof SelfDrive) {
        echo '普通の車なので道路に行きます';
    } elseif ($car instanceof SuperEngine) {
        echo 'スポーツカーなのでサーキットに行きます';
    }
}

selectRoad($car); //$numの数字によって違うクラスがインスタンス化されるので、クラスに応じて処理を分岐

ちょっとコードの中身はシンプルすぎるのですがこういうことができそうですね。

渡されたインスタンスのクラスに応じて処理を分岐させるとか。

ただ渡された値によって丸ごと分岐させるようなコードだと、普通に可読性が落ちそうな気がする。

その辺りを考えると、条件分岐をさせるためというよりは、正しいクラスやインターフェースの実装ができているかどうかのチェックをするために使う方が実用的なのかもしれない。

<?php

interface SelfDrive
{
    public function selfDrive();
}

class Car implements SelfDrive
{
    public function selfDrive() {
        echo '自動で走ります';
    }
}

$car = new Car();

function checkFunction ($car) {
    if ($car instanceof SelfDrive) {
        echo '自動運転実装オッケー!';
    } else {
        echo '自動運転じゃない!もっと今風にしてよ!';
    }
}

// ちなみにタイプヒンティングでも型をチェックできるので同じようなことができます。
function checkByTypeHinting (SelfDrive $car) {
    echo '自動運転実装オッケー!';
}

checkFunction($car); //自動運転実装オッケー!
checkByTypeHinting($car); //自動運転実装オッケー!

型をチェックするなら引数でタイプヒンティングを使っても同じようなことができますね!

はい。という訳で今回はPHPのinstanceofの使い道についてでした!

結局何が嬉しくなるのかははっきりわかってない気がする。というか絶対他に何か効率的な使い方や意図が隠れてる気がする。

正直僕がかなりオブジェクト志向的な部分を使いこなせていないので、もし便利な使い方を知っているという方がいらっしゃいましたらコメント等で教えていただけると幸いです!

以上、いっとくでした〜。さいなら!

コメント

  1. […] 型演算子 instanceof を使ってクラスのチェックをする | とりあえず、いっとく! […]

タイトルとURLをコピーしました