PHP OPAメカニズムとモードプロファイル(抽象類、インターフェースと契約式プログラミング)


1.抽象類
抽象的なクラスのメカニズムは、常に公共の基本クラスを定義し、特定の詳細を継承者に残して実装します。抽象概念によって、開発プロジェクトにおいて、拡張性の高いアーキテクチャを作成することができます。どのクラスも、少なくとも一つの方法が抽象として宣言されているなら、このクラスは抽象として宣言されなければならない。抽象的な方法として定義されているが、その呼び出し方式(パラメータ)を宣言しているだけで、その具体的な機能の実現は定義されていない。種類の声明の中でabstract修飾子を使って、ある種類の声明を抽象的にすることができます。
1.1メソッドプロトタイプ
メソッドの定義からメソッドを削除した後の署名です。アクセスレベル、関数キー、関数名、パラメータが含まれます。彼は({}または括弧内のコードを一切含んでいません。例えば、次のコードは方法の原型です。

public function prototypeName($protoParam)
抽象類を継承する場合、子類は父類の中のあらゆる抽象的な方法を定義しなければならない。また、これらの方法のアクセス制御は、親と同じ(またはより緩やか)でなければならない。
1.2抽象類について
    あるクラスは少なくとも一つの抽象的な方法を含む限り、抽象的なクラスとして宣言しなければなりません。    抽象的な方法として宣言し、実現するには同じまたは低いアクセスレベルを含まなければならない。    newキーワードを使って抽象クラスのインスタンスを作成できません。    生命に抽象的な方法では関数体は含まれません。    拡張されたクラスも抽象的なクラスとして宣言すれば、抽象的なクラスを拡張する際には、すべての抽象的な方法を実現する必要はありません。あるクラスが抽象的なクラスから継承される場合、ベースクラスで宣言されたすべての抽象的な方法が実現されていないときは、抽象的なものとしても宣言されなければなりません。)
1.3抽象類を使用する

<?php
abstract class Car
{   
    abstract function getMaxSpeend();
}

class Roadster extends Car
{
    public $Speend;

    public function SetSpeend($speend = 0)
    {
        $this->Speend = $speend;
    }
    public function getMaxSpeend()
    {
        return $this->Speend;
    }
}

class Street
{
    public $Cars ;
    public $SpeendLimit ;

    function __construct( $speendLimit = 200)
    {
        $this -> SpeendLimit = $speendLimit;
        $this -> Cars = array();
    }

    protected function IsStreetLegal($car)
    {
        if ($car->getMaxSpeend() < $this -> SpeendLimit)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public function AddCar($car)
    {
        if($this->IsStreetLegal($car))
        {
            echo 'The Car was allowed on the road.';
            $this->Cars[] = $car;
        }
        else
        {
            echo 'The Car is too fast and was not allowed on the road.';
        }
    }
}

$Porsche911 = new Roadster();
$Porsche911->SetSpeend(340);

$FuWaiStreet = new Street(80);
$FuWaiStreet->AddCar($Porsche911);

/**
 *
 * @result
 *
 * The Car is too fast and was not allowed on the road.[Finished in 0.1s]
 *
 */
?>

2.オブジェクトインターフェース
インターフェースを使って、あるクラスがどのような方法を実装しなければならないかを指定できますが、これらの方法の具体的な内容を定義する必要はありません。
インターフェースはインタフェースのキーワードで定義されています。標準クラスを定義するように、すべての方法を定義するのは空です。
インターフェースで定義されたすべての方法は公有でなければならない。これはインターフェースの特性である。
インターフェースは、クラスと類似した構造であり、実装クラスに対して必要な声明を表明するために使用できる方法である。例えば、インターフェースは一般に、このAPIをどのように実現するかを定義することなく、APIを宣言するために使用される。
    ほとんどの開発者は、コードと生成されたドキュメントでクラスと区別するために、インターフェース名の前に大文字Iをプレフィックスとして追加することを選択します。
2.1インターフェースの使用
抽象的なクラスを統合するにはextensのキーワードを使う必要がありますが、インターフェースを実現するにはimplementsのキーワードが使われています。一つの種類は複数のインターフェースを実現することができます。この時、私達はコンマで彼らを分離しなければなりません。あるクラスをあるインターフェースを実現したとしてマークしても、この言い訳を実現していないすべての方法は、エラーを投げ出します。
2.2インターフェースを使用した事例

<?php
abstract class Car
{   
    abstract function SetSpeend($speend = 0);
}

interface ISpeendInfo
{
    function GetMaxSpeend();
}

class Roadster extends Car implements ISpeendInfo
{

