PHPにおける抽象クラスとインターフェースの定義と使い方を詳しく解説

伊谢尔伦
リリース: 2023-03-12 12:44:02
オリジナル
2103 人が閲覧しました

1. 抽象クラス抽象クラス

1.抽象クラスとは、クラスの前に抽象キーワードがあり、抽象メソッド(クラスメソッドの関数キーワードの前に抽象キーワード)があるクラスを指します。

2.抽象クラスは直接インスタンス化できません。抽象クラスは、サブクラスに必要なメソッドのみを定義 (または部分的に実装) します。サブクラスは、抽象クラスを継承し、抽象クラス内のすべての抽象メソッドを実装することによって、抽象クラスを具体化できます。

3.サブクラスをインスタンス化する必要がある場合は、抽象クラス内のすべての抽象メソッドを実装する必要があります。サブクラスが抽象クラス内のすべての抽象メソッドを実装していない場合、サブクラスも抽象クラスであるため、クラスの前に抽象キーワードを追加する必要があり、インスタンス化できません。

りぃ

4.以下に示すように、A を継承するサブクラス B を作成するが、抽象メソッド abstract_func():

abstract class A  
{  
    /** 抽象类中可以定义变量 */  
    protected $value1 = 0;  
    private $value2 = 1;  
    public $value3 = 2;  
    /** 也可以定义非抽象方法 */  
    public function my_print()  
    {  
        echo "hello,world/n";  
    }  
    /** 
     * 大多数情况下,抽象类至少含有一个抽象方法。抽象方法用abstract关键字声明,其中不能有具体内容。 
     * 可以像声明普通类方法那样声明抽象方法,但是要以分号而不是方法体结束。也就是说抽象方法在抽象类中不能被实现,也就是没有函数体“{some codes}”。 
     */  
    abstract protected function abstract_func1();  
    abstract protected function abstract_func2();  
}  
abstract class B extends A  
{  
    public function abstract_func1()  
    {  
       echo "implement the abstract_func1 in class A/n";  
    }  
    /** 这么写在zend studio 8中会报错*/  
    //abstract protected function abstract_func2();  
}  
class C extends B  
{  
    public function abstract_func2()  
    {  
       echo "implement the abstract_func2 in class A/n";  
    }  
}
ログイン後にコピー

を実装していない場合、プログラムには次のエラーが発生します:

Class B extends A{};
ログイン後にコピー

5。 B が抽象メソッド abstract_func() を実装する場合、B の abstract_func() メソッドの アクセス制御 は、A の abstract_func() のアクセス制御よりも厳密にすることはできません。つまり、

(1) A () の abstract_func の場合 宣言は public であるため、B の abstract_func () のステートメントは、protrotition または private ではなく、public のみにすることができます

(2) A の abstract_func () ステートメントが profestru の場合、Public ですまたは保護されていますが、非公開にすることはできません

(3)。 (致命的なエラー: 抽象関数 A::abstract_func() をプライベートに宣言することはできません)

2.

インターフェースインターフェース1.抽象クラスは具体的な実装の標準を提供しますが、インターフェイスは純粋なテンプレートです。インターフェイスは関数のみを定義し、実装内容は定義しません。インターフェースはキーワードinterfaceで宣言されます。

2.インターフェイスは完全に抽象的であり、メソッドとパブリック メソッドのみを宣言でき、メソッド本体を定義できず、インスタンス変数も宣言できません。ただし、インターフェースは

定数

変数を宣言できます。ただし、インターフェイスに定数変数を配置すると、インターフェイスとして存在する目的に違反し、インターフェイスとクラスの異なる値が混乱します。本当に必要な場合は、対応する抽象クラスまたはクラスに配置できます。 りー3.インターフェイスを実装するクラスは、インターフェイス

Fatal error: Class B contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (A::abstract_func)
ログイン後にコピー

で定義されているすべてのメソッドを実装する必要があります。それ以外の場合、クラスは抽象として宣言する必要があります。

abstract class E implements iA{}
ログイン後にコピー

4.一个类可以在声明中使用implements关键字来实现某个接口。这么做之后,实现接口的具体过程和继承一个仅包含抽象方法的抽象类是一样的。一个类可以同时继承一个父类和实现任意多个接口。extends子句应该在implements子句之前。PHP只支持继承自一个父类,因此extends关键字后只能跟一个类名。

