ホームページ  >  記事  >  バックエンド開発  >  PHPのインターフェースと抽象クラスの違いは何ですか

PHPのインターフェースと抽象クラスの違いは何ですか

青灯夜游
青灯夜游オリジナル
2021-03-15 17:29:575103ブラウズ

違いは次のとおりです: 1. インターフェイスはインターフェイス キーワードによって定義され、抽象クラスは抽象キーワードによって定義されます; 2. インターフェイスにはデータ メンバーがありませんが、抽象クラスにはデータ メンバーがあります。抽象クラスはデータのカプセル化を実装できます; 3. インターフェイスにはコンストラクターがありませんが、抽象クラスはコンストラクターを持つことができます。

PHPのインターフェースと抽象クラスの違いは何ですか

このチュートリアルの動作環境: Windows7 システム、PHP7.1 バージョン、DELL G3 コンピューター

1. 抽象クラスとインターフェイスの違い

PHP オブジェクト指向を学習するとき、抽象クラスとインターフェイスについて混乱するでしょう。ほとんど同じ機能があるのに、なぜ混同しやすいのでしょうか? 1 つだけ保持して、そのインターフェイスはそのままにしておいてはどうでしょうか?他の?しかし実際には、この 2 つの違いは依然として非常に大きく、PHP の 2 つの方法をうまく活用できれば、オブジェクト指向プログラミングはより合理的で明確かつ効率的になります。

a. インターフェイスは、interface キーワードを通じて定義され、抽象クラスは、abstract キーワードを通じて定義されます。
b. インターフェースの使用はキーワードimplementsによって実現されますが、抽象クラスの操作はクラス継承のキーワードextendsによって実装されますので、使用する場合は特に注意してください。
c. インターフェイスにはデータ メンバーがありませんが、抽象クラスにはデータ メンバーがあり、抽象クラスはデータをカプセル化できます。
d. インターフェイスにはコンストラクターはありませんが、抽象クラスにはコンストラクターがあります。
e. インターフェイス内のメソッドはすべてパブリック型ですが、抽象クラス内のメソッドはプライベート、プロテクト、またはパブリックで変更できます。
f. クラスは同時に複数のインターフェイスを実装できますが、実装できる抽象クラスは 1 つだけです。

同じ点: 抽象メソッドとインターフェイスの関数本体には、2 つの中括弧も含めて何も記述できません。 ! !例: function getName(); これで実行されます。

2. インターフェイス

インターフェイス (インターフェイス) を使用すると、特定のクラスが実装する必要があるメソッドを指定できます。ただし必須ではありません。これらのメソッドの詳細を定義します。

インターフェースは、標準クラスの定義と同様に、interface キーワードを使用して定義されますが、その中で定義されているメソッドはすべて空です。

インターフェイスで定義されたすべてのメソッドはパブリックである必要があります。これはインターフェイスの特性です。

実装

インターフェイスを実装するには、implements 演算子を使用します。クラスは、インターフェイスで定義されているすべてのメソッドを実装する必要があります。実装しない場合は、致命的なエラーが報告されます。クラスは複数のインターフェイスを実装できます。複数のインターフェイスの名前を区切るにはカンマを使用します。

注:
複数のインターフェイスを実装する場合、インターフェイス内のメソッドに同じ名前を付けることはできません。

注:
extends 演算子を使用してインターフェイスを継承することもできます。

注:
インターフェイスを実装するには、クラスはインターフェイスで定義されているメソッドとまったく同じメソッドを使用する必要があります。そうしないと、致命的なエラーが発生します。

定数

定数はインターフェイスで定義することもできます。インターフェイス定数はクラス定数とまったく同じように使用されますが、サブクラスまたはサブインターフェイスによってオーバーライドすることはできません。

 <?php

// 声明一个&#39;iTemplate&#39;接口
interface iTemplate
{
    public function setVariable($name, $var);
    public function getHtml($template);
}


// 实现接口
// 下面的写法是正确的
class Template implements iTemplate
{
    private $vars = array();

    public function setVariable($name, $var)
    {
        $this->vars[$name] = $var;
    }

    public function getHtml($template)
    {
        foreach($this->vars as $name => $value) {
            $template = str_replace('{' . $name . '}', $value, $template);
        }

        return $template;
    }
}

