现在时间比较充沛

 

  

      先是有了这个比较简短但是内容比较丰盈的上篇,现在时间比较充沛,所以详细写来。搞前端的同学经常被其他程序员bs,做的工作简单,且只了解一门js,虽然现在前端确实更胜从前,但依旧有老顽固程序猿bs我们的地位,所以晓得一些其他语言也就显得迫在眉睫了,so文章开始以前我们也来探讨下其他的oop语言,顺便对比下其他oop语言和js的异同,哪怕旨在于了解,我们也是了解了,哈哈,休得鄙视。。。。 mdzz。。。。

 

絮叨

  

  学习js的很多小伙伴都是已经有了其他高级语言的基础,所以开头我们先来说下传统面向对象语言的一些特性,然后我们再来聊js这门 函数式面向对象语言。
  传统面向对象语言有这么三大特性,分别是 封装、继承、多态。何为封装?就是装箱呗,把不为人知的秘密隐藏起来;何为继承?就是子承父业呗,拿来主义坐享其成;何为多态?就是一种事物的多种状态呗,物理中学的固液气是也,其本质就是同一个事物,但其却在不同的情境下可以拥有多重身份,正如某本书中所述:“oop程序的世界是民主制的,封装使得公民拥有了个体身份,继承使得公民拥有了家庭的身份,多态使得公民拥有了社会身份”。
  下面我们先来分析下传统的面向对象语言,为我们以后能更好的学习js铺桥搭路。

 

传统面向对象语言

 

1.封装

  好了,看完生活中的类比,我们来看专业一点的释义,请看如下java伪代码

class Student{

    //封装私有变量
    private int name;   

    //定义一个公有方法
    public void eat(){
        System.out.println("eating....");
    }

    //name属性的专有getter/setter方法
    public int getName(name){
        rerurn this.name;
    }
    public void setName(name){
        this.name=name;
    }
}

 

如上代码所示,在一些高级语言中我们用关键字 class 来描述一个类,而我们最常说的就是封装一个类/一个方法或函数,其他oop语言是封装了一个类,而js铁定就是封装了一个函数呗!那什么叫封装一个类呢?我们可以简单理解为 把属性和方法集合在一起就是封装了类,方法和函数异同,我们知道在最新的ES6中也出现了类似语法糖的class关键字,看了上面的我们可以这样理解: 在我们开发中通常会把属性定义为私有的,因为大家更愿意去用getter/setter方法去访问和修改这个属性,也就是属性通常需要对外隐藏起来,而方法是需要对外公共出来提供服务滴,所以也就是有了private属性和public方法咯。综上所述我们可得如下总结

 

类或者函数可以理解为一个模具,里边封装了无数的方法(函数)和属性(成员、变量、字段)

备注:纵观语言进化史有机器语言,面向过程类型的语言,面向对象类型的语言。
1 在面向过程语言中我们的方法称之为函数,我们的属性称之为成员
2 在面向对象语言中,我们就用方法和属性来称呼这两个事物
而字段是出现在数据库中的概念,这里我们也可以形象的理解为其是对属性的一个别称,而变量在低高级语言中都会出现,其一般用在类和方法外。以上名词是我们在学习中会遇到但又经常混淆乱用的词汇,虽不知道也行,但我觉着还是通晓较好。

 

那么类有什么用呢?答:使用new关键字可以把类变成一个实例对象。比如我们上边定义的这个Student类,怎么变成一个对象呢?Student s = new Student(); 即可,s即为Student的一个实例对象,js也是如此这般生成使用new生成实例,但其内部机制会略显复杂。最后稍作总结,从这里我们可以得出传统面向对象语言是先有类才有实例对象滴,那js呢?

 

2.继承

  继承在其他语言中使用的是extends关键字,当然在es6中这个关键字也被提上了日程,传统的oop语言继承多为单继承,如我们本文要说到的js(特指原型链继承)以及java和oc,当然除c++外。继承其实就是拿来主义,别人有的你若需要直接拿来用即可。js中的继承相较于其他语言实现方式灵活多样,且其他oop语言继承的实现是基于的继承,我们先来看下其他语言的继承,先构造一个Person和Student类,让Student类去继承Person类

//定义一个Person类

class Person{
    //定义一个方法,打印一句话
    public void say(){
        System.out.println("人在say。。。。");
    }
}

继承的实现:

//定义Student类并使用extneds关键字继承Person类

class Student extends Person{
    //定义一个eat方法
    public void eat(){
        System.out.println("eating....");
    }

} 

 

需要注意的是,其他oop语言是在封装类的时候就需要指定继承了,而我们的js却不是这样滴。有了如上的操作当我们再次new Student的时候在Student的实例中就可以使用Say()这个方法了,他是哪里来的?答案,从Person中继承来的,这就是继承的妙处“代码复用”,具体的js继承,在下文我们会说到。

 

3.多态

  多态在js中提到的较为少,甚至有些程序猿就说js中没有多态,非也。首先我们先来找传统oop和js的共同点,大家注意我的书写顺序咯。封装->继承->多态,yes你懂了,他们三个是线性渐进滴,也就是可以理解为有了封装,才有了继承,有了继承才会出现多态咯?对,就要这么理解。。。没有封装一个类,你怎么用类去继承?多态有一句话我一直奉为经典,记住了也就会用了,多态如何体现在代码上呢?父类的引用,子类的实例,那么多态转换到生活中该如何理解尼?答曰:一种事物的多种状态,额!举个栗子,换成其他oop伪代码,多态是这么体现的

//定义一个父类Person
class Person{
    public void who(){
        System.out.println("Person");
    }
}

//定义一个父类Student并且继承Person
class Student extends Person{
    public void who(){
        System.out.println("Student");
    }
} 

//定义一个父类Work并且继承Person
class Work extends Person{
    public void who(){
        System.out.println("Work");
    }
}

分别生成实例对象,多态的代码体现:父类的引用,子类的实例
Person p1 = new Student();
Person p2 = new Work();

p1.who()//输出Student
p2.who()//输出Work

 

代码所示,父类Person和继承Person的子类Student以及Work,这三个类中都有一个who的方法,但输出不同,我们使用子类的构造器(Student和Work)生成父类的对象(p1和p2),最后再调用who这个方法,程序会自动执行分属于p1和p2子类中的相应方法,也就是说方法是父类调用的方法,但是执行者确是子类,顺一下,工人也是人的一种,学生异同,他们是人多种状态下的不同表现,具体功能不同但却都是人,所以多态就是系统在知道你有多种状态的情况下,只要你给一个最大的状态,其就能根据你具体的状态去很好的识别你。

  概念我们先缕到这里,此刻如果我让你写一个js多态的例子,你能写出来码?答案肯定是否定的,但是思路一定是有了,先搞一个函数类,在搞一个继承关系你再和我聊多态吧~哦了,有这个觉悟我觉着咱暂时就够了。