interface iB  
{  
    public function iBfunc1();  
    public function iBfunc2();  
}  
class D extends A implements iA,iB  
{  
    public function abstract_func1()  
    {  
       echo "implement the abstract_func1 in class A/n";  
    }  
    public function abstract_func2()  
    {  
       echo "implement the abstract_func2 in class A/n";  
    }  
    public function iAfunc1(){echo "in iAfunc1";}  
    public function iAfunc2(){echo "in iAfunc2";}  
    public function iBfunc1(){echo "in iBfunc1";}  
    public function iBfunc2(){echo "in iBfunc2";}  
}  
   
class D extends B implements iA,iB  
{  
    public function abstract_func1()  
    {  
       parent::abstract_func1();  
       echo "override the abstract_func1 in class A/n";  
    }  
    public function abstract_func2()  
    {  
       echo "implement the abstract_func2 in class A/n";  
    }  
    public function iAfunc1(){echo "in iAfunc1";}  
    public function iAfunc2(){echo "in iAfunc2";}  
    public function iBfunc1(){echo "in iBfunc1";}  
    public function iBfunc2(){echo "in iBfunc2";}  
}
ログイン後にコピー

5.接口不可以实现另一个接口,但可以继承多个

interface iC extends iA,iB{}  
class F implements iC  
{  
    public function iAfunc1(){echo "in iAfunc1";}  
    public function iAfunc2(){echo "in iAfunc2";}  
    public function iBfunc1(){echo "in iBfunc1";}  
    public function iBfunc2(){echo "in iBfunc2";}  
}
ログイン後にコピー

三、抽象类和接口的异同

1.相同点:

(1)     两者都是抽象类,都不能实例化。

(2)     interface实现类及abstract class的子类都必须要实现已经声明的抽象方法。

2. 不同点:

(1)     interface需要实现,要用implements,而abstract class需要继承,要用extends。

(2)     一个类可以实现多个interface,但一个类只能继承一个abstract class。

(3)     interface强调特定功能的实现,而abstract class强调所属关系。

(4)     尽管interface实现类及abstract class的子类都必须要实现相应的抽象方法,但实现的形式不同。interface中的每一个方法都是抽象方法,都只是声明的 (declaration, 没有方法体),实现类必须要实现。而abstract class的子类可以有选择地实现。这个选择有两点含义:a) abstract class中并非所有的方法都是抽象的,只有那些冠有abstract的方法才是抽象的,子类必须实现。那些没有abstract的方法,在 abstract class中必须定义方法体;b) abstract class的子类在继承它时,对非抽象方法既可以直接继承,也可以覆盖;而对抽象方法,可以选择实现,也可以留给其子类来实现,但此类必须也声明为抽象类。既是抽象类,当然也不能实例化。

(5)     abstract class是interface与class的中介。abstract class在interface及class中起到了承上启下的作用。一方面,abstract class是抽象的,可以声明抽象方法,以规范子类必须实现的功能;另一方面,它又可以定义缺省的方法体,供子类直接使用或覆盖。另外,它还可以定义自己的实例变量,以供子类通过继承来使用。

(6)     接口中的抽象方法前不用也不能加abstract关键字,默认隐式就是抽象方法,也不能加final关键字来防止抽象方法的继承。而抽象类中抽象方法前则必须加上abstract表示显示声明为抽象方法。

(7)     接口中的抽象方法默认是public的,也只能是public的,不能用private,protected修饰符修饰。而抽象类中的抽象方法则可以用public,protected来修饰,但不能用private。

3. interface的应用场合

(1)     类与类之间需要特定的接口进行协调,而不在乎其如何实现。

(2)     作为能够实现特定功能的标识存在,也可以是什么接口方法都没有的纯粹标识。

(3)     需要将一组类视为单一的类,而调用者只通过接口来与这组类发生联系。

(4)     需要实现特定的多项功能,而这些功能之间可能完全没有任何联系。

4. abstract class的应用场合

一句话,在既需要统一的接口,又需要实例变量或缺省的方法的情况下,就可以使用它。最常见的有:

(1)     定义了一组接口,但又不想强迫每个实现类都必须实现所有的接口。可以用abstract class定义一组方法体,甚至可以是空方法体,然后由子类选择自己所感兴趣的方法来覆盖。

(2)     某些场合下,只靠纯粹的接口不能满足类与类之间的协调,还必需类中表示状态的变量来区别不同的关系。abstract的中介作用可以很好地满足这一点。

(3) 相互に調整されたメソッドのセットを指定します。一部のメソッドは共通で状態に依存せず、サブクラスが個別に実装する必要がなく共有できますが、他のメソッドは各サブクラスがそのメソッドに従って実装する必要があります。特定の機能を実装するための独自の特定の状態 。

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

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート