意义
代码结构化
类和类图
TypeScript
class People {
constructor(protected name: string) {
this.name = name;
}
eat(): void {
console.log(`${this.name}吃饭了`);
}
}
继承
子类 能够使用 父类的 可访问变量 和 方法。
关键字
extents
super
// 父类
class People {
constructor(protected name: string) {
this.name = name;
}
eat(): void {
console.log(`${this.name}吃饭了`);
}
}
// 子类
class Person extends People {
constructor(protected name: string, protected age: number) {
super(name);
this.age = age;
}
who(): number {
console.log(`I am ${this.name}, ${this.age}`);
return this.age
}
}
封装
私有属性只能够通过get 和 set 方法来访问
关键字
public
: 完全开放
protected
:仅对子类开放
private
:仅对本类开放
class People {
constructor(private name: string) {
this.name = name;
}
eat(): void {
console.log(`${this.name}吃饭了`);
}
getName(): string {
return this.name;
}
setName(newName: string) {
this.name = newName;
}
}
let zxy = new People('张学友');
zxy.setName('霍华德');
console.log(zxy.getName()); // 霍华德
多态
1. ts中interface与class的区别
interface:接口只声明成员方法,不做实现。
class:类声明并实现方法。
也就是说:interface只是定义了这个接口会有什么,但是没有告诉你具体是什么。
// 接口的例子
interface Point {
name:number;
age:number;
say():void;
}
2.extends 与 implement
(1)
extends
是继承父类,只要那个类不是声明为final
或者那个类定义为abstract
的就能继承。
( 2 ) TS是但继承,多实现。
implements
可以实现多个接口,用逗号分开就行了。
class A extends B implements C,D,E
class Person extends People implements Eat,Sheep {
something: string;
constructor(protected name: string, protected age: number) {
super(name);
this.age = age;
this.somethingA = '寂寞';
this.somethingB = '寂寞';
}
who(): number {
console.log(`I am ${this.name}, ${this.age}`);
return this.age
}
// 吃的接口
chew(somethingA: string) {
this.somethingA = somethingA;
console.log(`${this.name}吃了${this.somethingA}`);
}
// 睡的接口
bed(somethingB: string) {
this.somethingB = somethingB;
console.log(`${this.name}睡了${this.somethingB}`);
}
}
3.ES6中使用Mixin实现“多重继承”
JavaScript / ES5
的继承模型是基于单一原型链的继承模型.通常情况下,在 JavaScript 实践中完全用原型链来实现继承式的代码复用,是远远不能满足需求的。
因此实战中,我们的代码抽象基本上都是采用混合的模式,既有原型继承,也有 mixin 组合。
在 ES6 中,我们可以采用全新的基于类继承的 “mixin” 模式设计更优雅的“语义化”接口,这是因为 ES6 中的 extends 可以继承动态构造的类,这一点和其他的静态声明类的编程语言不同。
const Serializable = Sup => class extends Sup {
constructor(...args){
super(...args);
if(typeof this.constructor.stringify !== "function"){
throw new ReferenceError("Please define stringify method to the Class!");
}
if(typeof this.constructor.parse !== "function"){
throw new ReferenceError("Please define parse method to the Class!");
}
}
toString(){
return this.constructor.stringify(this);
}
}
class Person {
constructor(name, age, gender){
Object.assign(this, {name, age, gender});
}
}
class Employee extends Serializable(Person){
constructor(name, age, gender, level, salary){
super(name, age, gender);
this.level = level;
this.salary = salary;
}
static stringify(employee){
let {name, age, gender, level, salary} = employee;
return JSON.stringify({name, age, gender, level, salary});
}
static parse(str){
let {name, age, gender, level, salary} = JSON.parse(str);
return new Employee(name, age, gender, level, salary);
}
}
let employee = new Employee("jane",25,"f",1,1000);
let employee2 = Employee.parse(employee+""); //通过序列化反序列化复制对象
console.log(employee2,
employee2 instanceof Employee, //true
employee2 instanceof Person, //true
employee == employee2); //false
在上面的代码里,我们改变了 Serializable,让它成为一个动态返回类型的函数,然后我们通过 class Employ extends Serializable(Person) 来实现可序列化,在这里我们没有可序列化 Person 本身,而将 Serializable 在语义上变成一种修饰,即 Employee 是一种可序列化的 Person。
实际应用
Jquery
class jQuery {
constructor(selector) {
let slice = Array.prototype.slice;
let dom = slice.call(document.querySelectorAll(selector));
let len = dom ? dom.length : 0;
for (let i = 0; i < len; i++) {
this[i] = dom[i];
};
this.length = len;
this.selector = selector || '';
}
who() {
console.log(this.dom);
}
}
window.$ = function (selector) {
// 工厂模式
return new jQuery(selector);
}
var $p = $('p')
console.log($p);
console.log($p.who);