ES6 OO

编程思想

面向过程编程(POP, Process Oriented Programming)

面向过程是分析出解决问题所需的步骤,然后使用函数将步骤一步步实现,使用时再一个个依次调用即可。

例如:使用面向过程的方式将一个大象装进冰箱

面向过程

面向对象编程(OOP, Object Oriented Programming)

面向对象是将事务分解为一个个对象,然后由对象之间分工合作完成任务。面向对象是以对象的功能来划分问题而非步骤。

例如:使用面向对象的方式将大象装进冰箱

首先需要找出对象,并分析出对象的功能。

对象:大象
功能:进入冰箱

对象:冰箱
功能:打开冰箱、关闭冰箱

对象:调度器
功能:使用大象和冰箱对象的功能,完成大象装入冰箱。

在面向对象程序开发思想中,每个对象都是功能的中心,具有明确地分工。面向对象编程具有灵活、代码可复用、容易维护和开发的优点,更加适合多人合作的大型软件项目。

面向对象的特性

  • 封装性
  • 继承性
  • 多态性
面向对象特性

面向过程与面向对象优缺点对比

  1. 面向过程
  • 优点:性能比面向对象高,适合跟硬件联系很紧密的应用场景,比如单片机就是采用面向过程编程。
  • 缺点:没有面向对象易维护、易复用、易扩展
  1. 面向对象
  • 优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态的特性,因此可以设计出低耦合的系统,使系统更加灵活且更易于维护。
  • 缺点:性能比面向过程低

通俗来讲,使用面向过程编写的程序类似一份蛋炒饭,而使用面向对象编写的程序则类似于一份盖浇饭。

类和对象

面向对象

面向对象更加贴近于现实生活,可以使用面向对象描述现实世界中的事物,事物也可以分为具体的事物和抽象的事物。

例如:手机这个概念是一个抽象的、泛指的。而你手中的那部iPhone4S则是一个具体的、特指的手机。

面向对象的思维特点

  • 抽取/抽象:对象公用的属性和行为组织(封装)成为一个类或模板
  • 对类进行实例化,获取类的对象。

面向对象编程考虑的是有哪些对象,按照面向对象的思维特点,不断地创建对象,使用对象,指挥对象做事情。

对象

现实生活中,万物皆对象,对象是一个具体事物,看得见摸得着。比如一本书、一辆车、一个人,可以是对象。一个数据库、一张网页、一个与远程服务器的连接也可以是对象。

在JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象。比如字符串、数值、数组、函数等。

对象是由属性和方法构成的

  • 属性是指事物的特征,在对象中使用属性来表示,常使用名词。
  • 方法是指事物的行为,在对象中使用方法来表示,常使用动词。

ES6中新增了类class的概念,可以使用class关键字声明类,之后可以使用这个类进行实例化对象。

类是抽象了对象的公共部分,是泛指的某一大类。对象是特指的某一个,通过类实例化出一个具体的对象。

创建类

// 创建类
class ClassName{
  // class body
}
// 创建实例
const obj = new ClassName();

类必须使用new实例化对象

构造函数

类的构造函数constructor()是类的默认方法,用于传递参数并返回实例对象,通过new命令生成对象实例时会自动调用该方法。如果类没有显式地定义,类的内部会自动创建一个构造函数。

//定义类
class User{
    //构造函数
    constructor(id, name){
        this.id = id;
        this.name = name;
    }
}
//实例对象
const user = new User(1, "alice");
console.log(user.id, user.name);//1 "alice"

注意事项

  • 通过class关键字创建类,类名习惯性首字母大写。
  • 类中具有constructor构造函数,可以接收传递进来的参数,同时会返回实例对象。
  • 构造函数constructor只要使用new生成实例对象时,就会自动被调用。若不编写构造函数类会自动生成默认的构造函数。
  • 生成对象实例时new不能够省略
  • 创建类时类名后面不要添加小括号,生成对象实例时类名后面需添加小括号,构造函数无需添加function

成员方法

  • 类中函数不需要添加function
  • 类中函数之间无需添加逗号分隔
//定义类
class User{
    //构造函数
    constructor(id, name){
        this.id = id;
        this.name = name;
    }
    //成员方法
    print(type){
        if(type == "error"){
            console.error(type, this.id, this.name);
        }else if(type == "info"){
            console.info(type, this.id, this.name);
        }else{
            console.log(type, this.id, this.name);
        }
    }
}
//实例对象
const user = new User(1, "alice");
user.print("info");

继承

现实中的继承,典型的比如子承父业,儿女一般都会继承父母的姓氏。

面向对象中类的继承extends指的是子类可以继承父类的某些属性和方法。

//定义父类
class Player{
    //构造函数
    constructor(aid, uname){
        this.aid = aid;
        this.uname = uname;
    }
    //成员方法
    print(){
        console.log(this.aid, this.uname);
    }
}
//定义子类
class ClubMember extends Player{
    constructor(cmid){
        //todo 根据ClubMember的cmid获取Player的id和uname
        const aid = 1;
        const uname = "alice";
        super(aid, uname);
    }
}
//实例化子类对象
let cm = new ClubMember(100);
//子类调用父类方法
cm.print();

使用super关键字,用于访问和调用父类上的函数,可以用来调用父类的构造函数,也可以调用父类的普通函数。

继承中属性或方法的查找原则:就近原则

继承中如果实例化子类输出一个方法,若子类存在则向执行子类。若子类不存在但父类存在则执行父类中的方法。

子类构造函数中使用super时必须放到this之前,也就是说必须先调用父类的构造方法,然后才能使用子类自己的构造方法。

//定义父类
class Player{
    //构造函数
    constructor(aid, uname){
        this.aid = aid;
        this.uname = uname;
    }
    //成员方法
    print(){
        console.log(this.aid, this.uname);
    }
}
//定义子类
class ClubMember extends Player{
    constructor(cmid){
        //todo 根据ClubMember的cmid获取Player的id和uname
        const aid = 1;
        const uname = "alice";
        //子类中的super必须在this之前调用
        super(aid, uname);
        //需要在super后执行
        this.cmid = cmid;
        this.aid = aid;
        this.uname = uname;
    }
    print(){
        //子类调用父类方法
        super.print();

        console.log(this.cmid);
    }
    getInfo(){
        //todo 根据cmid获取ClubMember信息
        console.log(this.cmid, this.aid, this.uname);
    }
}
//实例化子类对象
let cm = new ClubMember(100);
//子类调用父类方法
cm.print();//100
//子类调用自己的方法
cm.getInfo();//100 1 "alice"

你可能感兴趣的:(ES6 OO)