PHP対象プログラム設計(oop)学習ノート(一)-抽象類、対象インターフェース、instance ofと契約式プログラミング


1、PHPの抽象類
PHP 5は抽象類と抽象的な方法に対応しています。抽象的なクラスとして定義されていますが、実用化されません。どのクラスも、少なくとも一つの方法が抽象として宣言されているなら、このクラスは抽象として宣言されなければならない。抽象的な方法として定義されているが、その呼び出し方式(パラメータ)を宣言しているだけで、その具体的な機能の実現は定義されていない。クラスの声明の中でabstract修飾子を使って、ある種類の声明を抽象的にすることができます。
このように理解できます。抽象類は基本類として、特定の細部を継承者に残して実現します。抽象概念によって、開発プロジェクトにおいて、拡張性の高いアーキテクチャを作成することができます。

abstract class AbstractClass
{
    code...
}
1.1、抽象的な方法
abstractキーワードを使って抽象的な方法を定義します。抽象的な方法は、アクセスレベル、関数キーワード、関数名、パラメータを含む方法プロトタイプのみを保持します。彼は({}または括弧内のコードを一切含んでいません。例えば、次のコードは抽象的な方法で定義されています。

abstract 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]
 *
 */
?>
.オブジェクトインターフェース
インターフェースを使って、あるクラスがどのような方法を実装しなければならないかを指定できますが、これらの方法の具体的な内容を定義する必要はありません。
インターフェースはインタフェースのキーワードで定義されています。標準クラスを定義するように、すべての方法を定義するのは空です。
インターフェースで定義されたすべての方法は公有でなければならない。これはインターフェースの特性である。
インターフェースは、クラスと類似した構造であり、実装クラスに対して必要な声明を表明するために使用できる方法である。例えば、インターフェースは一般に、このAPIをどのように実現するかを定義することなく、APIを宣言するために使用される。
ほとんどの開発者は、コードと生成されたドキュメントでクラスと区別するために、インターフェース名の前に大文字Iをプレフィックスとして追加することを選択します。
2.1インターフェース実現(implements)
インターフェースを実現するには、implementsオペレータ(抽象クラスを引き継ぐにはextensのキーワードが異なる)を使用して、インターフェースで定義されたすべての方法を実現しなければなりません。そうでなければ、致命的なエラーが報告されます。クラスは複数のインターフェースを実現し、コンマで複数のインターフェースの名前を分離します。
複数のインターフェースを実現する時、インターフェースの中の方法は重名があってはいけません。インターフェースは引き継ぐこともできます。extensオペレータを使用します。インターフェースを実現するには、インターフェースで定義された方法と完全に一致する方法を使用しなければならない。致命的なエラーが発生します。インターフェースで定数を定義することもできます。インターフェースの定数とクラスの定数の使用は全く同じですが、布団類やサブインターフェースでカバーすることはできません。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値を返します。
PHP変数があるクラスのCLASSに属するかどうかを判定します。対象があるタイプから検査対象を引き継ぐかどうかを確認します。変数があるインターフェースのオブジェクトを実装しているかどうかを判定します。

echo $Porsche911 instanceof Car;
//result:1

echo $Porsche911 instanceof ISpeendInfo;
//result:1

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