// 类,即模板classPeople{constructor(name, age){this.name = name
this.age = age
}eat(){alert(`${this.name} eat something`)}speak(){alert(`My name is ${this.name}, age ${this.age}`)}}
// 父类classPeople{constructor(name, age){this.name = name
this.age = age
}eat(){alert(`${this.name} eat something`)}speak(){alert(`My name is ${this.name}, age ${this.age}`)}}// 子类继承父类classStudentextendsPeople{// extends 继承关键字constructor(name, age, number){super(name, age)// 将name,age传递给父类来执行this.number = number
}study(){alert(`${this.name} study`)}}// 实例let xiaoming =newStudent('xiaoming',10,'A1')
xiaoming.study()
console.log(xiaoming.number)
xiaoming.eat()let xiaohong =newStudent('xiaohong',11,'A2')
xiaohong.study()
xiaohong.speak()
2.4 面向对象–封装
2.4.1 封装的作用
封装,数据的权限和保密
public 完全开放
protected 对子类开放
private 对自己开放
2.4.2 封装的特点
减少耦合,不该外露的不外露
比如weight、girlfriend不想让外人访问,就不外露
如果强行访问,会报错
如果不这样,就要通过文档约束(仅限于人员少、沟通密切、没有恶意的情况下)
一旦人多,比如上百个人员协作,文档不全,沟通不密切的情况下
一旦访问又没有报错,万一出现线上问题就比较麻烦了
利于数据、接口的权限管理
一些安全性的隐私数据进行封装处理
ES6 目前不支持,一般认为_开头的属性是 private
// ES6 尚不支持,可以用 typescript 来演示// 父类classPeople{// typescript 定义属性
name
age
protected weight // 定义 protected 属性,受保护的属性,只有自己或者子类可以访问constructor(name, age){this.name = name
this.age = age
this.weight =120}eat(){alert(`${this.name} eat something`)}speak(){alert(`My name is ${this.name}, age ${this.age}`)}}// 子类classStudentextendsPeople{
number
private girlfriend // 定义 private 属性constructor(name, age, number){super(name, age)this.number = number
this.girlfriend ='xiaoli'}study(){alert(`${this.name} study`)}getWeight(){alert(`weight ${this.weight}`)}}// 实例let xiaoming =newStudent('xiaoming',10,'A1')
xiaoming.getWeight()// console.log(xiaoming.girlfriend) // 注意,编译时会报错,直接会编译不通过!// girlfriend是私有属性,只能在子类内部访问
2.5 面向对象–多态
2.5.1 多态的作用
同一接口不同实现
JS 应用极少
需要结合 java 等语言的接口、重写、重载等功能
2.5.2 多态的特点
保持子类的开放性和灵活性
并不是所有事情都让父类控制好,子类什么都不用做
可以通过把公共的功能抽离出来,放在父类中去继承
这样可以减少代码量,减少冗余,提高复用
但是如果子类中需要进行灵活的处理,还是可以进行修改的
面向接口编程
有时候不用管子类下面是如何实现的
只需要管父类有多少接口,是怎么样的接口
JS 引用极少
classPeople{constructor(name){this.name = name
}saySomething(){}}classAextendsPeople{constructor(name){super(name)}saySomething(){alert('I am A')}}classBextendsPeople{constructor(name){super(name)}saySomething(){alert('I am B')}}let a =newA('a')
a.saySomething()let b =newB('b')
b.saySomething()
2.6 JS 应用举例
jQuery 是一个 class
$('p') 是 jQuery 的一个实例
classjQuery{constructor(selector){// 构造函数let slice =Array.prototype.slice // 获取数组方法let dom =slice.call(document.querySelectorAll(selector))// 获取dom节点let len = dom ? dom.length :0// dom数组的长度for(let i =0; i < len; i++){this.[i]= dom[i]}this.length = len
this.selector = selector ||''}append(node){// ...}addClass(name){// ...}html(data){// ...}// 此处省略若干 API}// 入口
window.$=function(selector){// 工厂模式returnnewjQuery(selector)}// 测试代码var $p =$('p')
console.log($p)
console.log($p.addClass)
classPeople{constructor(name, age){this.name = name
this.age = age
}eat(){alert(`${this.name} eat something`)}speak(){alert(`My name is ${this.name}, age ${this.age}`)}}
类图
3.3 关系
泛化,表示继承
关联,表示引用
classPeople{constructor(name, house){// 在People中引用housethis.name = name
this.house = house
}saySomething(){}}classAextendsPeople{constructor(name, house){super(name, house)}saySomething(){alert('I am A')}}classBextendsPeople{constructor(name, house){super(name, house)}saySomething(){alert('I am B')}}classHouse{constructor(city){this.city = city
}showCity(){alert(`house in ${this.city}`)}}// 测试let aHouse =newHouse('北京')let a =newA('aaa', aHouse)
console.log(a)// a 有房子let b =newB('bbb')
console.log(b)// b 无房子