写点什么

不一样的面向对象(一)

用户头像
书旅
关注
发布于: 2020 年 09 月 24 日
不一样的面向对象(一)

面向对象三大特性

封装

把客观的事物封装成抽象的类,类可以通过访问控制将自己的属性给暴露出去或隐藏起来。让自己信任的类或对象使用自己的暴露出去的属性,对自己不信任的类或对象隐藏自己的属性

这样就做的目的其实就是为了使对象本身和对象的使用者分开,使用者只需要知道这个对象能够做什么就行了,不用知道它怎么实现的,这样可以保证类的安全性

举个不是很恰当的例子,假设我这有一个百里守约的类,属性有:血量、枪、攻击范围、等级,方法有:插眼、狙击、向后跳并狙击

<?php
class BaiLi
{
public $blood; //血量
public $gun;//枪
public $attackRange;//攻击范围
public $level;//等级
//设置等级
private function setLevel($level)
{
$this->level = $level;
}
//插眼
public function pushVision()
{
echo "Push a Vision";
}
//狙击
public function sniper()
{
echo "Shot a Shot";
}
//向后跳跃并狙击
public function jumpAndSniper()
{
echo "Jump And Shot";
}
}

当玩家选择了百里守约,就可以看做创建了一个百里守约类的对象。该对象就具备了该类封装的这些成员属性和方法,玩家只能看到和使用它对外提供的一些属性和方法,比如血量、插眼等,但是像设置等级,对玩家是不可见的。同时,玩家只需要知道百里守约有哪些属性和技能,不用关注它是怎么实现的

继承

继承机制可以创建多个层次的类,子类继承父类的属性和方法,使得子类对象也同时具备了父类对象的属性和方法。通常用来对公共属性或方法进行抽离

拿王者荣耀里边的英雄来举例,看图

当我们去封装王者荣耀里边每一个英雄的时候,会发现一些英雄都有公共的属性,比如百里、蒙犽这类英雄都能进行远程攻击,所以将这类英雄公共属性和方法提取出来,封装成一个底层的类,叫射手类。同样像廉颇、盾山这类血量比较厚的英雄,可以封装一个底层的类叫坦克类等

封装射手类、法师类、坦克类的时候,发现它们还会有一些公共的属性,比如都能进行移动、攻击等,同样可以抽出来封装成一个更加底层的类,也就是英雄类

假设王者荣耀新加了英雄叫属驴,是一个射手,首先它会有一些自己特有的属性和技能,然后这个英雄会继承它的父类射手类,此时这个英雄就拥有了远程攻击这些技能,然后射手类又会继承英雄类,那么这个新英雄就具备了移动、攻击这类属性。此时,一个完整的新英雄就被创建出来了(几个亿到手)

多态

多态其实可以简单的理解成“一个对外接口,多种内部实现”。它的专业定义是:同一个操作作用于不同的类的实例,将产生不同的执行结果。即不同类的对象收到相同的消息时,将得到不同的结果。上边的描述还是很抽象,看例子

在实际开发中,我们通常要写出通用的代码,做出通用的编程,以适应需求的不断变化

还是以王者荣耀来举例,假设下边有各种射手的类,它们都有射击的方法

<?php
class BailiShooter //百里守约
{
public function bailiShot()
{
echo "百里射击".PHP_EOL;
}
}
class mengYaShooter //蒙犽
{
public function mengYaShot()
{
echo "蒙犽射击".PHP_EOL;
}
}
function operateShot($obj = null)//处理射击的方法
{
if ($obj instanceof BailiShooter) {
$obj->bailiShot();
} elseif ($obj instanceof mengYaShooter) {
$obj->mengYaShot();
} else {
echo "操作错误";
}
}
operateShot(new BailiShooter());
operateShot(new mengYaShooter());
输出:
百里射击
蒙犽射击

上边定义了两个射手类:蒙犽和百里。然后下边有一个处理射击的方法,判断传入的是哪个射手要射击,然后调用相应的射击方法

可以看出,如果有新的射手进行射击操作的时候,需要首先定义具体射手的类,然后实现一个射击的方法,再在处理射击的方法中增加一个判断。这种扩展性是很差的,如果使用多态就能很好的解决这个问题

首先可以创建一个射手的父类,在父类中定义一个射击的方法,所有是射手属性的英雄都继承这个父类(同时会继承该父类的所有属性和方法),每个子类都可以对父类的射击方法进行各自的实现

<?php
class Shooter //射手
{
public function shot(){
echo "射击方法要在所有子类中进行重载";
}
}
class BailiShooter extends Shooter //百里守约
{
public function shot()
{
echo "百里射击".PHP_EOL;
}
}
class mengYaShooter extends Shooter //蒙犽
{
public function shot()
{
echo "蒙犽射击".PHP_EOL;
}
}
function operateShot($obj = null)//处理射击的方法
{
if ($obj instanceof Shooter) {
$obj->shot();
} else {
echo "操作错误";
}
}
operateShot(new BailiShooter());
operateShot(new mengYaShooter());
输出:
百里射击
蒙犽射击

此时就可以进行轻松的扩展了,只需要继承射手类,并对射击方法进行重载就可以实现自己的射击方法





发布于: 2020 年 09 月 24 日阅读数: 37
用户头像

书旅

关注

公众号:IT猿圈 2019.04.11 加入

还未添加个人简介

评论

发布
暂无评论
不一样的面向对象(一)