OOP 是指面向对象编程,是一种编程风格,以类作为组织代码的基本单元。能让代码更具有可维护性、可复用性、可扩展性。有三大特性:封装、继承和多态。
一、 封装
- 是什么:把属性封装好,仅通过有限的函数暴露必要的操作。
- 为了解决什么:为了防止数据被随意修改,造成属性不可控, 影响代码可维护性和可读性。
- 怎么使用: 通过类提供的函数访问操作内部属性。
需要访问权限控制支持:private(私有)、proteced(受保护)、 public(公有,默认关键字)。
class Person
{
private $name; // $name: 私有属性 (只能是自身类访问)
protected $age; // $age: 受保护属性 (只能是自身类和其父类和子类访问)
public $sex; // $sex: 公有属性 (任何地方都可访问)
public function __construct($name, $age, $sex)
{
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
return $this->name = $name;
}
public function getAge()
{
return $this->age;
}
}
$Person = new Person('gnahz', 22, '男');
echo $Person->getName() ."\n"; // 输出: gnahz (通过 Person 类提供的 getName 方法获取 name)
echo $Person->setName('zhang') ."\n"; // 输出: zhang (如若要修改 name, 可通过类提供的 setName 方法)
echo $Person->getAge() ."\n"; // 输出: 22
// echo $Person->name; // 不能就这样访问私有属性会报错: Cannot access private property Person::$name
echo $Person->sex ."\n"; // 输出: 男 (公有属性能被直接访问或随意修改)
echo $Person->sex = '女'; // 输出: 女 (也就没法达到隐藏信息和保护数据的作用)
二、 继承
- 是什么:类之间 is-a 关系 (比如: 猫是哺乳动物), 继承可分为单继承和多继承 (比如:猫即是哺乳动物,也是爬行动物)。
单继承(一个子类只能继承一个父类):Java,PHP
多继承(一个子类能继承多个父类):Python,C++
- 为了解决什么:为了能代码复用,假设两个类有一些相同的函数和属性, 就可抽取出去做个父类类继承使用,避免代码重复。
组合
也能实现。 如果继承层次过深、继承关系过于复杂会影响代码可读性和可维护性,这时使用组合
更好。
- 怎么使用:extends(Java、PHP)
class Animal
{
public function run()
{
echo "I can run \n";
}
}
// 猫类 继承 动物类
class Cat extends Animal
{}
Animal::run(); // I can run
Cat::run(); // I can run
三、多态
- 是什么:类在不同情况下的多种状态,即同一个类的不同子类,在调用同一方法可以有不同操作。
- 为了解决什么:提高代码的扩展性和复用性,是很多设计模式、设计原则、编程技巧的代码实现基础。
// 接口实现多态方式
// 定义一个 USB 设备接口
interface USB
{
function run();
}
// 定义一个电脑类,启动 USB 设备作用
class Computer
{
function useUSB($usb)
{
$usb->run();
}
}
// 扩展一个 usb 键盘设置,实现 USB 接口
class UsbKeyboard implements USB
{
function run()
{
echo "UsbKeyboard is running \n";
}
}
// 扩展一个 usb 鼠标设置,实现 USB 接口
class UsbMouse implements USB
{
function run()
{
echo "UsbMouse is running \n";
}
}
$computer = new Computer();
$computer->useUSB(new UsbKeyboard()); // UsbKeyboard is running
$computer->useUSB(new UsbMouse()); // UsbMouse is running
// 抽象实现多态方式
class Teacher
{
public function drawPolygon(Polygon $polygon)
{
$polygon->draw();
}
}
// 定义一个能画多边形的抽象类
abstract class Polygon
{
abstract protected function draw();
}
// 继承多边形抽象类画个长方形
class Rectangle extends Polygon
{
public function draw()
{
echo "draw a Rectangle \n";
}
}
// 继承多边形抽象类画个正方形
class Square extends Polygon
{
public function draw()
{
echo 'draw a Square';
}
}
$teacher = new Teacher();
$teacher->drawPolygon(new Rectangle()); // draw a Rectangle
$teacher->drawPolygon(new Square()); // draw a Square