V. class

Keyword class

class Greeter {
  greetering: string;
  constructor(message: string){
    this.greetering = message;
  }
  // 在使用任何类成员是都使用this关键字
  greet() {
    return 'Hello, ' + this.greetering;
  }
}
let greeter = new Greeter('world');

inherit

Class-based programming, a basic model is allowed to extend an existing class inheritance

  • Class inherits properties and methods from the base class
  • When the manual contains the derived class constructor, you must call super (), he will perform the constructor of the base class, before accessing this property in the constructor, you must first call the super (), it is important to enforce the rules TS
// 基类或者超类
class Animal {
  name: string;
  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');
// 即使定义成Animal类型,但是他的值是House,所以调用move时,会调用Horse里重写的方法
let tom: Animal = new Horse('Tommy the Palomino');

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

Members of the modifier

  • public: When you define a class member if not then the default modifier for the public, are free to access the members defined in the class
  • private: the statement can not be accessed outside of his class
  • protected: private with similar, but members can still access the protected derived class (subclass) in
  • readonly: attribute to read-only, read-only attribute declaration must be initialized when the constructor or
// public 类型 
class Person2 {
  public name: string;
  public constructor(theName: string){
    this.name = theName;
  }
  public move(distanceInMeters: number){
    console.log(`${this.name} moved ${distanceInMeters}m.`);
  }
}
// private类型
class Person1 {
  private name: string;
  constructor(theName: string) {
    this.name = theName;
  }
}
let person = new Person1("Book");
person.name; // error name是私有的访问不到
// protected类型
class Person {
  protected name: string;
  constructor(name: string){
    this.name = name;
  }
}
class Employ extends Person {
  private department: string;
  constructor(name: string, department: string) {
    super(name);
    this.department = department;
  }
  public getElevatorPitch() {
    return `Hello, my name is ${this.name} and I work in ${this.department}.`;
  }
}
let howard = new Employ('Howard', 'Sales');
console.log(howard.getElevatorPitch());
console.log(howard.name) // error protected 类型外部无法访问
// readonly类型
class Octopus {
  readonly name: string;
  readonly numberOfLegs: number = 8;
  constructor(theName: string){
    this.name = theName;
  }
}
let dad = new Octopus('Man with the 8 strong legs');
dad.name = 'Ald'; // error name属性是只读的
console.log(dad.name)

Note: The constructor can also be marked as protected, means that this class can not contain him outside of class is instantiated, but can be inherited

// 构造函数也可以被标记为protected,意味着这个类不能在包含他的类外被实例化,但能被继承
class Person3 {
  protected name: string;
  protected constructor(theName: string){
    this.name = theName;
  }
}
class Employee3 extends Person3{
  private department: string;
  constructor(name: string, department: string){
    super(name);
    this.department = department;
  }
  public getElement(){
    return `Hello, my name is ${this.name} and I work in ${this.department}.`;
  }
}
let hward = new Employee3('Howrl',"Sales");
let john = new Person3('John'); // error Person3的构造函数是被保护的

Description: TS using a structural type system, when comparing two different types, and do not care where they come from, if all members of the types are compatible, they think that they are compatible with the type of

class Animal1 {
  private name: string;
  constructor(theName: string) {
    this.name = theName;
  }
}
class Rhino extends Animal1 {
  constructor(){
    super('Rhino');
  }
}
class Employee {
  private name: string;
  constructor(theName: string) {
    this.name = theName;
  }
}
let animal = new Animal1('Goat');
let rhino = new Rhino();
let employee = new Employee('Bob');
// animal跟rhino共同继承自基类Animal1 所以出处是一样的,所以类型是兼容的
animal = rhino;
// employee是独立的虽然字段一样,但是出处不同,所以TS会认为类型不兼容
animal = employee; // error animal 与 employee不兼容

Special: When comparing with the type of private or protected members, and if one type contains a private member, then only when there is also another type of such a private members, and they all come from the same statement at the time, was considered these two classes are compatible, protected equally applicable

Parameters property

In one place can easily define and initialize a member
define: an access parameter properties by adding to the former qualifier constructor arguments are declared with the private attribute defining a parameter declared and initialized to a member of a private, public, protected similarly

class Octopus1 {
  readonly numberOfLegs: number = 8;
  // 直接在构造函数中创建跟初始化name成员,把声明跟赋值合并
  constructor(readonly name: string){}
}

Accessor

TS to intercept access to the object's members getters / setters, can effectively control the access object members
Note:

