最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Typescript 学习之 - Class

    正文概述 掘金(Liqiaomiao)   2021-01-30   408

    类的概念

    类包含了一类事物的抽象特点,包含这类事物的属性和方法。

    类的实现

    传统方法中我们通过构造函数实现类的概念,在ES6中我们终于迎来了 class,而 Typescript 除了实现ES6中的类的功能外,还添加了一些新的用法。

    Typescript 中类的用法

    属性和方法

    使用 class 定义类,一个类可以包含以下几个成员

    • 构造函数 Constructor
    • 属性 Properties
    • 方法 Methods

    通过 new 生成实例的时候,会自动调用 constructor

    class Animal {
       public name;
       constructor(name) {
           this.name = name;
       }
       sayHi() {
           return `My name is ${this.name}`;
       }
    }
    
    let a = new Animal('Jack');
    console.log(a.sayHi()); // My name is Jack
    

    继承

    使用关键字 extends 实现继承。

    关于 super:

    • 在子类的 constructor 中,必须要使用 super(),他会调用父类的 constructor
    • 在子类中可以通过 super 来调用父类的方法。
    class Animal {
       public name;
       constructor(name) {
           this.name = name;
       }
       sayHi() {
           return `My name is ${this.name}`;
       }
    }
    
    class Human extends Animal { 
        constructor(name) {
            super(name) // 调用父类的 constructor
        }
        sayMorning() {   
            console.log('moring')
            console.log(super.sayHi()) // 调用父类的方法
        }  
    }
    const man = new Human('Andy')
    man.sayMorning()
    

    上述示例中,子类 Human存在构造函数,必须要调用super,调用的同时会触发父类的构造函数,因次如果父类的构造函数存在参数,super的调用也需要传对应的参数。

    在子类的方法 sayMorning 中,通过 super.sayHi() 调用了父类的 sayHi

    修饰符

    TypeScript 可以使用三种访问修饰符,分别是 publicprivateprotected,默认为 public

    • public 修饰的属性或方法是公有的,可以在任何地方访问到。
    • private 修饰的属性或方法是私有的
      • 不能在声明它的类的外部访问(实例和子类)
      • 当构造函数修饰为 private 时,该类不允许被继承或实例化
    • protected 修饰的属性或方法是受保护的
      • private 相似,但是可以在子类中访问。
      • 当构造函数被修饰为protected时,该类不允许被实例化,但可以被继承。

    public

    class Animal {
      public name;
      public constructor(name) {
        this.name = name;
      }
    }
    
    let a = new Animal('Jack');
    console.log(a.name); // Jack
    a.name = 'Tom';
    console.log(a.name); // Tom
    

    public 描述的属性可以在实例中访问

    private

    1. 私有属性无法在实例中访问
    class Employee {
        public name;
        private salary=10000;
        public constructor(name) {
            this.name = name;
        }
        printSalary() { 
           return this.salary // Employee类中访问私有属性 salary 是 OK 的
        }
    }
    
    let a = new Employee('Jack');
    
    console.log(a.salary); 
    // Property 'salary' is private and only accessible within class 'Employee'.
    a.salary = 100000;
    // Property 'salary' is private and only accessible within class 'Employee'.
    
    1. 私有属性无法在子类中访问
    class Employee {
        public name;
        private salary=10000;
        public constructor(name) {
            this.name = name;
        }
        printSalary() { 
           return this.salary
        }
    }
    class Boy extends Employee{
        public constructor(name) {
            super(name)
            console.log(this.salary)
             //Property 'salary' is private and only accessible within class 'Employee'.
           
        }
    }
    

    上述示例中,Boy 继承了 Employee,在子类 Boy 中访问私有属性 salary会出现错误提示。

    1. constructor 被设置为 private 后无法创建实例
    class Employee {
        private constructor(name) {
           
        }
    }
    
    let a = new Employee('Jack');
    // Constructor of class 'Employee' is private and only accessible within the class declaration.
    

    提示 Employee 的构造函数是私有的,只能在类中使用。

    protected

    1. 受保护的属性可以在子类中访问,但是无法通过实例访问
    class Employee {
        public name;
        protected salary=10000;
        public constructor(name) {
            this.name = name;
        }
        printSalary() { 
           return this.salary
        }
    }
    class Boy extends Employee{
        public constructor(name) {
            super(name)
            console.log(this.salary) // 受保护属性在子类中可以访问
        }
    }
    let a = new Employee('Jack');
    console.log(a.salary)
    // Property 'salary' is protected and only accessible within class 'Employee' and its subclasses.
    
    1. 构造函数被设置为受保护的属性后,无法创建实例
    class Employee {
      public name;
      protected salary=10000;
      protected constructor(name) {
          this.name = name;
      }
      printSalary() { 
         return this.salary
      }
    }
    
    let a = new Employee('Jack');
    
    // Constructor of class 'Employee' is protected and only accessible within the class declaration.
    

    readonly修饰符

    readonly 即一旦创建,不能修改。但不影响初始化,在类中声明或构造函数中初始化是允许的、也是有必要的。

    class Employee {
        readonly empCode: number = 1; // Ok: declaration
        readonly empName: string;
        
        constructor(code: number, name: string)     {
            this.empName = name; //  Ok: initialized inside the class constructor
        }
    }
    let emp = new Employee(10, "John");
    emp.empCode = 20; 
    // Error:Cannot assign to 'empCode' because it is a constant or a read-only property.
    emp.empName = 'Bill';
    // Error:Cannot assign to 'empName' because it is a constant or a read-only property.
    

    注意如果 readonly 和其他访问修饰符同时存在的话,需要写在其后面。

    class Animal {
      public readonly name
      public constructor(name) {
        this.name = name;
      }
    }
    

    参数属性

    修饰符和 readonly 可以在构造函数参数中使用,等同于类中定义该属性的同时给该属性赋值,使代码更简洁

    class Employee {
        constructor(protected name='human') {
        }
    }
    
    class Boy extends Employee{
        getName() {
            return this.name
        }
    }
    let boy = new Boy()
    console.log(boy.getName()) // human
    

    静态属性

    属性前加上static关键字,就表示该属性不会被实例继承。

    静态属性只能通过类来访问

    class Animal {
      static num = 42;
    
      constructor() {
        // ...
      }
    }
    
    console.log(Animal.num); // 42
    const cat = new Animal()
    console.log(cat.num)
    // Property 'num' is a static member of type 'Animal'
    
    

    存取器

    使用 getter setter 可以改变属性的读取和赋值行为

    可以防止我们意外的直接修改公有属性,并为我们检索和设置属性提供了更多控制。

    class Person {
        private _name: string = '';
        get name(): string { 
            return  this._name
        }
        set name(newName) {
            alert(newName.length)
            if (newName && newName.length < 5) {
             throw new Error('Name is too short'); 
            } else {
             this._name=newName 
            }
           
        }
    }
    let person = new Person()
    person.name = 'Jane Smith'
    console.log(person.name)
    

    上述示例中,_name 为私有属性,通过 getter 的 name 获取 _name 的值,在 setter 中我们限制的name的赋值长度需大于 5,小于 5 的话抛出一个异常。

    另外 只带有 get不带有 set的存取器自动被推断为 readonly

    抽象类

    abstract 用于定义抽象类和其中的抽象方法

    抽象类有以下几个特点

    • 抽象类不允许被实例化
    • 抽象类通过子类来实现
    • 抽象类方法和接口相似,只定义方法,不包含方法体
    • 抽象类方法必须通过子类实现

    抽象类不允许被实例化: 实例化一个抽象类会出现异常提示

    abstract class Animal{
        constructor(public name:string) { 
            this.name  = name
        }
        
    }
    const abstractAnimal = new Animal()
    // Cannot create an instance of an abstract class.
    
    

    抽象类通过子类来实现,子类继承了抽象类的属性和方法

    class Cat extends Animal{
    }
    
    const cat = new Cat('miaomiao')
    console.log(cat.name)
    

    上述示例中,Cat 继承了抽象类 Animal,并且能够拥有 Animal 的属性name

    抽象类方法和接口相似,只定义方法,不包含方法体,并且必须通过子类实现。

    abstract class Animal{
        constructor(public name:string) { 
            this.name  = name
        }
        abstract getName(){}
        // Error:  Method 'getName' cannot have an implementation because it is marked abstract.
    }
    class Cat extends Animal{
    // Error: Non-abstract class 'Cat' does not implement inherited abstract member 'getName' from class 'Animal'.
    }
    
    

    上述示例抛出了两个异常:

    • 抽象方法包含方法体后提示: getName为抽象类方法,不能被实现。
    • 继承类没有实现抽象方法提示: 非抽象类Cat没有实现抽象类Animal的方法getName

    正确示例应为

    abstract class Animal{
       constructor(public name:string) { 
           this.name  = name
       }
        abstract getName()
    }
    
    class Cat extends Animal{
       getName() {
           return this.name
        }
    }
    const cat = new Cat('miaomiao')
    console.log(cat.getName()) // miaomiao
    

    类的类型

    即类可以像接口一样作为类型描述

    class Animal{
        constructor(public name: string = 'animal') {
            this.name = name
        }
    }
    const animal:Animal = new Animal()
    

    起源地下载网 » Typescript 学习之 - Class

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元