class的本质
class的本质依然是function
class A{
name: string;
constructor(name){
this.name = name;
}
say(){
console.log(`i am ${this.name}`)
}
}
a.say(); // i am abc
console.log(`type of A: `, typeof A) // type of A: function
console.log(`type of a: `, typeof a) // type of a: object
class的作用
个人理解:代码复用,比如继承,实例化
OOP
面向对象(OOP)的特性:A PIE :抽象 多态 继承 封装
封装(Encapsulation)
- 隐藏数据操作细节,只暴露对外接口。
- 外界直接调用接口,但不需要(也不可能)知道细节
继承(Inheritance)
- 子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特性
- 父类:别名 基类,超类
- 子类:别名 派生类
多态(Polymorphism)
- 由继承而产生的不同类,对同一个方法可以有不同的响应。
- 如 Cat 和 Dog 都继承自 Animal,分别实现自己 eat 方法。
- 无需了解是 Cat 还是 Dog,就可直接调用 eat 方法,程序会自动判断该如何执行 eat
例子1: class基本使用
class Greeter {
greeting: string; // 成员变量
constructor(message: string){ // 构造函数
this.greeting = message;
};
sayHi() { // 成员函数
console.log(this.greeting);
}
}
let myGreeter1 = new Greeter('hi, nice to meet you!');
myGreeter1.sayHi(); // hi, nice to meet you!
例子2: class继承
class Animal {
name: string;
constructor(name: string){
this.name = name;
};
move(distance: number){
console.log(`${this.name} moved ${distance} m`);
};
};
class Snake extends Animal {
// 子类执行父类的构造函数
constructor(name: string){
// 注意!! TypeScript强制执行的重要规则
// 子类构造函数必须调用super方法,之后才能正常使用this,
super(name);
};
// 子类重写了父类的move方法
move(distance: number = 5){
console.log('snake slitering...');
super.move(distance);
}
}
let snake1 = new Snake('sk1');
snake1.move(); // snake slitering... sk1 moved 5 m
let snake2: Animal = new Snake('sk2');
snake2.move(100); // snake slitering... sk2 moved 100 m
例子3: 修饰符public protected private
class Plant {
// public 子类和实例都可访问
public nme:string;
// protected 子类可访问,实例不可访问
protected age: number;
// private:子类和实例都不可访问
private region: string;
// protected修饰构造函数,意味着Plant不能被实例化
protected constructor(name:string, age: number, region:string){
this.name = name;
this.age = age;
this.region = region;
}
};
class Bamboo extends Plant {
public color: string;
// public修饰构造函数,意味着Bamboo可以被实例化
public constructor(name: string, age:number, region:string, color: string){
super(name, age, region);
this.color = color;
}
public getInfo(){
console.log(`my name is ${this.name}`);
console.log(`my age is ${this.age}`);
// console.log(`my region is ${this.region}`);// compile error!
}
};
// Plant不可实例化
// let plant1 = new Plant('tree', 2, 'south'); // compile error!
// Bamboo可实例化
let bamboo1 = new Bamboo('boom1', 1, 'north','lightGreen');
// 不可以访问bamboo1.age和bamboo1.region
console.log(`bamboo1.name=${bamboo1.name}, bamboo1.color=${bamboo1.color}`);
// 打印:bamboo1.name=boom1, bamboo1.color=lightGreen
修饰器:限制访问
修饰属性或方法
- public,TypeScript里,成员(包括属性和方法)都默认为 public
- private,只能当前类内部访问, 子类和实例不能访问
- protected,可在当前类和子类内部访问, 实例不能直接访问
修饰构造函数(特殊)
- private ,该类不允许被继承或者实例化
- protected,该类运行被继承,不允许实例化
例子4: readonly修饰符
class Octopus{
// readonly变量初始化(可写):声明时
public readonly enviroment: string;
public readonly legs: number = 8;
public name: string;
public constructor(enviroment:string, name: string, legs: number){
// readonly变量初始化(可写):构造函数
this.enviroment = enviroment;
this.legs = legs;
this.name = name;
}
}
// oct1.enviroment 和 oct1.legs 只能读不能写
// oct1.name 可读可写
let oct1 = new Octopus('water', 'oct1', 10);
console.log(oct1.enviroment, oct1.legs, oct1.name); // water 10 oct1
oct1.name = 'newOct1'
console.log(oct1.enviroment, oct1.legs, oct1.name);// water 10 newOct1
例子5 参数属性
class OriginalAnimal{
private name:string;
public constructor(name: string){
this.name = name;
}
getInfo(){
console.log(`OriginalAnimal: my name is ${this.name}`);
}
}
let myOrigin1 = new OriginalAnimal('kawa');
myOrigin1.getInfo();// OriginalAnimal: my name is kawa
class BetterAnimal{
// 参数属性(修饰词):构造函数的参数中使用修饰词 如public
// ts规定此构造函数和OriginalAnimal构造函数是等价的
constructor(private name:string){};
getInfo(){
console.log(`BetterAnimal: my name is ${this.name}`);
}
}
let myBetter1 = new BetterAnimal('loty');
myBetter1.getInfo(); //BetterAnimal: my name is loty
参数属性的作用?
- 个人理解是ts语法糖
- 使用参数属性,可以把声明和赋值合并到一起
例子6 静态属性
class Movie{
public static goal:string = 'for fun!'; // 静态属性
public constructor(public name:string) { };
public getInfo(){
console.log(`i am movive ${this.name} and my goal is ${Movie.goal}`);
}
};
let myMovie = new Movie('matrix');
// 类的内部方法getInfo访问静态属性
myMovie.getInfo(); // i am movive matrix and my goal is for fun!
// 类的外部直接访问静态属性
console.log(`静态属性Movie.goal: ${Movie.goal}`); // 静态属性Movie.goal: for fun!
静态属性
- static关键字声明
- 属于类,不属于实例
- 可以通过类名.静态属性来访问