  • Access supports ES5 version or higher
  • Only bands get accessor automatically set without being inferred readonly
let passcode = 'secret passcode';
class Employee4{
  private _fullName: string;
  get fullName(): string {
    return this._fullName;
  }
  set fullName(newName: string){
    if(passcode && passcode == 'secret passcode'){
      this._fullName = newName;
    } else {
      console.log("Error: Unauthorized update of employee!");
    }
  }
}
let employee4 = new Employee4();
employee4.fullName = 'Bob Smith';
if(employee4.fullName){
  console.log(employee4.fullName);
}

Static properties

Class instance members: will only be initialized when the class is instantiated, and accessed by this instance members.

Static properties: Property exists on the class itself rather than on instance, use the static keyword defined to access static member in the constructor name.

class Grid {
  static origin = { x: 0, y: 0 };
  calculateDistanceFromOrigin(point: { x: number; y: number; }){
    let xDist = (point.x - Grid.origin.x);
    let yDist = (point.y - Grid.origin.y);
    return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
  }
  constructor(public scale: number){}
}
let grid1 = new Grid(1.0);
let grid2 = new Grid(5.0);
console.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));

Abstract class

Used as a base class to the derived class to other, generally not instantiated
Note: Unlike the interface, implementation details may comprise abstract class members
Keywords: abstract keywords or abstract methods defined in an abstract class for abstract class inside

Abstract class features:

  • Abstract methods abstract class does not contain specific implementation and must be implemented in the derived class
  • The method of abstract syntax similar interface method, both of which are not defined, but the method signatures have a body
  • Abstract methods must include the abstract keyword and may include access modifiers
// 定义
abstract class Animal4{
  abstract makeSound(): void;
  move(): void {
    console.log('roaming the earch...');
  }
}

abstract class Department {
  constructor(public name: string){}
  printName(): void {
    console.log('Department name: ' + this.name);
  }
  abstract printMeeting(): void; // 必须在派生类中实现
}
class AccountingDepartment extends Department {
  constructor(){
    super('Accounting and Auditiing'); // 派生类构造函数必须调用super()
  }
  printMeeting(): void {
    console.log('The Accounting Department meets each Monday at 10am.');
  }
  generateReports(): void {
    console.log('Generating accounting reports...');
  }
}
let departMent: Department; // 允许创建一个对抽象类型的引用
// departMent = new Department(); // error 不能创建一个抽象类型的实例
departMent = new AccountingDepartment(); // 允许对一个抽象类子类进行实例化跟赋值
departMent.printName();
departMent.printMeeting();
// departMent.generateReports(); // error 方法在声明的抽象类中不存在

Constructor

When you declare a class in the TS, in fact, a statement that a lot of things:

  • Examples of the type of
  • Create a constructor, the constructor will be called when the class is created using a new instance of the constructor also contains all the static properties of the class
class Greeter1 {
  greeting: string;
  constructor(message: string){
    this.greeting = message;
  }
  greet() {
    return 'Hello, ' + this.greeting;
  }
}
// Greeter1类的实例的类型是Greeter1
let greete: Greeter1;
greete = new Greeter1('world');
console.log(greete.greet());

The interface classes as:
Since the class definition creates two things: the type of class instance, a constructor
because class types can be created, it is possible to allow the use of the interface in place using the class

class Point {
  x: number;
  y: number;
}
interface Point3d extends Point{
  z: number;
}
let point3d: Point3d = {x: 1, y: 2, z: 3};
console.log(point3d);

Guess you like

Origin blog.51cto.com/14533658/2436004