TypeScript 是面向对象的 JavaScript。类描述了所创建的对象共同的属性和方法。
TypeScript 支持面向对象的所有特性,比如 类、抽象类、接口等。
一、定义类
class 类名 {
属性名: 类型;
// 静态属性
static 属性名:类型;
// 只读属性,针对成员属性
//readonly设置后,可以直接赋值或在构造函数中赋值是不会报错的
readonly 属性名:类型 = 值;
// 构造方法
constructor(参数: 类型){
this.属性名 = 参数;
}
// 实例方法
方法名(){
....
}
}
TS中属性具有三种修饰符
- public(默认值),共有的,可以在类、子类和对象中修改
- protected 受保护的,可以在类、子类中访问,类外不能访问到
- private 私有的,只能在该类中修改
二、属性存取器
对于一些不希望被任意修改的属性,可以将其设置为 private ,直接将其设置为 private 将导致无法再通过对象修改其中的属性,我们可以在类中定义一组读取、设置属性的方法,这种对属性读取或设置的属性被称为属性的存取器。
class Myclass {
private _name: string
constructor(public id: number, name: string) {
this._name = name
}
//获取器
get name() {
return this.id > 10 ? this._name : '****'
}
//修改器
set name(name: string) {
this._name = name
}
}
let c = new Myclass(8,'lisi');
console.log(c.name);
console.log(c.id);
三、继承
通过继承可以将其他类中的属性和方法引入到当前类中。
语法:
class A {}
class B extends B {}
class Parent{
constructor(public name:string){
}
}
class Child extends Parent{
constructor(public id:number,name:string){
super(name)
}
}
let c = new Child(10,'zhangsan');
console.log(c.id);
console.log(c.name);
四、抽象类
抽象类是专门用来被其他类所继承的类,它只能被其他类所继承不能用来创建实例。
抽象类 abstract class ,一般用来给类中的方法定义规范。
抽象类中可以没有抽象方法,抽象方法如果存在,则继承的子类中一定要去实现,否则编译报错。
type userType = { id: number, name?: string }
abstract class Parent {
abstract fn_abs(id: number, name?: string): userType
fn() {
return 'aaa';
}
}
class Child extends Parent {
fn_abs(id: number, name: string): userType {
let obj: userType = { id, name };
obj.id = id;
obj.name = name;
return obj
}
}
let c = new Child();
console.log(c.fn_abs(10, 'lisi'));
五、接口
接口主要负责定义一个类的结构,类要实现此接口,该类中必须包含接口中定义的所有属性和方法才能定义成功。
接口:也就是定义一系列的规则给类或函数去实现。
类接口
interface Person {
//id属性必须有
id: number;
//name属性可以有,可以没有
name?: string;
//say方法必须有
say():void;
}
//类实现接口
class Stu implements Person{
id: number;
name?: string | undefined;
constructor(id:number,name:string){
this.id = id;
this.name = name;
}
say(): void {
console.log(this.id);
}
}
let s = new Stu(5,'zhangsan');
s.say();
函数接口
type searchType = {
id: number,
title: string
}
interface SearchInterface {
(kw: string, username?: string): searchType[]
}
let searchFn: SearchInterface = (kw: string): searchType[] => {
return [
{id:10,title:'这是标题1'},
{id:11,title:'这是标题2'},
]
}
console.log(searchFn('aa'));
六、泛型
定义一个函数或类时,有些情况下无法确定其中要是用的具体类型(返回值、参数、属性的类型不能确定),此时泛型就能发挥作用。
1、泛型函数
在没有使用泛型时,使用any会关闭TS的类型检查,其次这样设置也不能体现出参数和返回值是相同的类型
function test(arg:any): any{
return arg;
}
使用泛型
function test<T>(param:T): T {
return param;
}
//这里的<T>就是泛型;
//设置泛型后即可在函数中使用T来表示该类型
//所以泛型其实很好理解,就是表示某个类型
//指定类型使用
test<number>(10);
//函数中声明多个泛型
function test<T, K>(a: T, b: K): K {
return b;
}
test<number,string>(10,'aa');
2、泛型类
使用泛型类
class Myclass<T>{
name :T;
constructor(name:T) {
this.name = name;
}
}
let c = new Myclass<string>('11');
泛型继承
//接口定义规范
interface Myinter {
length: number;
}
//泛型T继承接口规范,参数没有有length属性时即报错
function test<T extends Myinter>(arg: T): number {
return arg.length;
}
test<string>('aaa');
var arr : Array<number>;
arr = [1,2,3,4];
test<Array<number>>(arr);
//number类型没有length属性报错
test<number>(1234);