PHP: Абстрактные классы - Manual

downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

Интерфейсы объектов Константы в объектах

Last updated: Sat, 27 Jan 2007

view this page in

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

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

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

`<?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".

add a note User Contributed Notes
Абстрактные классы
david at mr-t dot nl
25-Jul-2006 08:27
`It took me a while to figure this out and i couldn't find it easily in the documentation anywhere.
If you want to override a method from a base class and want to call the base class in the method, then you have to use the parent::function() syntax, even though the method isn't static. There is no $base variable in php that i know of.
Expamle:
<?php
public abstract class BasePerson() {
/*
* alot of code..
*/
public function getName() {
return $this->name;
}
}
public class Person() extends BasePerson {
/*
* alot of code..
*/
// override of base getName()..
public function getName() {
// you would expect $base->getName() instead of parrent::getName()...
return htmlspecialchars(parent::getName());
}
}
?>
Hope this helps!`
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`
add a note
Интерфейсы объектов Константы в объектах

Last updated: Sat, 27 Jan 2007
show source | credits | stats | sitemap | contact | advertising | mirror sites
Copyright © 2001-2007 The PHP Group
All rights reserved.
This mirror generously provided by: Yahoo! Inc.
Last updated: Sat Mar 10 09:32:46 2007 PST