// 下面的写法是错误的,会报错,因为没有实现 getHtml():
// Fatal error: Class BadTemplate contains 1 abstract methods
// and must therefore be declared abstract (iTemplate::getHtml)
class BadTemplate implements iTemplate
{
    private $vars = array();

    public function setVariable($name, $var)
    {
        $this->vars[$name] = $var;
    }
}
?>
Example #2 可扩充的接口

<?php
interface a
{
    public function foo();
}

interface b extends a
{
    public function baz(Baz $baz);
}

// 正确写法
class c implements b
{
    public function foo()
    {
    }

    public function baz(Baz $baz)
    {
    }
}

// 错误写法会导致一个致命错误
class d implements b
{
    public function foo()
    {
    }

    public function baz(Foo $foo)
    {
    }
}
?>
Example #3 继承多个接口

<?php
interface a
{
    public function foo();
}

interface b
{
    public function bar();
}

interface c extends a, b
{
    public function baz();
}

class d implements c
{
    public function foo()
    {
    }

    public function bar()
    {
    }

    public function baz()
    {
    }
}
?>
Example #4 使用接口常量

<?php
interface a
{
    const b = &#39;Interface constant&#39;;
}

// 输出接口常量
echo a::b;

// 错误写法,因为常量不能被覆盖。接口常量的概念和类常量是一样的。
class b implements a
{
    const b = &#39;Class constant&#39;;
}
?>

http://php.net/manual/zh/ language.oop5.interfaces.php

3. 抽象クラス

PHP 5抽象クラスと抽象メソッドをサポートします。抽象として定義されたクラスはインスタンス化できません。クラス内の少なくとも 1 つのメソッドが抽象宣言されている場合は、クラスを抽象宣言する必要があります。抽象として定義されたメソッドは、その呼び出しメソッド (パラメーター) を宣言するだけであり、その特定の関数の実装を定義することはできません。

抽象クラスを継承する場合、サブクラスは親クラス内のすべての抽象メソッドを定義する必要があり、さらに、これらのメソッドのアクセス制御は親クラスと同じ (またはより緩和された) ものでなければなりません。たとえば、抽象メソッドが protected として宣言されている場合、サブクラスに実装されているメソッドは protected または public として宣言する必要があり、private として定義することはできません。さらに、メソッドを呼び出すメソッドは一致している必要があります。つまり、必要なパラメータの型と数が一致している必要があります。たとえば、サブクラスが親クラスの抽象メソッドの宣言に含まれていないオプションのパラメーターを定義している場合、2 つの宣言の間に競合はありません。これは、PHP 5.4 以降のコンストラクターにも当てはまります。 PHP 5.4 より前のコンストラクター宣言は異なる可能性があります。

<?php
abstract class AbstractClass
{
 // 强制要求子类定义这些方法
    abstract protected function getValue();
    abstract protected function prefixValue($prefix);

    // 普通方法(非抽象方法)
    public function printOut() {
        print $this->getValue() . "\n";
    }
}

class ConcreteClass1 extends AbstractClass
{
    protected function getValue() {
        return "ConcreteClass1";
    }

    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass1";
    }
}

class ConcreteClass2 extends AbstractClass
{
    public function getValue() {
        return "ConcreteClass2";
    }

    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass2";
    }
}

$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') ."\n";

$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') ."\n";
?>
以上例程会输出:

ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2
Example #2 抽象类示例

<?php
abstract class AbstractClass
{
    // 我们的抽象方法仅需要定义需要的参数
    abstract protected function prefixName($name);

}

class ConcreteClass extends AbstractClass
{

    // 我们的子类可以定义父类签名中不存在的可选参数
    public function prefixName($name, $separator = ".") {
        if ($name == "Pacman") {
            $prefix = "Mr";
        } elseif ($name == "Pacwoman") {
            $prefix = "Mrs";
        } else {
            $prefix = "";
        }
        return "{$prefix}{$separator} {$name}";
    }
}

$class = new ConcreteClass;
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";
?>
以上例程会输出:

Mr. Pacman
Mrs. Pacwoman
老代码中如果没有自定义类或函数被命名为“abstract”,则应该能不加修改地正常运行。

http://php.net/manual/zh/ language.oop5.abstract.php

推奨学習: 「PHP ビデオ チュートリアル

以上がPHPのインターフェースと抽象クラスの違いは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。