typescript之五(类)

我们常常提及到的类,在服务端语言中倒是常常提到,在前端js中,那就没有那么多词语来形容类的概念了,偶尔也仅仅是函数,来充当类的概念,毕竟一切皆对象,这不,多态的概念又出来了。在es2015中也提出了class类的概念,当然还是有很多不同的地方,毕竟ts基于js的一种超集,当然在功能上会多出很多,笔记是前端语言,最终结果也都还是编译成js文件,只是提供了一种方便编写的解决方案而已。

类我们要用到的关键词是class 

class Test{}

使用class关键字定义类,类名通常首字母大写的形式,以花括号包含类中的内容

class Animal {
    constructor(protected leg: number) {
        this.leg = leg;
    }
    name(name: string) {
        console.log(`my name is ${name} I have ${this.leg} legs`);
    }
}
class Cat extends Animal {

}
let cat = new Cat(4);
cat.name('kitty');//my name is kitty I have 4 legs

上面的animal即为基类,Cat为派生类,继承于animal,于是cat实例中也会有name方法可供调用

class Animal1 {
    constructor(protected name: string) {
        this.name = name;
    }
    move(leg: number = 0) {
        console.log(`my name is ${this.name} I have ${leg} legs`);
    }
}
class Cat extends Animal1 {
    age: number = 0;
    constructor(name: string) {
        super(name);
        // 当存在继承关系时,基类中存在constructor,继承类中若提供constructor,则务必执行super()执行父类中的constructor
        this.age = 1;
    }
    // 重写父类中的move方法,通过super关键字调用父类的方法或属性
    move(leg = 4) {
        console.log('cat move');
        super.move(leg);
    }
}
let cat = new Cat('cat');
cat.move()
// cat move
// my name is cat I have 4 legs

上面继承关系中子类调用父类方法,重写父类方法,使用关键字super来调用,在父子类中都存在constructor时,子类务必执行super()方法来执行父类的构造方法,或者子类不提供构造方法,且在子类中的构造方法中使用this调用属性或是方法时也必须是在执行super()方法之后。

class Test {
    // 定义属性或方法 默认可访问性为public,同时还可以是private(私有),protected(受保护的)
    // public 类的实例可访问到,
    // private 只对当前类可访问 私有属性一般以下划线开头
    // protected 当前类及继承关系可访问到
    name: string;//默认public
    private age: number;
    protected habbies: string;
    private _sex: number;
    readonly CLASSES: number = 2 //只读属性一般全大写,es2015中的const一样,下文中不可修改
    // 构造函数,若不提供,系统也会提供一个可执行的构造函数,在实例化时执行
    constructor(name: string) {
        this.name = name;
    }
    // 获取name值
    getName() {
        return this.name;
    }
    // 设置值
    setName(name: string) {
        this.name = name;
    }
    getHabbies() {
        return this.habbies;
    }
    setHabbies(habbies: string) {
        this.habbies = habbies;
    }
    getAge() {
        return this.age;
    }
    setAge(age: number) {
        this.age = age;
    }
    // 设置sex值,若不提供set方法,则在当前类中sex属性相当于readonly只读属性
    set sex(sex: number) {
        this._sex = sex;
    }
    // 获取sex值
    get sex() {
        return this._sex;
    }
}
let t = new Test('zhangsan');
console.log(t.name); // 'zhangsan'
// 在这里我们可以直接通过这种方式直接修改实例类中的属性值,虽然大部分时候不应该这样做,但是这样做并不会报错,故而有private及protected来控制属性的可访问性
t.name = 'lishi';
console.log(t.name);// 'lisi'
// 受保护的,不能通过实例方式直接调用属性
// console.log(t.habbies);
// 对habbies设置值
t.setHabbies('sing,switing');
console.log(t.getHabbies());
// age属性可访问性为private私有属性,只能在当前类中访问
// console.log(t.age);
// 对age设值
t.setAge(12);
console.log(t.getAge());
// 设置sex(存取器)
t.sex = 0;
console.log(t.sex);
// 将提示没有权限修改当前属性
// t.CLASSES = 3;
console.log(t.CLASSES);

public: 自由的访问程序里定义的成员,没有特殊说明,在类中定义的属性及方法都默认为public

private:私有声明,使用private声明的属性或方法就不能在声明它的类的外部访问

protected:受保护的,与private类似,但该声明的属性或是方法在派生类中是可访问的,private只有在当前声明的类中才能被访问到,当使用protected来修饰constructor时,这个类不能在包含它的类外被实例化,但是能被继承

readonly:使用readonly修饰符修饰的属性在声明时或构造方法中必须赋值,且后面无法修改其值

上述代码中,我们可以定义一个私有属性private _sex 来作为存取器,通过get 来取值,通过set 来赋值,当实例化类时,通过实例的属性赋值操作执行set方法,获取执行get方法。若不存在set方法时,则表明该属性为只读属性,可读不可写。

//静态类
class StaticA {
    static obj: any = { name: 'zhangsan', age: 22 }
    getName() {
        console.log(StaticA.obj.name);
    }
}
let sa = new StaticA;
sa.getName() //zhangsan
// 抽象
abstract class AbstractA {
    abstract getName(): string;
    age: number;
    getAge(): number {
        return this.age;
    }

}
class Wolf extends AbstractA {
    name: string;
    age: number = 3;
    constructor(name: string) {
        super();
        this.name = name;
    }
    getName(): string {
        return this.name;
    }
}
let w:AbstractA = new Wolf('wolf');
console.log(w.getName(), w.getAge()); //wolf 3
// 错误,在定义w时指定类型为抽象类,在该抽象类中不存在getHabby属性或方法
// console.log(w.getHabby());

在使用抽象类时,基类中的抽象方法在子类中必须实现,需要注意的是抽象类是不能被实例化的。

// 构造函数
class TestName {
    constructor(private name: string) {
        this.name = name;
    }
    getName() {
        return this.name;
    }
}
let tname = new TestName('张三');
console.log(tname.getName()); //张三

同样可以在其构造函数中声明属性,然后在后期调用。

百度已收录
分享