TypeScript学习笔记之 类

传统的JavaScript程序使用函数和基于原型(prototype)的继承来创建可重用的组件,但对于熟悉使用面向对象方式的程序员来讲就有些棘手,因为他们用的是基于类的继承并且对象是由类构建出来的。 从ECMAScript 2015,也就是ECMAScript 6开始,JavaScript程序员将能够使用基于类的面向对象的方式。 但是可能要等到下个版本的javascript发布发布才能使用,在TypeScript中我们现在就可以使用这些新特性。


TypeScript中类的概念跟java是差不多的。有个别地方是不一样的,比如构造方法。

/**
 * Created by yzq on 2017/1/9.
 */

class Person {
    name: String;//属性
    age: number;//属性
    /*构造方法 与java不同,不是使用类名,而是使用constructor*/
    constructor(name: String, age: number) {
        this.name = name;
        this.age = age;
    }
    /*方法*/
    say() {
        return `Hello,my name is ${this.name},I'm ${this.age} years old`;
    }

}
var person = new Person("yzq", 23);
alert(person.say());

上面的代码就是定义了一个Person类。这个类有name和age两个属性,还有一个构造方法和一个say方法,很简单,和java基本一样,除了构造器名字和java的有点区别。需要注意的是,TypeScript好像暂时不能存在多个构造器,没有重载方法。子类可以重写父类方法。
打印结果
TypeScript学习笔记之 类_第1张图片

继承
TypeScript的继承和java也类似。

/**
 * Created by yzq on 2017/1/9.
 */

class Person {
    name: String;//属性
    age: number;//属性
    /*构造方法 与java不同,不是使用类名,而是使用constructor*/
    constructor(name: String, age: number) {
        this.name = name;
        this.age = age;
    }
    /*方法*/
    say() {
        return `Hello,my name is ${this.name},I'm ${this.age} years old`;
    }

}
// var person = new Person("yzq", 23);
// alert(person.say());

class Student extends Person{
    school:String;
    constructor(){
        super("yzq",23);
        this.school="清华"
    }
    /*这个地方类似 重写 */
    say(){
        return `姓名:${this.name},年龄${this.age},学校${this.school}`
    }
}
var s=new Student();
// s.name="张三";//这里可以重新赋值
// s.age=34;
// s.school="北大";
alert(s.say());

打印结果
TypeScript学习笔记之 类_第2张图片

访问修饰符
跟java类似,TypeScript的访问修饰符有三个,分别是public、private、protected 。
TypeScript的默认访问修饰符是public。
1)public声明的属性和方法在类的内部和外部均能访问到。
2)protected声明的方法和属性只能在类的内部和其子类能访问。
3)private声明的方法和属性只能在其类的内部访问。

/**
 * Created by yzq on 2017/1/9.
 */
/*访问修饰符*/

class Person {
    private name: String;
    protected age: number;
    constructor(name: String,age: number) {
        this.name = name;
        this.age = age;
    }
    private say(){
        console.log(`${this.name},${this.age}`);
    }
    protected tell(){
        console.log(`${this.name},${this.age}`);
    }
}
var p=new Person("yzq",23);
// p.name="yzq";//错误,无法访问到
// p.age=23;
class Student extends Person{
    /*错误 无法访问*/
    // say(){
    //  }

    tell(){

    }
}

readonly修饰符
使用readonly关键字会将属性设置为只读的。 只读属性必须在声明时或构造函数里被初始化。且值不能不能被修改,和const类似。
最简单判断该用readonly还是const的方法是看要把它做为变量使用还是做为一个属性。 做为变量使用的话用 const,若做为属性则使用readonly。

class Person { 
    readonly name: string;

    readonly age: number=23;//必须初始化

    constructor(name:string) {
        this.name = name;//必须初始化
   }

}

let p = new Person("yzq");
p.name = "aaa"//错误,不能被修改
p.age=24//错误,不能被修改

参数属性
在上面的例子中,我们都是在类中先声明一个属性,然后再赋值。这跟java比较像。在TypeScript中,参数属性可以方便地让我们在一个地方定义并初始化一个成员。参数属性通过给构造函数参数添加一个访问限定符来声明。

class Person {
   
    /*参数属性  直接给参数添加一个访问修饰符来定义一个属性,注意,必须要添加修饰符*/
    constructor(private name: String, protected age: number) {
      
    }

    private say() {
        console.log(`${this.name},${this.age}`);
    }

    protected tell() {
        console.log(`${this.name},${this.age}`);
    }
}

存取器(Getter And Setter)
TypeScript中的存取器就类似与java中set和get方法,只不过调用的方式不一样。比如在一个类中我们将其中一个属性用private修饰,那么,在类的外部就无法访问到该属性,这个时候我们可以通过getters/setters来封装一下,以便在类的外部去访问该属性。需要注意的是,只带有 get不带有set的存取器自动被推断为readonly。也就是说,如果只写get但没有set的话,我们是不能更改值的。

/**
 * Created by yzq on 2017/1/10.
 */
/*存取器*/

class Person {
    private _age: number;

    /*相当于java中的getAge()*/
    get age() {
        return this._age;
    }
    /*相当于java中的setAge()*/
    set age(inputAge: number) {
        /*这里可以做一些逻辑处理 */
        if (inputAge < 0 || inputAge > 150) {
            alert("年龄异常");
        } else {
            this._age = inputAge;
        }
    }
    say() {
        console.log(`i'm ${this._age} years old`);
    }
}
let p = new Person();
//p._age=23;//错误,这里访问不到
p.age = 23;//这里相当于调用java中的setAge()方法。
p.say();

静态属性
跟java类似,也是使用static关键字修饰。用static修饰的属性会在这个类被加载的时候就进行初始化。
静态属性直接通过类名访问,无需实例化。

class Person {
    // private name: String;
    // protected age: number;
    static school:String;

    /*参数属性  直接给参数添加一个访问修饰符来定义一个属性*/
    constructor(private name: String, protected age: number) {
        this.name = name;
        this.age = age;
    }

    private say() {
        console.log(`${this.name},${this.age}`);
    }

    protected tell() {
        console.log(`${this.name},${this.age}`);
    }
}
Person.school;//直接通过类名访问,无需实例化

抽象类
这里跟java抽象类 类似,抽象类做为其它派生类的基类使用。 它们一般不会直接被实例化。 不同于接口,抽象类可以包含成员的实现细节。 abstract关键字是用于定义抽象类和在抽象类内部定义抽象方法。子类必须实现父类的抽象方法。抽象类不能直接实例化。

/**
 * Created by yzq on 2017/1/10.
 */

abstract class Person{
    name:string;
    age:number;
    abstract say();
    tell(){
        console.log("hello")
    }
}
class Student extends Person{
    school:string;
    /*必须实现父类抽象方法*/
    say(){
        console.log(`i’m a student`);
    }
    test(){

    }
}
let p:Person;
p=new Student();//子类对象指向父类引用。p无法获取到子类中的属性和方法
p.tell();
let s=new Student();
s.say();

你可能感兴趣的:(web前端,从零开始,学习web前端)