|
|
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
Абстрактные классы
sneakyimp at hotmail dot com
09-Oct-2007 05:05
Ok...the docs are a bit vague when it comes to an abstract class extending another abstract class. An abstract class that extends another abstract class doesn't need to define the abstract methods from the parent class. In other words, this causes an error:
[php]
abstract class class1 {
abstract public function someFunc();
}
abstract class class2 extends class1 {
abstract public function someFunc();
}
[/php]
Error: Fatal error: Can't inherit abstract function class1::someFunc() (previously declared abstract in class2) in /home/sneakyimp/public/chump.php on line 7
However this does not:
[php]
abstract class class1 {
abstract public function someFunc();
}
abstract class class2 extends class1 {
}
[/php]
An abstract class that extends an abstract class can pass the buck to its child classes when it comes to implementing the abstract methods of its parent abstract class.
linus dot martensson at elplan-gm dot se
20-Sep-2007 01:22
This should be a lot more obvious than people make it out to be.
The difference between an interface and an abstract class, is that an interface does not define the behavior of an object.
Rather, it defines how you work with a class.
You use interfaces to decouple the behavior of a class from the accessors and mutators which make up the class.
With an abstract class, you are saying that "Method X should work like this", "Variable Y should be used", an interface could be used to do something completely different.
A well-known usage is that of the proxy.
A proxy is used to moderate access to the real object without modifying the class which describes the object.
Instead, you create a new class, implementing the same interface, adding the new behaviour in the new class.
This could be security checks, accessing a remote object through a TCP/UDP connection, or simply using a light object to avoid creating the heavier one unless it's explicitly necessary depending on the accessed functions.
Either way, the abstract class does not allow this, as it has already decided how the class should work. The interface is much more open-ended in this way and would allow for the same, as it never decides anything about the object implementing it.
pierre at pamdata dot com
01-Aug-2007 12:24
I still don't understand why people want to compare Interfaces and Abstract classes.
They are made for two different purposes in a "development environment".
Interfaces are made for class USERS(the ones who instantiate the class that implements the Interface).
Interfaces can be considered as an agreement between the Class USER and the Class BUILDER/OWNER.
In other words the class Builder/Owner must implement exactly what is in the Interface.
While Abstract Classes are made for other Class builders who are going to EXTEND a "abstract" parent class.
The abstract class will tell what methods to use without changing it, and what methods you can implement in your Child class.
What ever the OOP language used, it should be the same concept.(Those are pure OOP concepts)
As simple as that.
Please,Don't be confused.Take a look again at:
http://www.php.net/manual/en/language.oop5.abstract.php#75990
eamon at gizzle dot co dot uk Eamon Straughn
20-Jul-2007 04:20
Sometimes I wonder. PHP needs to be pushed to its limits and below everyone fails to understand what an interface is and what abstraction is. So let me make it extremely clear as I have many languages under my belt.
Interfaces are in general WYSIWYG implementations of logic which in PHP are not accessible like in other languages like Java \ ASP.NET where you don't have to access the class itself...however in future I hope PHP does give us this functionality. Interfaces in PHP only define public functions without any basic or core functionality therefore making it lesser a friend to PROs from OOP && OOD backgrounds.
Instead Abstraction in PHP is perfered as this allows your objects a core with the ability to define different levels of access to methods | variables | constants. Although publicly allowing access to variables (to me) | (to official \ senior programmers) defeats the whole idea of OO. Abstraction allows the keywords of final which is very important to me as I can have many child objects of objects and of child objects.
Thus knowing the difference helps with your choosen style but if your really looking to make an application with Abstraction I would always suggest using an Abstract Class instead of Interfaces as Interfaces are limited and provides no functionality and is a waste of bytes on your hard drive.
The below is an example of Abstraction used in an automated system.
<?php
Abstract Class events
{
protected $priority;
protected $message;
protected $environment;
protected $syslog;
protected $config;
protected $global;
protected $classes;
protected $super;
public function __construct(array &$config)
{
$this->config = $config;
}
abstract protected function writeToDatabase(Environment &$environment);
abstract protected function writeToSystem(Environment &$environment);
abstract protected function writeToEmail(Environment &$environment);
abstract protected function writeToMobile(Environment &$environment);
abstract public function execute(&$class, $method, $args);
protected function environment(Exception &$object) {
$this->super =& new Environment($object, $this->config);
$this->global = $this->super->env();
$this->global = $this->global['environment'];
return $this->super;
}
public function __destruct()
{
unset($this);
}
}
?>
Wes
06-Jul-2007 02:29
a simple solution to write an abstract class with the constructor predefinition
interface MyBaseClassAbstract
{
public pleaseDefineThisMethod();
}
class MyBaseClass
{
function __construct()
{
if(get_class($this) == __CLASS__)
throw new Exception("you can't instantiate this class");
else
{
//common constructor
}
}
}
class MyClass extends MyBaseClass implements MyBaseClassAbstract
{
function pleaseDefineThisMethod()
{
echo "hello";
}
}
$test = new MyClass();
$test = new MyBaseClass(); // error!
pierre at pamdata dot com
25-Jun-2007 06:25
I love examples.
This example will let you see that an Interface and an Astract Class are two different entities.
Just go and read the Object Interface section at :
http://www.php.net/manual/en/language.oop5.interfaces.php
and look at this example
<?php
abstract class Shape
{
protected $base;
protected $height;
public function getValue($base,$height)
{
$this->base = $base;
$this->height = $height;
}
abstract public function surface();
}
class Triangle extends Shape
{
public function surface(){
return round((($this->base)*($this->height)/2),2);
}
}
class Rectangle extends Shape
{
public function surface(){
return round((($this->base)*($this->height)),2);
}
}
$r = new Rectangle();
$r->getValue(15,3);
echo $r->surface() ."\n"; $t = new Triangle();
$t->getValue(15,3);
echo $t->surface() ."\n"; ?>
joebert
24-Jun-2007 04:09
I don't agree with jfkallens' last comparison between Abstract Classes & Object Interfaces completely.
In an Abstract Class, you can define how some methods work, where as in an Object Interface you can not.
An Object Interface is essentually nothing but a list of function names that a class must define if the class implements that interface.
An Abstract Class is essentually a prototype which hints towards what extending classes should be doing.
An Abstract Class can also be thought of as a Base Class that provides some basic functionality, & also defines a built-in Object Interface that all extending classes will implement.
So, an Object Interface is really a built-in part of an Abstract Class.
jfkallen at hotmail dot com
10-Jun-2007 08:25
A couiple of years ago I raised the question on this website as to what the difference between an interface and an abstract class is. At some point I learned how to define the words for myself since then - and now all is clear :)
An interface allows you to define what is conceptually the same thing as an abstract class except that all methods are public. That makes sense as an "interface" represents how an app or environment interacts with the object - normally via public methods.
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() {
public function getName() {
return $this->name;
}
}
public class Person() extends BasePerson {
public function getName() {
return htmlspecialchars(parent::getName());
}
}
?>
Hope this helps!
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
abstract class ValidatorWrap {
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();
}
}
abstract public function setupValidator();
abstract public function validate($value);
}
class Validator1 extends ValidatorWrap {
protected $pattern = '';
public function setupValidator($pattern)
{
$this->pattern = $pattern;
}
public function validate($value)
{
return preg_match($this->pattern, $value);
}
}
$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
abstract class AbstractFactory {
public abstract function CreateProductA(); public abstract function CreateProductB(); }
class ConcreteFactory1 extends AbstractFactory {
public function CreateProductA() { return new ProductA1();
}
public function CreateProductB() { return new ProductB1();
}
}
class ConcreteFactory2 extends AbstractFactory {
public function CreateProductA() { return new ProductA2();
}
public function CreateProductB() { return new ProductB2();
}
}
abstract class AbstractProductA {
}
abstract class AbstractProductB {
public abstract function Interact($a); }
class ProductA1 extends AbstractProductA {
}
class ProductB1 extends AbstractProductB {
public function Interact($a) {
echo __CLASS__." interacts with ".__METHOD__."\n";
var_dump($a);
}
}
class ProductA2 extends AbstractProductA {
}
class ProductB2 extends AbstractProductB {
public function Interact($a) {
echo __CLASS__." interacts with ".__METHOD__."\n";
var_dump($a);
}
}
class Client {
private $AbstractProductA; private $AbstractProductB; public function __construct($factory) {
$this->AbstractProductB = $factory->CreateProductB();
$this->AbstractProductA = $factory->CreateProductA();
}
public function Run() {
$this->AbstractProductB->Interact($this->AbstractProductA);
}
}
$factory1 = new ConcreteFactory1();
$c1 = new Client($factory1);
$c1->Run();
$factory2 = new ConcreteFactory2();
$c2 = new Client($factory2);
$c2->Run();
?>
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
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();
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
|