    public $Speend;

    public function SetSpeend($speend = 0)
    {
        $this->Speend = $speend;
    }

    public function getMaxSpeend()
    {
        return $this->Speend;
    }
}

class Street
{

    public $Cars ;
    public $SpeendLimit ;

    function __construct( $speendLimit = 200)
    {
        $this -> SpeendLimit = $speendLimit;
        $this -> Cars = array();
    }

    protected function IsStreetLegal($car)
    {
        if ($car->getMaxSpeend() < $this -> SpeendLimit)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public function AddCar($car)
    {
        if($this->IsStreetLegal($car))
        {
            echo 'The Car was allowed on the road.';
            $this->Cars[] = $car;
        }
        else
        {
            echo 'The Car is too fast and was not allowed on the road.';
        }
    }
}


$Porsche911 = new Roadster();
$Porsche911->SetSpeend(340);

$FuWaiStreet = new Street(80);
$FuWaiStreet->AddCar($Porsche911);

/**
 *
 * @result
 *
 * The Car is too fast and was not allowed on the road.[Finished in 0.1s]
 *
 */
?>

3.instance of操作子
instance ofオペレータはPHP 5の比較オペレータです。彼は左右のパラメータを受け取り、bollan値を返します。このオペレータは、オブジェクトのあるインスタンスが特定のタイプであるかどうかを判定するために使用され、またはあるタイプから継承されているか、またはある種類の特定のインターフェースを実装するために使用されます。

echo $Porsche911 instanceof Car;
//result:1

echo $Porsche911 instanceof ISpeendInfo;
//result:1

4.契約式プログラミング
契約式プログラミングとは、クラスを作成する前に宣言インターフェースを実現するためのプログラミング実践のことです。この方法はクラスのパッケージ性を保証する上で非常に有用である。契約式のプログラミング技術を使って、私達はアプリケーションを作る前にビューの実現の機能を定義することができます。これは建築士がビルを建てる前に先に青写真を描くというやり方ととても似ています。
5.まとめ
抽象類はabstractを使ったキーワード声明の種類です。あるクラスを抽象的なクラスとしてマークすることによって、私たちは宣言された方法の実現を遅らせることができます。ある方法を抽象的な方法として宣言するには、すべての大かっこを含むメソッドエンティティを取り除くと、メソッド宣言のコード行をセミコロンで終了します。
抽象類は直接的に実例化することができず、彼らは継承されなければならない。
あるクラスが抽象的なクラスから継承される場合、ベースクラスで宣言されたすべての抽象的な方法が実現されないときは、抽象的なものとしても宣言されなければなりません。
インターフェースでは、メソッドのプロトタイプがないことを宣言できます。これは抽象類と似ています。彼らの違いは、インターフェースがいかなる方法体を持っているかを宣言できないことです。そして彼らが使う文法も違います。ルールを明らかにするために、あるクラスに強制的に追加するには、extensキーワードではなくimplementsキーワードを使用する必要があります。
いくつかの場合、特定のクラスのタイプかどうか、または特定のインターフェースが実装されているかどうかを確認する必要があります。instance ofは、このタスクを完了するのに適したものに分類されます。instance ofは、3つのことをチェックします。インスタンスは特定のタイプであるかどうか、インスタンスは特定のタイプから継承されているかどうか、インスタンスまたは彼の任意の祖先タイプがクラス特定のインターフェースを実装しているかどうかです。
いくつかの言語は複数のクラスから継承される能力を持っています。これを多重継承といいます。PHPは多重継承に対応していません。アイデアは、彼が複数のインターフェースを宣言するクラスの機能を提供します。
インターフェースは宣言クラスが従わなければならない規則の時に非常に有用である。契約式プログラミング技術は、この機能を使用してパッケージ性を強化し、ワークフローを最適化する。