介绍

你好。是正吉。

PHP 中面向对象的三个主要元素。
三者是封装、继承和多态。

对于那些不知道的人,我认为这是一个笑话。
要理解这些,我觉得从 PHP 类中学习还是不错的。

所以,首先,为了理解PHP类,我会通过Pokemon写一个实现例子。

有各种类型的口袋妖怪。
起初有151种动物,现在有900多种。

这不是我记得很清楚的事情。

好吧,突然之间,假设您是 Pokemon 开发人员。

必须编写编程代码来代表 900 多种不同的神奇宝贝。
在这种情况下,可以通过为每只动物编写单独的程序代码来实现。

但是,使用该方法,如果再次发布新的口袋妖怪,您必须以相同的方式添加新口袋妖怪数量的代码。

这就是类的想法派上用场的地方。

在一个类中,您可以共同定义每个 Pokemon 共有的信息。
如果把每个班级的共同信息放在一起,即使出现了新的口袋妖怪,也可以重复使用代码,所以应该可以减少很多工作量。

让我们仔细看看类。

类有哪些共同信息?

我写道,类可以共同定义口袋妖怪共有的信息。

它们共有的信息可以分为两种。

属性和方法。

属性是口袋妖怪的特征和特征,例如它的名称、类型和重量。

接下来,方法是口袋妖怪可以做的事情,例如攻击、进化和发出声音。

如果你制作一个口袋妖怪类表,它看起来像下面这样。

班级 宝可梦
财产 名称、类型、重量
方法 攻击、进化、哭泣

另外,如果你还不明白也没关系,但是如果你使用这个类来制作一个 Charmander,它会是这样的:

班级 宝可梦
财产 Charmander,火型,8.5kg
方法 日野子进化成蜥蜴,影影

有了这种感觉,你就可以预先定义口袋妖怪在课堂上共有的信息。

尝试对目前的内容进行编码

让我们编写到目前为止的代码。
上表中有多个属性和方法,但为了简化代码,属性只是名称。进化是唯一的方法。

口袋妖怪.php
<?php
class Pokemon
{
  //名前プロパティ
  private $name;

  //進化メソッド
  public function evolve($evolvedName)
  {
    echo "おめでとう!".$this->name."は".$evolvedName."に進化した!";
  }
}

如何定义一个类

首先,可以通过用class クラス名 定义一个类并用{} 括起来来创建一个类。
我们将在这个类中编写属性和方法。

口袋妖怪.php
<?php
class Pokemon {}

财产

下面是部分。

口袋妖怪.php
//名前プロパティ
private $name;

属性实际上只是一个变量。稍后,您可以通过将值存储在此变量中来表示名称。

此外,该属性前还有一个描述private。如果加上这个,只能在类内操作和调用。

在这里,如果您至少了解“呵呵”就可以了。
以后一旦了解了封装的概念,就会明白。

方法

下面是部分。

口袋妖怪.php
//進化メソッド
public function evolve($evolvedName)
{
  echo "おめでとう!".$this->name."は".$evolvedName."に進化した!";
}

方法实际上只是一个函数。
在示例中,调用该方法会回显文本“恭喜!X 已演变为 X!”

所以,假设前面提到的$name 属性包含“Charmander”。然后,如果你以“蜥蜴”作为参数调用evolve 方法,它将显示“恭喜!Charmander 已进化成蜥蜴!”

另外,在方法之前有一个描述public。有了这个,您可以从类外部调用该函数并使用它。

另外,在$name 之前还有$this,代表它自己的类。

实例〜尝试从课堂上制作Charmander〜

至此,我能够为 Pokemon 类创建一个模板。
现在让我们从 Pokemon 类实际创建一个 Charmander 对象。

顺便说一句,从 Pokemon 类(在本例中为 Charmander)创建的对象称为实例。

创建一个实例

要创建实例,请编写:

索引.php
require_once('./Pokemon.php');

$hitokage = new Pokemon('ヒトカゲ');

首先,使用php的require_once()加载文件以使用创建的Pokemon类。
要从该类创建一个实例,您可以使用new クラス名() 来完成。

