参考链接:js:面向对象编程,带你认识封装、继承和多态 & 浅谈面向对象——多态
面向对象的优点
- 减少重复
- 易于维护
- 方便拓展
面向对象和面向过程的区别
- 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
- 面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
具体的实现我们看一下最经典的“把大象放冰箱”这个问题
面向过程的解决方法:
- 开门(冰箱)
- 装进(冰箱,大象)
- 关门(冰箱)
面向对象的解决方法:
- 冰箱.开门()
- 冰箱.装进(大象)
- 冰箱.关门()
面向对象有三大特性:封装、继承、多态
封装
var Book = function (id, name, price) {
//private(在函数内部定义,函数外部访问不到,实例化之后实例化的对象访问不到)
var num = 1;
var id = id;
function checkId() {
console.log('private')
}
//protected(可以访问到函数内部的私有属性和私有方法,在实例化之后就可以对实例化的类进行初始化拿到函数的私有属性)
this.getName = function () {
console.log(id)
}
this.getPrice = function () {
console.log(price)
}
//public(实例化的之后,实例化的对象就可以访问到了~)
this.name = name;
this.copy = function () {
console.log('this is public')
}
}
//在Book的原型上添加的方法实例化之后可以被实例化对象继承
Book.prototype.proFunction = function () {
console.log('this is proFunction')
}
//在函数外部通过.语法创建的属性和方法,只能通过该类访问,实例化对象访问不到
Book.setTime = function () {
console.log('this is new time')
}
var book1 = new Book('1129','环游世界','$99');
book1.getName(); //1129 getName是protected,可以访问到类的私有属性,所以实例化之后也可以访问到函数的私有属性
book1.checkId(); //报错book1.checkId is not a function
console.log(book1.id); //undefined id是在函数内部通过定义的,是私有属性,所以实例化对象访问不到
console.log(book1.name); //环游世界 是通过this创建的,所以在实例化的时候会在book1中复制一遍name属性,所以可以访问到
book1.copy(); //this is public
book1.proFunction(); //this is proFunction
Book.setTime(); //this is new time
book1.setTime(); //报错book1.setTime is not a function
继承
// 父类
function Plane(color, country) {
this.color = color;
this.country = country;
}
Plane.prototype.fly = function () {
console.log("fly");
}
// 子类
function Fighter(color, country, num) {
Plane.call(this, color, country); // 继承属性
this.bullet = num;
}
inheritPrototype(Fighter, Plane); // 继承方法
Fighter.prototype.shoot = function () {
console.log("shoot");
}
// 继承函数
function inheritPrototype(child, parent) {
var p = Object.create(parent.prototype);
p.constructor = child;
child.prototype = p;
}
// 输出
let fighter01 = new Fighter("red", "china", 99);
console.dir(fighter01);
console.log(fighter01.bullet);
fighter01.shoot();
fighter01.fly();
多态
程序员在敲代码,球员在打球
<?php
abstract class Professional
{
abstract public function play();
}
class Coder extends Professional
{
public function play()
{
print_r("程序员在敲代码!<br/>");
}
}
class Player extends Professional
{
public function play()
{
print_r("球员在打球!<br/>");
}
}
class Run
{
private $profess;
public function __construct($profess)
{
$this->profess = $profess;
}
public function play()
{
if ($this->profess instanceof Professional) {
$this->profess->play();
}
}
}
$coder = new Run(new Coder);
$coder->play();
$player = new Run(new Player);
$player->play();
上面的代码就是多态实现,是不是有点像策略模式;这样的好处就是再有这样的职业人添加进来只需要继承职业人类就可以实现相关的行为
不同行为不可使用多态
比如程序员在吃饭、球员在玩游戏,这两种行为抽象不出来他们的相同点,不能勉强进行多态化