从C#到TypeScript - 类

从C#到TypeScript - 类

在ES6之前Javascript的类都是用function定义的,ES6把类关键字正式加进来,虽说其实也还是function,不过代码可读性上好了不少。 TypeScript同样支持class,并且和C#也非常相似,下面来看看:

同C#一样,由构造函数,属性,方法组成,属性和方法有三个级别的访问权限:private, protected, public,比C#少个internal。 不过不同的是C#类的成员默认是private,而TypeScript默认是public。 在类里面所有成员都必须用this来访问。

class User{
    constructor(name: string, pwd: string){
        this.name = name;
        this.pwd = pwd;
    }

    name: string;
    private pwd: string;

    checkLogin(): boolean{
        return this.name === 'brook' && this.pwd === '123';
    }
}

let u: User = new User('brook', '123');
console.info(u.checkLogin()); // true

u.name = 'test';
console.info(u.checkLogin()); // false

参数属性

上面的User类有两个成员,而且都是从构造函数赋值的,也就是其实构造函数的参数就是类的成员,这就是参数属性。 类里面的那两个属性其实可以不用写,只要在构造函数的参数上加上操作限定符,TypeScript就会自动为参数生成属性,来重构下上面的User

class User{
    constructor(public name: string, private pwd: string){ }

    checkLogin(): boolean{
        return this.name === 'brook' && this.pwd === '123';
    }
}

getter/setter

同样,也有存取器,不过语法和C#不太一样,写起来稍麻烦些。 只有get的时候也就变成只读属性了。

class User{
    private _name: string;

    get name(): string{
        return this._name;
    }

    set name(name: string){
        this._name = name;
    }
}

静态属性和方法

上面说的都是实例成员,TypeScript也支持静态成员,不用实例化,而是通过类名来访问。

class User{
    static permission = 'user';

    static setPermission(p: string){
        User.permission = p;
    }
}

console.info(User.permission); // user

User.setPermission('admin');
console.info(User.permission); // admin

也同时支持staticreadonly,不过static要放在前面,这样可以实现单例模式。

class User{
    
    static readonly instance = new User();

    private constructor(){}

    checkLogin(name: string, pwd: string): boolean{
        return name === 'brook' && pwd === '123';
    }
}

console.info(User.instance.checkLogin('brook', '123'));

抽象类

这点和C#一样,都可以用抽象类来把有共同行为抽象出来,关键字都是abstract。 不能实例化,可以包含实现,abstract标识的方法,继承类必须实现。 但没有virtual关键字,不过和Java一样,可以认为是天生虚函数,也不需要override,直接覆盖也能支持多态。 继承类里要调用父类的函数需要用super关键字。

abstract class User{
    name: string;
    pwd: string;

    abstract checkLogin(): boolean;
    
    checkName(): boolean {
        return this.name.indexOf('.') < 0;
    }
}

class Admin extends User {
    checkLogin(): boolean {  // 必须实现的抽象方法
        return this.checkName();  
    }

    checkName(): boolean {  // 这里会把User里的checkName覆盖掉
        return true && super.checkName();
    }
}

let user: User;
user = new Admin(); 
user.name = 'brook.shi';
console.info(user.checkLogin()); // 同样有多态,checkLogin里调用的是Admin的checkName

另外,继承时还需要注意,如果派生类里有构造函数,则构造函数必须要调用父类的构造函数:super()

兼容性

TypeScript里的类是有兼容性的,这点和C#很不一样,TypeScript认为:只有成员的类型是兼容的,那它们的类型也是兼容的。 不过成员的兼容对于public很宽容,完全不相干的类如果全是public的成员,并且一致就认为是兼容的。 但对于privateprotected则只有是继承的才会被认可为兼容。

class Test1{
    name: string;
    pwd: string;

    checkName(): boolean{
        return true;
    }
}


class Test2{
    name: string;
    pwd: string;

    checkName(): boolean{
        return false;
    }
}

let t: Test1 = new Test2();
console.info(t.checkName());  // false

如果给上面的TestTest2各加一个private email: string;,结果是编译不了,因为它们并不是继承关系,也就兼容不了。

泛型

同接口一样支持泛型,用法也一样,可以参考接口泛型。

interface Testable<T> {
    field: T;
    method(arg: T): T;
}

class Test<T> implements Testable<T>{
    field: T;
    method(arg: T): T{
        console.info(`arg is ${typeof arg}`);
        return null;
    }
}

let test11 = new Test<string>();
test11.method('method');  // arg is string
test11.method(123); // error, 123 is not string

总的来说,TypeScript的类和C#或Java可以说十分相似,除了兼容性基本上没有什么新的东西,不过对于JavaScript来说却是一大进步了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏xx_Cc的学习总结专栏

iOS底层原理总结 - 探寻block的本质(二)

2004
来自专栏风口上的猪的文章

.NET面试题系列[8] - 泛型

“可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用。“ - Jon Skeet

973
来自专栏微信公众号:Java团长

深入理解Java:String

按照官方的说法:Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。

771
来自专栏程序员互动联盟

【专业知识】初学者需要知道的10个Java字符串问题

下面我为大家总结了10条Java开发者经常会提的关于Java字符串的问题,如果你也是Java初学者,仔细看看吧: ? 1、如何比较字符串,应该用”==”还是eq...

3527
来自专栏程序你好

C# 语言中Lambda(拉姆达) 表达式介绍

934
来自专栏Java帮帮-微信公众号-技术文章全总结

通过字节码分析JDK8中Lambda表达式编译及执行机制【面试+工作】

在Class文件中,方法调用即是对常量池(ConstantPool)属性表中的一个符号引用,在类加载的解析期或者运行时才能确定直接引用。

611
来自专栏前端杂货铺

前端开发中的字符编码

前端开发过程中会接触各种各样的编码,比较常见的主要是UTF-8和HTML实体编码,但是web前端的世界却不止这两种编码,而且编码的选择也会造成一定的问题,如前后...

2898
来自专栏向治洪

Kotlin之Elvis 操作符

Elvis 操作符的优先级 首先要注意到,Elvis 操作符的优先级是比较低的,特别是比加减乘除的运算符低,混合运算时一定要记得加上括号。比如: fun <T>...

18710
来自专栏你不就像风一样

Java性能优化之String字符串优化

Java中八大基本数据类型没有String类型,因为String类型是Java对char数组的进一步封装。

692
来自专栏海纳周报

修饰者模式

java.io 这个包里有一个类,比较特别,这就是BufferedReader。我们从JDK的源码里,找到它的实现: public class Buffered...

32812

扫码关注云+社区