Typescript-Class(1)

Typescript-Class(1)接口能够描述JavaScript中对象拥有的各种各样的外形。 除了描述带有属性的普通对象外,接口也可以描述函数类型。 当一个类实现了一个接口时,只对其实例部分进行类型检查。 constructor存在于类的静态部分,所以不在检查的范围内。

Typescript Class(1)

类是函数的一个语法糖,比ES5通过原型链实现继承更加清晰和方便

类中有三个成员:greeting属性、构造函数、greet方法

class Greeter {
    greetingstring;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

let greeter = new Greeter("world");

继承

我们通过继承,对现有的类进行扩展 一个Animal类(基类)中有一个move方法,使用Dog(子类)在继承Animal的基础上,新增了一个dark方法

class Animal {
    move(distanceInMeters: number = 0) {
        console.log(`Animal moved ${distanceInMeters}m.`);
    }
}

class Dog extends Animal {
    bark() {
        console.log('Woof! Woof!');
    }
}

const dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();

以下是一段更复发的代码 注意super,通过继承父类的子类自身是没有this的 子类所使用的this是通过获取父类的构造函数塑造的,得到父类实例的属性和方法以后,进行加工,加上自己的属性和方法 构造函数中super必须在使用this前使用

class Animal {
    namestring;
    constructor(theName: string) { this.name = theName; }
    move(distanceInMeters: number = 0) {
        console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
}

class Snake extends Animal {
    constructor(name: string) { super(name); }
    move(distanceInMeters = 5) {
        console.log("Slithering...");
        super.move(distanceInMeters);
    }
}

class Horse extends Animal {
    constructor(name: string) { super(name); }
    move(distanceInMeters = 45) {
        console.log("Galloping...");
        super.move(distanceInMeters);
    }
}

let sam = new Snake("Sammy the Python");
let tomAnimal = new Horse("Tommy the Palomino");

sam.move();
tom.move(34);

public private protected

默认情况下,ts默认设置为public,这样可以随意访问类中的成员

// 默认或设置为public
class Animal {
    public namestring;
    public constructor(theName: string) { this.name = theName; }
    public move(distanceInMeters: number) {
        console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
}

// private protected 属性

class Person {
  protected namestring
  private agenumber = 10
  constructor(strName: string) {
    this.name = strName
  }
  public getAge() {
    return this.age
  }
  public getName() {
    return this.name
  }
}
const example =  new Person('aaa')
console.log(example.name)
console.log(example.age)
// Property 'name' is protected and only accessible within class 'Person' and its subclasses.ts(2445)
// Property 'age' is private and only accessible within class 'Person'.ts(2341)
console.log(example.getName())
console.log(example.getAge())
// private protected constructor 
class Person2 {
  protected namestring
  private agenumber = 10
  private constructor(strName: string) {
    this.name = strName
  }
  public getAge() {
    return this.age
  }
  public getName() {
    return this.name
  }
}
const example =  new Person2('aaa')

// Constructor of class 'Person2' is private and only accessible within the class declaration.ts(2673)
// Constructor of class 'Person2' is protected and only accessible within the class declaration.ts(2674)
// extends

// 继承
class Person {
  protected namestring
  private agenumber = 10
  constructor(strName: string) {
    this.name = strName
  }
  public getAge() {
    return this.age
  }
  public getName() {
    return this.name
  }
}

class Jack extends Person {
  constructor(name: string) {
    super(name)
  }
  getJackName() {
    super.getName
  }
  getJackAge() {
    console.log(this.name)
    console.log(this.age)
    // Property 'age' is private and only accessible within class 'Person'.ts(2341)
  }
}
const example =  new Jack('aaa')
console.log(example.name)
// Property 'name' is protected and only accessible within class 'Person' and its subclasses.ts(2445)

实现接口

接口能够描述JavaScript中对象拥有的各种各样的外形。 除了描述带有属性的普通对象外,接口也可以描述函数类型。

// 索引签名
// 数字索引签名的返回值类型必须是字符串索引签名返回值的子类型
class Animal {
  name: string = 'name';
}
class Dog extends Animal {
  breed: string = 'breed';
}

// 错误:使用数值型的字符串索引,有时会得到完全不同的Animal!
interface NotOkay {
  [x: number]: Animal;
  // Numeric index type 'Animal' is not assignable to string index type 'Dog'.ts(2413)
  [x: string]: Dog;
}
interface NotOkay {
  [x: number]: Dog;
  [x: string]: Animal;
}

接口强制类的实现

interface ClockInterface {
    currentTimeDate;
    setTime(dDate);
}

class Clock implements ClockInterface {
    currentTimeDate;
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}

上面例子接口约束了类的属性和方法,那么构造函数该如何约束? 接口描述了类的公共部分,而不是公共和私有两部分

类是具有两个类型的:静态部分的类型和实例的类型

// 使用构造器签名定义一个接口,再使用类去实现该接口
interface ClockConstructor {
    new (hournumberminutenumber);
    // Construct signature, which lacks return-type annotation, implicitly has an 'any' return type.ts(7013)
}

class Clock implements ClockConstructor {
  // Class 'Clock' incorrectly implements interface 'ClockConstructor'.
  // Type 'Clock' provides no match for the signature 'new (hour: number, minute: number): any'.ts(2420)
    currentTimeDate;
    constructor(h: number, m: number) { }
}

interface ClockConstructor {
    new (hournumberminutenumber): any;
}

class Clock implements ClockConstructor {
    currentTimeDate = new Date();
    constructor(h: number, m: number) { }
}

发生错误的原因? 当一个类实现了一个接口时,只对其实例部分进行类型检查。 constructor存在于类的静态部分,所以不在检查的范围内。 如何对构造函数签名进行检测?

interface ClockInterface {
  tick(): any;
}

interface ClockConstructor {
  new (hournumberminutenumber): ClockInterface;
}

// 检查是否满足构造函数签名(有这么个构造函数可以去验证)
function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
  return new ctor(hour, minute);
}

class DigitalClock implements ClockInterface {
  constructor(h: number, m: number) { }
  tick() {
      console.log("beep beep");
  }
}
class AnalogClock implements ClockInterface {
  constructor(h: number, m: number) { }
  tick() {
      console.log("tick tock");
  }
}

let digital = createClock(DigitalClock1217);
let analog = createClock(AnalogClock732);

今天的文章Typescript-Class(1)分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/19317.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注