在你的 Laravel 职业生涯中,你会多次听到“依赖注入”这个词,所以你不妨熟悉一下它。在我们进入 Laravel 之前,让我们看看依赖注入作为 PHP(或任何编程语言)中的一个概念。
我们应该知道我们可以将对象作为参数传递给方法。我们也可以用继承类打hint,这是对PHP多态性的一个概述。我们可以将对象作为参数传递给构造函数。然后构造函数将在类中设置属性。这称为依赖注入。
在我的 PHP 教程系列中,我们研究了依赖注入。我们可以使用该代码来刷新自己。首先,让我们创建几个类:Lamborghini 和 Ferrari。这些类中的每一个都需要 Car 类。
<?php
require_once("Car.php");
class Lamborghini extends Car {
}
<?php
require_once("Ferrari.php");
class Ferrari extends Car {
}
我们现在可以创建我们的测试类并实例化这些对象。
<?php
// Object Arguments
require_once("Lamborghini.php");
require_once("Ferrari.php");
$lamborghini_diablo = new Lamborghini(1999, "Lamborghini", "Diablo");
$ferrari_f355 = new Ferrari(1996, "Ferrari", "F355");
你觉得上面的代码行得通吗?我们没有向 Lamborghini 和 Ferrari 类添加任何构造函数,但我们将参数传递给构造函数。信不信由你,它确实会起作用。为什么?因为我们已经在Car
父类中定义了构造函数参数。如果我们的子类中没有构造函数,它会自动将参数传递给我们的父类。让我们快速浏览一下我们的Car
类构造函数。
<?php
require_once('Vehicle.php');
require_once('Engine.php');
require_once('Transmission.php');
class Car extends Vehicle
{
use Transmission, Engine {
Transmission::check_oil_level insteadof Engine;
Engine::check_oil_level as check_engine_oil_level;
}
const HAS_HEADLIGHTS = true;
const HAS_TAIL_LIGHTS = true;
const HAS_TURN_SIGNALS = true;
private int $fuel_type;
private int $hp;
private int $tq;
private string $transmission;
private string $vehicle_type;
private bool $car_on;
public function __construct(int $year,
string $make,
string $model,
string $color = "",
int $fuel_type = 93,
int $hp = -1,
int $tq = -1,
string $transmission = "5 Speed Manual",
string $vehicle_type = "",
float $exterior_height = -1,
float $exterior_width = -1,
float $exterior_length = -1,
string $exterior_um = "in",
float $weight = -1,
string $weight_um = "lbs",
bool $car_on = false
)
{
$this->year = $year;
$this->make = $make;
$this->model = $model;
$this->color = $color;
$this->fuel_type = $fuel_type;
$this->hp = $hp;
$this->tq = $tq;
$this->transmission = $transmission;
$this->vehicle_type = $vehicle_type;
$this->exterior_height = $exterior_height;
$this->exterior_width = $exterior_width;
$this->exterior_length = $exterior_length;
$this->exterior_um = $exterior_um;
$this->weight = $weight;
$this->weight_um = $weight_um;
$this->car_on = $car_on;
}
//...
}
我们现在能做什么?我们可以访问父类中的所有属性和方法(只要它们不是私有的)。所以我们可以调用那些属性和方法。
<?php
// Object Arguments
require_once("Lamborghini.php");
require_once("Ferrari.php");
$lamborghini_diablo = new Lamborghini(1999, "Lamborghini", "Diablo");
echo $lamborghini_diablo->check_engine_oil_level();
$ferrari_f355 = new Ferrari(1996, "Ferrari", "F355");
echo $ferrari_f355->check_oil_level();
伟大的。我们还没有完成任何对象作为参数的传递。
我们要做的是创建一个Driver
类。我们Driver
类中的第一个方法将是drive()
方法,因为Driver
应该可以drive()
开车。我们可以将Car
对象作为参数传递给它,然后我们可以使用各种不同的Car
方法来帮助我们驾驶汽车。我们将重点关注Car
类中的两个方法是turnOn()
方法和drive()
方法。
<?php
class Driver {
public function drive(Car $car) {
echo $car->turnOn();
echo $car->drive();
}
}
我们现在可以回到我们的测试类并实例化对象。
<?php
// Object Arguments
require_once("Lamborghini.php");
require_once("Ferrari.php");
$lamborghini_diablo = new Lamborghini(1999, "Lamborghini", "Diablo");
$ferrari_f355 = new Ferrari(1996, "Ferrari", "F355");
$dino = new Driver();
$dino->drive( $lamborghini_diablo );
刚刚发生了什么?我以为我们指定我们必须将Car
类型对象作为参数传递给drive()
方法。它在drive()
声明中。
public function drive( Car $car )
这是你关于多态性的课程。由于我们的类Lamborghini
和Ferrari
类都扩展了Car
类,从技术上讲它们是汽车!你猜怎么了?由于Car
扩展了Vehicle
类,从技术上讲,类Lamborghini
和Ferrari
类也是车辆!您想知道我们是否可以修改我们的声明以说明以下内容:
public function drive( Vehicle $vehicle )
答案是肯定的!你绝对可以。而且您仍会将 the$lamborghini_diablo
或$ferrari_f355
作为参数传递给该drive()
方法。如果我们将 传递$ferrari_f355
给我们的drive()
方法,我们将得到以下结果:Ferrari F355 has been turned on. I’m driving.
现在让我们做一些不同的事情。int
我们创建了、string
等类型的类属性?只要看看Car
类,您就会看到所有各种不同的属性。我们如何初始化这些属性?从构造函数。在实例化对象时,我们会将参数传递给构造函数,然后构造函数会使用作为参数传递的值来初始化这些属性。与我们将在课堂上所做的相同的概念Driver
。我们将指定我们将拥有一个Car
基于属性,并且我们将通过我们的构造函数传递一个Car
参数并将其分配给我们的Car
属性。请记住, aCar
只是一种数据类型,例如int
or string
。
<?php
class Driver {
private Car $car;
public function __construct(Car $car)
{
$this->car = $car;
}
}
我现在不想在这里失去你。请记住,一旦$car
通过我们的构造函数初始化了该属性,我们就可以访问我们所有的Car
属性和方法,例如turnOn()
和drive()
。因为我们知道我们必须将一种Car
类型的对象传递给我们的构造函数并且它必须分配给我们的$car
属性,所以我们可以创建方法以预期我们将能够访问这些Car
方法。所以,让我们drive()
在我们的类中重新创建我们的方法Driver
。
<?php
class Driver {
private Car $car;
public function __construct(Car $car)
{
$this->car = $car;
}
public function drive() {
echo $this->car->turnOn();
echo $this->car->drive();
echo $this->car->turnOff();
}
}
你知道这是怎么回事吗?让我们在我们的测试文件中运行一个示例,然后遍历代码。
<?php
// Object Arguments
require_once("Lamborghini.php");
require_once("Ferrari.php");
require_once("Driver.php");
$lamborghini_diablo = new Lamborghini(1999, "Lamborghini", "Diablo");
$ferrari_f355 = new Ferrari(1996, "Ferrari", "F355");
$dino = new Driver( $ferrari_f355 );
$dino->drive();
$harrison = new Driver( $lamborghini_diablo );
$harrison->drive();
是时候进行彻底的代码遍历了。
- PHP 进入测试类,需要
Lamborghini
, Ferrari
, 和Driver
类。 - 实例化了一个新
Lamborghini
对象,其类型为Car
。 - 由于
Lamborghini
该类不包含构造函数,因此调用父构造函数并将三个参数传递给父构造函数:1999
, Lamborghini
, Diablo
。 - 实例化了一个新
Ferrari
对象,它也是 类型Car
。 - 由于
Ferrari
该类不包含构造函数,因此调用父构造函数并将三个参数传递给父构造函数:1996
, Ferrari
, F355
。 - 创建一个新对象
Driver
并将该$ferrari_f355
对象作为参数传递给构造函数。 - 该类使用刚传递给它的对象
Driver
初始化了$car
自身内部的属性。$ferrari_f355
该$car
属性现在可以访问 中的所有方法$ferrari_f355
。 - 该
drive()
方法被调用。 - PHP进入
drive()
方法。它看到它正在调用 3 个不同的方法,所有方法都位于$car
属性内,从技术上讲,这就是$ferrari_355
对象。 - PHP 执行
turnOn()
, drive()
, 和turnOff()
方法。 -
Driver
在测试文件中创建一个新对象,并将该$lamborghini_diablo
对象作为参数传递给构造函数。 - 该类使用刚传递给它的对象
Driver
初始化了$car
自身内部的属性。$lamborghini_diablo
该$car
属性现在可以访问 中的所有方法$lamborghini_diablo
。 - 该
drive()
方法被调用。 - PHP进入
drive()
方法。它看到它正在调用 3 个不同的方法,所有方法都位于$car
属性内,从技术上讲,这就是$lamborghini_diablo
对象。 - PHP 执行
turnOn()
, drive()
, 和turnOff()
方法。
通过构造函数传递参数并将其分配给属性就是所谓的依赖注入。
只要您想象参数如何在代码中移动的流程,我相信您会理解依赖注入。简单主题的复杂名称。
我们将在下一篇文章中解决 Laravel 对依赖注入的使用。
标签:Laravel,Lamborghini,Car,P48,drive,Ferrari,car,PHP,构造函数 From: https://blog.51cto.com/u_1213352/6052074