所以我已经理解了接口和抽象在 PHP 中是如何工作的,例如,如果它只是设置一个指南并要求实现的对象具有某些方法,我只是没有看到有一个接口的意义。特别是因为接口甚至没有被实例化。
这也与抽象有关,我只是不能将它应用到我的代码中并将其视为一件很棒的事情。当我试图创建更大规模的对象以相互交互以找出接口时,每个类最终都会来回传递信息,但从来没有触及接口。
所以我要问的是你们是否有任何建议或指向外部资源的链接,可以很好地解释这种事情。
我可以给你一个尽可能简单的例子。
假设您想要一个允许您的网站使用 Facebook/Twitter 登录的功能
# here's your interface/abstract class
interface Auth_Adapter {
public function auth();
}
# now your Facebook
class Auth_Adapter_Facebook implements Auth_Adapter {
public function login() {
# include facebook-sdk and auth
}
}
# Twitter
class Auth_Adapter_Twitter implements Auth_Adapter {
public function login() {
# include twitter-oauth and auth
}
}
想象一下,当有人尝试使用 Facebook/Twitter 时,他们可以简单地调用
$adapter = new Auth_Adapter_Facebook;
$adapter->login();
$adapter = new Auth_Adapter_Twitter;
$adapter->login();
如您所见,两个适配器使用相同的login
接口。如果将来您必须包含“Pinterest”登录,会发生什么?只要您实现相同的接口,您的代码仍然可以工作。
编辑:更多解释
这就是你必须使用的原因interface or abstract
# I use `type-hinting` here. So I can ensure that only object that implements `Auth_Adapter` will allow. Without this implementation someone might pass some other object that doesn't have `login` method in. But in our case we don't have to worry about that.
public function perform_login(Auth_Adapter $adapter) {
$adapter->login();
}
这是一个简单的例子。创建接口和抽象类允许您确保对象符合通用 API。请参见下面的示例。
interface iCar
{
function drive();
}
abstract class Car implements iCar
{
public $make = 'Generic';
public function drive()
{
printf("I'm driving in my %s%s", $this->make, PHP_EOL);
}
}
class FordTruck extends Car
{
public $make = "Ford";
}
class Porsche extends Car
{
public $make = 'Porsche';
public function drive()
{
printf("I'm speeding around in my %s%s", $this->make, PHP_EOL);
}
}
class Yugo extends Car
{
public $make = 'Yugo';
public function drive()
{
printf("I'm pushing my %s around town%s", $this->make, PHP_EOL);
}
}
function drive(iCar $car)
{
$car->drive();
}
$car1 = new FordTruck;
$car2 = new Porsche;
$car3 = new Yugo;
drive($car1);
drive($car2);
drive($car3);
即使你没有在drive()
函数上指定输入参数的类型,你也可以检查输入是否是instanceof
一个 iCar
function drive($car)
{
if ($car instanceof iCar)
$car->drive();
}
另一个例子是在你的应用程序中构建一个缓存接口。您可以指定所有缓存引擎都支持相同的方法来读取/写入/使缓存中的对象无效,而无需了解(或关心)特定缓存引擎的实际实现。