将创建的实例存储在$hitokage 变量中。

现在,这里还有一个问题。
我们将参数“Charmander”传递给类。

为了在类中接收这个参数,我们需要定义一个叫做构造函数的东西。

构造函数 ~ 在 $name 属性中存储 "Charmander" ~

构造函数是创建实例时执行的第一个函数。

在类中,如果你这样写,它就变成了一个构造函数。

口袋妖怪.php
function __construct(){}

构造函数不仅首先执行,而且还具有接收从实例传递过来的值作为参数的能力。

换句话说,如果您将new Pokemo('ヒトカゲ') 的名称“Charmander”写成如下所示,您可以将其作为参数接收。

口袋妖怪.php
  function __construct($name)
  {
    echo $name;
    // >> ヒトカゲ
  }

现在我们已经收到了名称,让我们将值存储在$name 属性中。
请执行下列操作:

口袋妖怪.php
  function __construct($name)
  {
    $this->name = $name;
  }

$this 代表了它自己的一个类。通过将构造函数接收到的“charmander”存储在自己类的$name属性中,$name属性值变成了“charmander”。

从您的实例访问进化方法以进化 Charmander

到目前为止,我们已经创建了一个 Pokemon 类并将其实例化以创建 Charmander。

接下来,让我们尝试通过访问类中定义的进化方法来进化 Charmander。

另外,进化方法是以下功能。

口袋妖怪.php
//進化メソッド
public function evolve($evolvedName)
{
  echo "おめでとう!".$this->name."は".$evolvedName."に進化した!";
}

要从实例访问方法:

索引.php
<?php
require_once('./pokemon.php');

$hitokage = new Pokemon('ヒトカゲ');
echo $hitokage->evolve("リザード");//追記

这将导致以下输出:

おめでとう!ヒトカゲはリザードに進化した!

我能够安全地进化。恭喜。

充分利用物件三大元素打造皮卡丘

现在,最后,说到重点。 (很长……)

如开头所述,面向对象中有一个概念叫做三大要素。
它们是封装、继承和多态。

所以,我个人认为,理解了三大要素,我们就能站在面向对象的入口。

封装

首先,我们来谈谈“封装”。

当您想到胶囊时,您可能会想到发出咔哒声的东西,但在计算机编程中使用时,它代表“内部隐藏”。

换句话说,它隐藏了对象的内容,好处之一是可以限制从外部访问对象的属性和方法的内部元素。

在这里,我希望您记住,当您创建 Pokemon 类时,您在定义 $name 属性时添加了 private 修饰符。

口袋妖怪.php
//名前プロパティ
private $name;

如果加上这个,就只能在类内操作和调用了,但是为什么需要这样的东西呢?

让我们实际将private 更改为public
还要添加一个表示类型的$type 属性。

口袋妖怪.php
//名前プロパティ
public $name;
//追加
private $type;

然后创建一个 Charmander 的实例。

索引.php
$hitokage = new Pokemon('ヒトカゲ','ほのお');

“火焰型”“Charmander”已经完成。

然而这里有个坏人把名字改成了“皮卡丘”。
然后...

索引.php
$hitokage->name = 'ピカチュウ';
echo '名前は'.$hitokage->name.'です。';
//>> 名前はピカチュウです。

我的名字最终是皮卡丘,我最终得到了一个“火系”皮卡丘。
游戏是完全错误的。

这样,处理对象的安全方法是使用封装来限制来自外部的访问并防止意外更改内容。

看来封装还有其他好处,有兴趣的可以看看。

遗产

继承是一种机制,允许您通过接管已经准备好的类的信息来创建另一个类。
定义如下。

class 新クラス extends 元クラス { }

实际上,我会继承 Pokemon 类,并尝试创建一个专用于皮卡丘的类。

皮卡丘。 php
class Pikachu extends Pokemon{}

现在我们有了一个继承自 Pokemon 类的 Pikachu 类。

接下来,让我们只为 Pikachu 类添加一个新方法。

皮卡丘在世界各地都非常受欢迎,所以我们会让您冲浪以获得粉丝服务。

