Абстрактные классы

PHP 5 поддерживает определение абстрактных классов и методов. Создавать экземпляр класса, который был объявлен абстрактным, нельзя. Класс, в котором объявлен хотя бы один абстрактный метод, должен также быть объявлен абстрактным. Методы, объявленные как абстрактные, несут, по существу, лишь описательный смысл и не могут включать какой-либо функционал.

Пример 19-17. Пример абстрактного класса

<?php

abstract class AbstractClass {

  
/* Данный метод должен быть определён в дочернем классе */
  
abstract protected function getValue();

  
/* Общий метод */
  
public function print() {
     print
$this->getValue();
   }

}

class
ConcreteClass1 extends AbstractClass {

   protected function
getValue() {
     return
"ConcreteClass1";
   }

}

class
ConcreteClass2 extends AbstractClass {

   protected function
getValue() {
     return
"ConcreteClass2";
   }

}

$class1 = new ConcreteClass1;
$class1->print();

$class2 = new ConcreteClass2;
$class2->print();
?>

Код, предназначенный для прежних версий PHP, должен работать без изменений, если в нём отсутствуют классы или функции, именованные "abstract".



Абстрактные классы
James
16-May-2006 10:10
A nice tutorial on PHP5's abstract classes and interfaces:

Working with php5 class types abstract classes and interfaces.

http://www.phpfive.net/article4.htm
gsteren at gmail dot com
06-Mar-2006 05:48
Abstract classes allow the declaration of protected abstract methods, which cannot be emulated with the use of an interface and a concrete superclass.

Even private abstract methods can be declared, although I fail to see the use in them, as subclasses will not see them anyway.
rasto_klc (at) yahoo (dot) obvious
28-Dec-2005 01:27
Variable-length argument lists in abstract methods will generate fatal error if derived. Here is an simple example:

<?php
// common wrap for all validators is forcing uniform interface
abstract class ValidatorWrap {

  
// just example why variable-length arguments are needed
  
public function __construct()
   {
       if (
func_num_args() > 0) {
          
$arg_list = func_get_args();
          
call_user_func_array(array(&$this, 'setupValidator'), $arg_list);
       } else {
          
$this->setupValidator();
       }
      
// continue with construction
  
}

  
// amount of arguments is specific to validator implementation
  
abstract public function setupValidator();

  
// known interface
  
abstract public function validate($value);
}

class
Validator1 extends ValidatorWrap {

   protected
$pattern = '';

  
// this will generate PHP Fatal error because $pattern is not expected
  
public function setupValidator($pattern)
   {
      
$this->pattern = $pattern;
   }

  
// this will do OK
  
public function validate($value)
   {
       return
preg_match($this->pattern, $value);
   }
}

// make numeric validator
$validator = new Validator1('/^\d+$/');
echo (int)
$validator->validate($_REQUEST['digits']);
?>

I need it to work so I just redefine troublemaking function as follows:

<?php
  
public function setupValidator() { }
?>

This will give me functionality I need and generates only PHP Strict Standards warning.
turgut85 at hotmail dot com
02-Dec-2005 09:38
<?php

// Design Pattern ABSTRACT FACTORY  implementation //

abstract class AbstractFactory {
   public abstract function
CreateProductA();  // return data type is AbstractProductA
  
public abstract function CreateProductB();  // return data type is AbstractProductB
}

// Abstract factory #1 //
class ConcreteFactory1 extends AbstractFactory {

   public function
CreateProductA() { // return data type is AbstractProductA
      
return new ProductA1();
   }

   public function
CreateProductB() { // return data type is AbstractProductB
      
return new ProductB1();
   }
}

// Abstract factory #2 //
class ConcreteFactory2 extends AbstractFactory {

   public function
CreateProductA() { // return data type is AbstractProductA //
      
return new ProductA2();
   }

   public function
CreateProductB() { // return data type is AbstractProductB //
      
return new ProductB2();
   }
}

// "AbstractProductA" //
abstract class AbstractProductA {
}

// "AbstractProductB" //
abstract class AbstractProductB {
   public abstract function
Interact($a); // return type is void // // input type is  AbstractProductA
}

// "ProductA1" //
class ProductA1 extends  AbstractProductA {
}

// "ProductB1" //
class ProductB1 extends  AbstractProductB {

   public function
Interact($a) {
       echo
__CLASS__." interacts with ".__METHOD__."\n";
      
var_dump($a);
   }
}

// "ProductA2"
class ProductA2 extends AbstractProductA {
}

// "ProductB2"
class ProductB2 extends AbstractProductB {
   public function
Interact($a) {
       echo
__CLASS__." interacts with ".__METHOD__."\n";
      
var_dump($a);
   }
}

class
Client {

   private 
$AbstractProductA;                            // type AbstractProductA;
  
private  $AbstractProductB;                            // type AbstractProductB;

   // Constructor
  
public function __construct($factory) {
      
$this->AbstractProductB = $factory->CreateProductB();
      
$this->AbstractProductA = $factory->CreateProductA();
   }

   public function
Run() {
      
$this->AbstractProductB->Interact($this->AbstractProductA);
   }
}

// Abstract factory #1
$factory1 = new ConcreteFactory1();
$c1 = new Client($factory1);
$c1->Run();

// Abstract factory #2
$factory2 = new ConcreteFactory2();
$c2 = new Client($factory2);
$c2->Run();

// TURGUT Z. YESILYURT, MS
// Software Developer
// NewJersey, USA

?>
Output::

ProductB1 interacts with ProductB1::Interact
object(ProductA1)#4 (0) {
}
ProductB2 interacts with ProductB2::Interact
object(ProductA2)#8 (0) {
}
mail dot phatlip at gmail dot com
06-Nov-2005 09:04
just RE: ramonzamora at gmail dot com

Abstraction is 'stricter' than inheritance+implementation as it contains 'rules' about the visibility of the methods that are inherited, as well as the fact that it saves needing two classes to get a job done.

The fact you cannot instantiate an abstract class can be benificial also.
ramonzamora at gmail dot com
27-Aug-2005 03:46
so abstract clases are the same than inheritance+interfaces??

<?php

//using inheritance+interfaces

interface callA{
   protected function
callA();
}

class
callB{
   protected
$b;
   protected function
callB(){
       return
$this->b;
   }
}

class
caller extends callB implements callA{
   protected
$a;
   public function
__construct($a,$b){
      
$this->a=$a;
      
$this->b=$b;
   }
   protected function
callA(){
       return
$this->a;
   }
 
   public function
callAB(){
       return
$this->callA().$this->callB();
   }
}

$caller=new caller('a','b');
$caller->callAB();

//using abstract class

abstract class callAB{
   abstract protected function
callA();
   protected
$b;
   protected function
callB(){
       return
$this->b;
   }
}

class
caller extends callAB{
   protected
$a;
   public function
__construct($a,$b){
      
$this->a=$a;
      
$this->b=$b;
   }
   protected function
callA(){
       return
$this->a;
   }
   public function
callAB(){
       return
$this->callA().$this->callB();
   }
}

$caller=new caller('a','b');
$caller->callAB();
?>

the only difference i see is that using inheritance+interfaces you can instantiate the parent but using abstract classes you can't

<Константы в объектахИнтерфейсы объектов>
 Last updated: Tue, 15 Nov 2005