What is a abstract class and interface in PHP 开发者_运维技巧and when would you use them? A layman answer with an example would be great to aid my understanding.
Abstract classes and interfaces are not specific to PHP; they're features of many modern object-oriented languages.
An abstract class is a class that has one or more unimplemented member functions. You would use one in a situation where you would want a set of classes that have similar behaviors, differing only in a few methods. Each of these classes would derive from the abstract class, and implement the unimplemented methods in the manner that's appropriate for their specific case.
An interface is similar to an abstract class, but it contains no method implementations, only signatures. A class that implements an interface must implement all of the methods.
A class can implement many interfaces, but can only be derived from one abstract class (or parent class of any sort), since PHP does not support multiple inheritance.
Both abstract classes and interfaces allow for polymorphism; i.e., you can specify a reference as being to an abstract type (which could refer to any instance of class derived from it) or to an object implementing an interface.
Assuming you understand why you use them in other languages, the same concepts apply to PHP. Interfaces are class "signatures"... they contain no code. Abstract classes cannot be instantiated, but they can contain both implemented and abstract (empty) functions.
Note that a class can only extend a single parent class (or abstract class), but it can implement as many interfaces as it needs.
But given that PHP does not have strict typing and has no concept of compile time checks, you can typically make do without them, unlike in languages like C++ or Java.
The core PHP require interfaces for some things. For example:
class Foo implements Countable
{
public function count()
{
return 5;
}
}
echo count(new Foo()); // returns 5
If you remove the "implements Countable," PHP will not call your count
method. There are many other interfaces you can implement that allows custom objects to all behave in a similar way. For instance, you can create an object that works with a foreach
iteration.
Interfaces at the user level aren't extremely useful in PHP, as I previously mentioned. But if you make use of type hints, they can be:
function foo(MyInterface $bar)
{
$bar->someMethod();
}
Assuming someMethod
is declared in MyInterface
, then you are guaranteed that the call to $bar->someMethod()
exists. (The reason why this isn't as useful in PHP as it is in other languages, is because the type hint in the function signature won't get checked until runtime.)
Empty interfaces can be useful too as ways to categorize classes. Say you want to do something to a particular set of objects. They could all implement some empty interface. Then your code could just check for that interface without ever having to know anything about the object.
interface Red {}
class Foo implements Red { }
$foo = new Foo();
if ($foo instanceof Red)
{
// do something
}
Abstract classes are useful when you have a lot of code that is shared among sub classes, but isn't meaningful by itself. You can declare the base class as abstract, implement all the shared functionality, and leave the rest of the functions empty. By declaring that base class as abstract, nobody will ever be able to use it by itself.
The PHP manual explains it simply and provides many examples:
- Interfaces
- Abstraction
Understanding and Applying Polymorphism in PHP
An interface defines a set of methods that a class must implement. Such a class implements the interface by providing a concrete implementation of those methods. An interface cannot contain any implementation of its own; it's just a set of method signatures. If I define an interface called ILogger
, then I can write code that uses the methods defined in ILogger
(maybe write
and writeLine
) to pass along messages to be logged. I can pass in any class that implements ILogger
, and it's all the same to the client code.
An abstract class is similar, but can implement some methods and state. Abstract classes cannot be instantiated, and any class that extends them must provide an implementation of each abstract
method in the parent class. If a set of classes share some implementation details but differ in others, then you can define the shared implementation in an abstract class, declare the differing methods abstract, and let child classes fill those in with their own implementation. If I wanted a uniform way to collect system information, add timestamps, etc. that's shared by all of my loggers, I might choose to create an abstract class LoggerBase
that handles those details, marking write
and writeLine
abstract
so that any classes extending LoggerBase
would just need to specify how to write to their particular log.
精彩评论