PHPの抽象クラスとは何ですか?


121

PHPの抽象クラスとは何ですか?

どのように使用できますか?




6
@Gordon:時々、公式ドキュメントは一部の人々にとってそれほど明確ではありません:(
Sarfraz


3
@SarfrazはRTFMの意味ではありません。公式ドキュメントへのリンクがあると便利だと思います。また、公式ドキュメントを読んでいない人や、その存在を知らない人がどれほどいるのか信じられないでしょう。
Gordon、

回答:


131

抽象クラスは、少なくとも1つの抽象メソッドを含むクラスです。抽象メソッドは、実際のコードが含まれていないメソッドで、名前とパラメータのみが含まれ、「抽象」としてマークされています。

これの目的は、継承するクラスの一種のテンプレートを提供し、継承クラスに抽象メソッドを実装させることです。

したがって、抽象クラスは、通常のクラスと純粋なインターフェースの間の何かです。また、インターフェースは、すべてのメソッドが抽象である抽象クラスの特殊なケースです。

詳細については、PHPマニュアルのこのセクションを参照してください。


6
では、このスレッド、抽象的には、任意の抽象メソッドが含まれていません。
r0ng 2016年

6
@ r0ng抽象クラスには抽象メソッド含まれる場合があり、抽象メソッドは常に抽象クラス内にある必要があると言う方が正しいでしょう。私の心の中で定義している実用的な機能は、抽象クラスをインスタンス化することはできませんが、メソッドを継承して上書きすることができ、抽象クラスの静的メソッドは通常どおり使用できることです。
okdewit 2017

117

抽象クラスは、1つ以上の抽象メソッドを含むクラスです。抽象メソッドは、宣言されているが実装が含まれていないメソッドです。抽象クラスはインスタンス化されない場合があり、抽象メソッドの実装を提供するためにサブクラスが必要です。

1.抽象クラスをインスタンス化できない抽象として定義されたクラスはインスタンス化できません。また、少なくとも1つの抽象メソッドを含むクラスも抽象でなければなりません。

以下の例:

abstract class AbstractClass
{

    abstract protected function getValue();
    abstract protected function prefixValue($prefix);


    public function printOut() {
        echo "Hello how are you?";
    }
}

$obj=new AbstractClass();
$obj->printOut();
//Fatal error: Cannot instantiate abstract class AbstractClass

2.少なくとも1つの抽象メソッドを含むクラスも抽象である必要があります。抽象クラスには抽象メソッドと非抽象メソッドを含めることができますが、少なくとも1つの抽象メソッドを含める必要があります。クラスに少なくとも1つの抽象メソッドがある場合、そのクラスは抽象として宣言する必要があります。

注:トレイトは、提示するクラスに要件を課すために、抽象メソッドの使用をサポートします。

以下の例:

class Non_Abstract_Class
{
   abstract protected function getValue();

    public function printOut() {
        echo "Hello how are you?";
    }
}

$obj=new Non_Abstract_Class();
$obj->printOut();
//Fatal error: Class Non_Abstract_Class contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Non_Abstract_Class::getValue)

3.抽象メソッドに本文を含めることはできません:抽象として定義されたメソッドは、メソッドの署名を宣言するだけです-実装を定義することはできません。ただし、非抽象メソッドは実装を定義できます。

abstract class AbstractClass
{
   abstract protected function getValue(){
   return "Hello how are you?";
   }

    public function printOut() {
        echo $this->getValue() . "\n";
    }
}

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

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

$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') ."\n";
//Fatal error: Abstract function AbstractClass::getValue() cannot contain body

4.抽象クラスから継承する場合、親のクラス宣言で抽象とマークされたすべてのメソッドは、子によって定義される必要があります。抽象クラスを継承する場合、その中のすべての抽象メソッドに実装を提供する必要があります。

abstract class AbstractClass
{
    // Force Extending class to define this method
    abstract protected function getValue();

    // Common method
    public function printOut() {
        print $this->getValue() . "<br/>";
    }
}

class ConcreteClass1 extends AbstractClass
{
    public function printOut() {
        echo "dhairya";
    }

}
$class1 = new ConcreteClass1;
$class1->printOut();
//Fatal error: Class ConcreteClass1 contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (AbstractClass::getValue)

5.同じ(またはそれほど制限されない)可視性:抽象クラスから継承する場合、親のクラス宣言で抽象とマークされたすべてのメソッドは子によって定義される必要があります。さらに、これらのメソッドは、同じ(または制限の少ない)可視性で定義する必要があります。たとえば、抽象メソッドが保護されていると定義されている場合、関数の実装は、プライベートではなく、保護またはパブリックとして定義する必要があります。

抽象メソッドはプライベートであってはならないことに注意してください。

abstract class AbstractClass
{

    abstract public function getValue();
    abstract protected function prefixValue($prefix);

        public function printOut() {
        print $this->getValue();
    }
}

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

    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass1";
    }
}
$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') ."<br/>";
//Fatal error: Access level to ConcreteClass1::getValue() must be public (as in class AbstractClass)

6.抽象メソッドのシグネチャは一致する必要があります。抽象クラスから継承する場合、親のクラス宣言で抽象とマークされたすべてのメソッドは子によって定義される必要があります。メソッドのシグネチャは一致する必要があります。つまり、タイプヒントと必要な数引数は同じでなければなりません。たとえば、子クラスがオプションの引数を定義し、抽象メソッドのシグネチャが定義しない場合、シグネチャに競合はありません。

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"), "<br/>";
echo $class->prefixName("Pacwoman"), "<br/>";
//output: Mr. Pacman
//        Mrs. Pacwoman

7.抽象クラスは多重継承をサポートしていません:抽象クラスは別の抽象クラスを拡張できます。抽象クラスはインターフェイスの実装を提供できます。しかし、多重継承はサポートしていません。

interface MyInterface{
    public function foo();
    public function bar();
}

abstract class MyAbstract1{
    abstract public function baz();
}


abstract class MyAbstract2 extends MyAbstract1 implements MyInterface{
    public function foo(){ echo "foo"; }
    public function bar(){ echo "bar"; }
    public function baz(){ echo "baz"; }
}

class MyClass extends MyAbstract2{
}

$obj=new MyClass;
$obj->foo();
$obj->bar();
$obj->baz();
//output: foobarbaz

注:コード内のクラスの順序または位置付けはインタープリターに影響を与え、致命的なエラーを引き起こす可能性があることに注意してください。したがって、抽象化の複数のレベルを使用する場合は、ソースコード内でのクラスの配置に注意してください。

以下の例では致命的なエラーが発生します:クラス 'horse'が見つかりません

class cart extends horse {
    public function get_breed() { return "Wood"; }
}

abstract class horse extends animal {
    public function get_breed() { return "Jersey"; }
}

abstract class animal {
    public abstract function get_breed();
}

$cart = new cart();
print($cart->get_breed());

1
よく練られた。
Talk2Nit

18

抽象クラスは、プログラマによって部分的にのみ実装されるクラスです。1つ以上の抽象メソッドが含まれている場合があります。抽象メソッドは、メソッドを子クラスに実装する必要があることをプログラマーに伝えるための関数定義です。

ここでそれの良い説明があります


こんにちは、説明ありがとうございます。真実は、PHPでの抽象とインターフェースについて、インターネット上でこれほど良い説明はないということです。
レーニンサパタ

12

抽象クラス
1.抽象メソッドを含む
2.直接初期化
できない3.抽象クラスのオブジェクトを作成できない
4.継承の目的でのみ使用

抽象メソッド
1.本体を含めることはできません
2.プライベートとして定義することはできません
3.子クラスは、抽象クラスで宣言されたメソッドを定義する必要があります

コード例:

abstract class A {
    public function test1() {
        echo 'Hello World';
    }
    abstract protected function f1();
    abstract public function f2();
    protected function test2(){
        echo 'Hello World test';
    }
}

class B extends A {
    public $a = 'India';
    public function f1() {
        echo "F1 Method Call";
    }
    public function f2() {
        echo "F2 Method Call";
    }
}

$b = new B();
echo $b->test1() . "<br/>";
echo $b->a . "<br/>";
echo $b->test2() . "<br/>";
echo $b->f1() . "<br/>";
echo $b->f2() . "<br/>";

出力:

Hello World
India
Hello World test
F1 Method Call
F2 Method Call

子クラスオブジェクトで親の保護されたメソッドを呼び出すことはできません。このオブジェクトで子クラスメソッドを呼び出すことができます。echo $ b-> test2()。"<br/>";
Al-Amin

7
  • 抽象クラスにはメソッドのシグネチャの宣言のみが含まれ、実装を定義することはできません。
  • 抽象化クラスは、キーワードabstractを使用して定義されます。
  • 抽象クラスは多重継承を実装することはできません。
  • PHP 5の最新バージョンでは、抽象クラスとメソッドが導入されています。
  • 抽象として定義されたクラス。オブジェクトを作成できません(インスタンス化されない場合があります)

0

抽象クラスは、直接初期化できないクラスです。あるいは、言い換えると、抽象クラスは、オブジェクトを直接作成できないクラスであると言えます。PHPでは、抽象クラスはキーワードabstractで定義されています。

また、少なくとも1つのクラスの抽象クラスになるには、クラスの1つのメソッドが抽象クラスでなければなりません。

抽象クラスの詳細については、PHPの抽象クラスに関するブログを参照してください。


0

抽象クラスは、通常のクラスと同様に、変数を含み、保護された変数を含みます。

抽象メソッドは、定義のない空のメソッドを意味するため、抽象クラスの1つの違いだけでは、抽象クラスのオブジェクトを作成できません

抽象には抽象メソッドが含まれている必要があり、それらのメソッドは継承クラスで定義されている必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.