皮卡丘。 php
  public function naminori()
  {
    echo 'なみのり'.$this->name;
  }

我正在尝试访问 $this->name 以使用 Pokemon 类的 $name 属性,但这会导致错误。
这是因为带有private 的那些不会被继承。

要使属性可用于继承的类,请使用protected 属性,如下所示。

口袋妖怪.php
protected $name;

继承目的地的不同取决于修饰符的类型,如下所示。

  • 公共:可继承
  • 私有:不可继承
  • 受保护:可继承。它可以从继承的类中引用,但不能从外部引用。

现在,让我们调用实际添加的方法。

索引.php
$pikachu = new Pikachu('ピカチュウ');
$pikachu->naminori();
// >> なみのりピカチュウ

我安全地做到了。

多态性

最后,还有多态性。

多态性意味着相同的方法在不同的对象上表现不同。

我认为通过实际示例更容易理解。

皮卡丘类,继承自Pokemon类,可以使用Pokemon类中定义的进化方法。

口袋妖怪.php
//進化
public function evolve($evolvedName)
{
    echo "おめでとう!".$this->name."は".$evolvedName."に進化した!";
}

不过,皮卡丘进化需要“闪电石”。
因此,在皮卡丘类中,我们将定义一种新的进化方法,需要进化石作为进化的条件。

皮卡丘。 php
  //進化
public function evolve($evolvedName,$stone = null)
{
  if(!$stone){
      echo '進化するには、進化の石が必要です';
  }else{
      echo "おめでとう!".$this->name."は".$evolvedName."に進化した!";
  }
}

然后添加一个接口。
接口允许您显式指定类应实现的方法。

口袋妖怪.php
interface IPokemon{
  public function evolve($evolvedName);
}

可以使用实现在每个类中实现接口。
通过这样做,我能够明确指定 Pokemon 和 Pikachu 类都需要一个 Evolution 方法。

口袋妖怪.php
class Pokemon implements IPokemon{}
皮卡丘。 php
class Pikachu extends Pokemon implements IPokemon{}

现在,让我们尝试使用皮卡丘类的实例进行进化。
除非您将进化石作为第二个参数传递,否则您将无法再进化。

索引.php
$pikachu->evolve('ライチュウ');
//  >> 進化するには、進化の石が必要です
$pikachu->evolve('ライチュウ','かみなりのいし');
//  >> おめでとう!ピカチュウはライチュウに進化した!

实现示例代码

最后是所有的实现代码。

索引.php
<?php
require_once('./Pokemon.php');
require_once('./Pikachu.php');
$hitokage = new Pokemon('ヒトカゲ');
echo $hitokage->evolve("リザード");
echo "<br>";
$pikachu = new Pikachu('ピカチュウ');
$pikachu->naminori();
echo "<br>";
$pikachu->evolve('ライチュウ');
echo "<br>";
$pikachu->evolve('ライチュウ','かみなりのいし');
口袋妖怪.php
<?php

interface IPokemon{
  public function evolve($evolvedName);
}

class Pokemon implements IPokemon
{
  //プロパティ
  protected $name;

  function __construct($name)
  {
    $this->name = $name;
  }

  //進化
  public function evolve($evolvedName)
  {
    echo "おめでとう!".$this->name."は".$evolvedName."に進化した!";
  }
}
皮卡丘。 php
<?php
require_once('./Pokemon.php');

class Pikachu extends Pokemon implements IPokemon
{
  public function naminori()
  {
    echo 'なみのり'.$this->name;
  }

  //進化
  public function evolve($evolvedName,$stone = null)
  {
    if(!$stone){
      echo '進化するには、進化の石が必要です';
    }else{
      echo "おめでとう!".$this->name."は".$evolvedName."に進化した!";
    }
  }
}

概括

面向对象和类语法很深。我想谈谈 getter、setter 和其他东西,但现在就这些了。
如果您发现任何错误,请发表评论或请求请求。谢谢你。

参考


原创声明:本文系作者授权爱码网发表,未经许可,不得转载;

原文地址:https://www.likecs.com/show-308622832.html

相关文章: