Что такое абстрактный класс в PHP?

123

Что такое абстрактный класс в PHP?

Как это можно использовать?

удайа
источник
1
(Ссылка) de2.php.net/manual/en/language.oop5.abstract.php
Гордон
2
(связанный) stackoverflow.com/questions/2288467/…
Гордон
6
@Gordon: Иногда официальные документы не так понятны для некоторых людей :(
Sarfraz
3
@Sarfraz, не предназначенный для RTFM. Я просто считаю, что ссылка на официальную документацию - полезный актив. И вы не поверите, сколько людей не читают официальные документы или даже не знают, что они существуют.
Гордон

Ответы:

132

Абстрактный класс - это класс, который содержит по крайней мере один абстрактный метод, который представляет собой метод без какого-либо фактического кода в нем, только имя и параметры, и который отмечен как «абстрактный».

Цель этого - предоставить своего рода шаблон для наследования и заставить наследующий класс реализовать абстрактные методы.

Таким образом, абстрактный класс представляет собой нечто среднее между обычным классом и чистым интерфейсом. Также интерфейсы являются частным случаем абстрактных классов, где ВСЕ методы абстрактны.

См. Этот раздел руководства PHP для получения дополнительной информации.

selfawaresoup
источник
6
В этом потоке аннотация не содержит абстрактного метода.
r0ng
6
@ r0ng Правильнее было бы сказать, что абстрактный класс может содержать абстрактные методы, а абстрактные методы всегда должны находиться внутри абстрактного класса. На мой взгляд, определяющие практические особенности заключаются в том, что абстрактный класс не может быть создан, но вы можете наследовать и перезаписывать методы, а статические методы абстрактного класса можно использовать как обычно.
okdewit
118

Абстрактные классы - это классы, содержащие один или несколько абстрактных методов. Абстрактный метод - это метод, который объявлен, но не содержит реализации. Абстрактные классы не могут быть созданы, и для них требуются подклассы для реализации абстрактных методов.

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. Любой класс, содержащий хотя бы один абстрактный метод, также должен быть абстрактным : абстрактный класс может иметь абстрактные и не абстрактные методы, но он должен содержать хотя бы один абстрактный метод. Если у класса есть хотя бы один абстрактный метод, тогда класс должен быть объявлен абстрактным.

Примечание. Черты характера поддерживают использование абстрактных методов, чтобы налагать требования на демонстрирующий класс.

Пример ниже:

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

Примечание. Обратите внимание, порядок или расположение классов в вашем коде может повлиять на интерпретатор и вызвать фатальную ошибку. Итак, при использовании нескольких уровней абстракции будьте осторожны с позиционированием классов в исходном коде.

приведенный ниже пример вызовет фатальную ошибку: класс 'лошадь' не найден

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

Абстрактный класс - это класс, который программист реализует лишь частично. Он может содержать один или несколько абстрактных методов. Абстрактный метод - это просто определение функции, которое сообщает программисту, что метод должен быть реализован в дочернем классе.

Существует хорошее объяснение того , что здесь .

Sarfraz
источник
Привет, спасибо за объяснение, правда в том, что в Интернете нет такого хорошего объяснения абстрактности и интерфейса в 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/>";
Аль-Амин
7
  • Абстрактный класс содержит только объявление сигнатуры метода, они не могут определить реализацию.
  • Класс абстракции определяется с помощью ключевого слова abstract .
  • В абстрактном классе невозможно реализовать множественное наследование .
  • В последней версии PHP 5 представлены абстрактные классы и методы.
  • Классы, определенные как абстрактные, мы не можем создать объект (не можем создать экземпляр)
Elangovan
источник
0

Абстрактные классы - это те классы, которые нельзя инициализировать напрямую. Или, другими словами, мы можем сказать, что абстрактные классы - это те классы, объект которых нельзя создать напрямую. В PHP абстрактные классы игнорируются ключевым словом abstract .

Также, чтобы стать одним абстрактным классом, один метод класса должен быть абстрактным.

Подробную информацию об абстрактном классе вы можете найти в моем блоге об абстрактном классе в PHP .

Анкур Кумар Сингх
источник
0

Абстрактный класс похож на обычный класс, он содержит переменные, он содержит защищенные переменные, функции, он содержит конструктор, только одно отличается: он содержит абстрактный метод.

Абстрактный метод означает пустой метод без определения, поэтому только одно различие в абстрактном классе мы не можем создать объект абстрактного класса.

Abstract должен содержать абстрактный метод, и эти методы должны быть определены в его наследующем классе.

шрияш дешмукх
источник