zoukankan      html  css  js  c++  java
  • 第四节:TypeScipt类、接口、枚举类型详解

    一. ts类详解

    1. 类的定义

    class Person {
        // 属性
        name: string
        age: number
        // 构造函数
        constructor(name: string, age: number) {
            this.name = name;
            this.age = age;
        }
        // 普通方法
        eating() {
            console.log(`${this.name}[${this.age}岁], is eating`);
        }
    }
    
    // 调用
    const p=new Person('ypf',18);
    console.log(p.name);
    console.log(p.age);
    p.eating();

    2. 类的继承

     通过extends关键字继承父类
    // 1.父类
    class Person {
        // 属性
        name: string = ''
        age: number = 0
        // 构造函数
        constructor(name: string, age: number) {
            this.name = name;
            this.age = age;
        }
        // 普通方法
        eating() {
            console.log(`${this.name}[${this.age}岁], is eating`);
        }
    }
    
    // 2. 子类 
    // 通过extends关键字继承父类
    class Student extends Person {
        sno: number = 0
        constructor(name: string, age: number, sno: number) {
            super(name, age);
            this.sno = sno;
        }
        studying() {
            console.log(`姓名为:${this.name},年龄为:${this.age},学号为:${this.sno} 正在学习中....`)
        }
    }
    
    // 调用
    const student = new Student('ypf', 18, 1001);
    student.studying();
    View Code

    3. 类的多态

    class Animal {
        action() {
            console.log("animal action")
        }
    }
    
    class Dog extends Animal {
        action() {
            console.log("dog running!!!")
        }
    }
    
    class Fish extends Animal {
        action() {
            console.log("fish swimming")
        }
    }
    
    class Person extends Animal {
    
    }
    
    // animal: dog/fish
    // 多态的目的是为了写出更加具备通用性的代码
    function makeActions(animals: Animal[]) {
        animals.forEach(animal => {
            animal.action()
        })
    }
    
    makeActions([new Dog(), new Fish(), new Person()])
    View Code

    4. 成员修饰符

    (1). 在TypeScript中,类的属性和方法支持三种修饰符: public、private、protected

      public 修饰的是在任何地方可见、公有的属性或方法,默认编写的属性就是public的;

      private 修饰的是仅在同一类中可见、私有的属性或方法;

      protected 修饰的是仅在类自身及子类中可见、受保护的属性或方法;

    (2). 只读属性readonly

      如果有一个属性我们不希望外界可以任意的修改,只希望确定值后直接使用,那么可以使用readonly

    class Person {
        // 属性
        public name: string
        private age: number
        protected sex: string
        readonly address: string
        // 普通方法
        eating() {
            console.log(`${this.name}[${this.age}岁], is eating`);
        }
    }

    5. get和set

     一些私有属性我们是不能直接访问的,或者某些属性我们想要监听它的获取(getter)和设置(setter)的过程,这个时候我们可以使用存取器。
    class Person {
        private _name: string
        constructor(name: string) {
            this._name = name
        }
        // 访问器
        // set
        set name(newName) {
            this._name = newName
        }
        // get
        get name() {
            return this._name
        }
    }
    
    const p = new Person("why")
    p.name = "ypf"
    console.log(p.name)

    6. 静态成员static

    //普通类+静态成员
    class Student{
        static time:string='12:28'
        static getMsg(){
            console.log('学习中....')
        }
    }
    // 调用
    console.log(Student.time);
    Student.getMsg();

    7. 抽象类abstract

    (1). 特点:

         抽象类是不能被实例的话(也就是不能通过new创建)

         抽象方法必须被子类实现,否则该类必须是一个抽象类;

    (2). 关键字: abstract

    abstract class Shape {
        abstract getArea(): number
    }
    class Rectangle extends Shape {
        private  number
        private height: number
        constructor( number, height: number) {
            super()
            this.width = width
            this.height = height
        }
        getArea() {
            return this.width * this.height
        }
    }
    
    const rectangle = new Rectangle(20, 30)
    console.log(rectangle.getArea())

    8. 类的类型 

     类本身也是可以作为一种数据类型的.
    class Person {
        name: string = "123"
        eating() {}
    }
    const p = new Person()
    const p1: Person = {
        name: "why",
        eating() { }
    }
    function printPerson(p: Person) {
        console.log(p.name)
    }
    
    printPerson(new Person())
    printPerson({ name: "ypf", eating: function () { } })

    二. ts接口详解

    1. 对象类型

    // 在其中可以定义可选类型,也可以定义只读属性
    interface IInfoType {
        readonly name: string
        age: number
        friend?: {
            name: string
        }
    }
    const info: IInfoType = {
        name: "why",
        age: 18,
        friend: {
            name: "kobe"
        }
    }
    console.log(info.friend?.name)
    console.log(info.name)

    2. 索引类型

    // 声明接口为索引类型
    interface IndexLanguage {
        [index: number]: string
    }
    const frontLanguage: IndexLanguage = {
        0: "HTML",
        1: "CSS",
        2: "JavaScript",
        3: "Vue"
    }
    
    interface ILanguageYear {
        [name: string]: number
    }
    const languageYear: ILanguageYear = {
        "C": 1972,
        "Java": 1995,
        "JavaScript": 1996,
        "TypeScript": 2014
    }

    3. 函数类型

    // 函数类型
    interface ICalcFn {
        (n1: number, n2: number): number
    }
    function calc(num1: number, num2: number, calcFn: ICalcFn) {
        return calcFn(num1, num2)
    }
    const add: ICalcFn = (num1, num2) => {
        return num1 + num2
    }
    console.log(calc(20, 30, add))

    4. 接口的继承

     接口和类一样是可以进行继承的,也是使用extends关键字:并且我们会发现,接口是支持多继承的(类不支持多继承)
    interface ISwim {
        swimming: () => void
    }
    interface IFly {
        flying: () => void
    }
    interface IAction extends ISwim, IFly {
    }
    const action: IAction = {
        swimming() {
        },
        flying() {
        }
    }

    5. 交叉类型

    // 一种组合类型的方式: 联合类型
    type WhyType = number | string
    type Direction = "left" | "right" | "center"
    
    // 另一种组件类型的方式: 交叉类型
    type WType = number & string
    interface ISwim {
      swimming: () => void
    }
    interface IFly {
      flying: () => void
    }
    type MyType1 = ISwim | IFly
    type MyType2 = ISwim & IFly
    const obj1: MyType1 = {
      flying() {
      }
    }
    const obj2: MyType2 = {
      swimming() {
      },
      flying() {
      }
    }

    6. 接口的实现

    // 接口的实现
    
    
    interface ISwim {
        swimming: () => void
    }
    interface IEat {
        eating: () => void
    }
    // 类实现接口
    class Animal {
    
    }
    
    // 继承: 只能实现单继承
    // 实现: 实现接口, 类可以实现多个接口
    class Fish extends Animal implements ISwim, IEat {
        swimming() {
            console.log("Fish Swmming")
        }
    
        eating() {
            console.log("Fish Eating")
        }
    }
    
    class Person implements ISwim {
        swimming() {
            console.log("Person Swimming")
        }
    }
    
    // 编写一些公共的API: 面向接口编程
    function swimAction(swimable: ISwim) {
        swimable.swimming()
    }
    
    // 1.所有实现了接口的类对应的对象, 都是可以传入
    swimAction(new Fish())
    swimAction(new Person())
    
    
    swimAction({ swimming: function () { } })
    View Code

    7. interface和type的区别

    (1). 我们会发现interface和type都可以用来定义对象类型,那么在开发中定义对象类型时,到底选择哪一个呢?

      如果是定义非对象类型,通常推荐使用type,比如Direction、Alignment、一些Function;

    (2). 如果是定义对象类型,那么他们是有区别的:

     A. interface 可以重复的对某个接口来定义属性和方法;

     B. type定义的是别名,别名是不能重复的;

    interface IFoo {
        name: string
    }
    interface IFoo {
        age: number
    }
    const foo: IFoo = {
        name: "why",
        age: 18
    }
    
    
    // 下面代码报错
    // type IBar = {
    //   name: string
    //   age: number
    // }
    
    // type IBar = {
    // }

    8. 字面量赋值

      因为TypeScript在字面量直接赋值的过程中,为了进行类型推导会进行严格的类型限制。  但是之后如果我们是将一个 变量标识符 赋值给其他的变量时,会进行freshness擦除操作。
    interface IPerson {
        name: string
        age: number
        height: number
    }
    const info = {
        name: "why",
        age: 18,
        height: 1.88,
        address: "广州市"
    }
    
    // freshness擦除
    const p: IPerson = info
    
    console.log(info)
    console.log(p)

    三. ts枚举详解

    1. 说明

     枚举类型是为数不多的TypeScript特性有的特性之一:

     枚举其实就是将一组可能出现的值,一个个列举出来,定义在一个类型中,这个类型就是枚举类型;

     枚举允许开发者定义一组命名常量,常量可以是数字、字符串类型;

    enum Direction {
        LEFT,
        RIGHT,
        TOP,
        BOTTOM
    }
    function turnDirection(direction: Direction) {
        switch (direction) {
            case Direction.LEFT:
                console.log("改变角色的方向向左")
                break;
            case Direction.RIGHT:
                console.log("改变角色的方向向右")
                break;
            case Direction.TOP:
                console.log("改变角色的方向向上")
                break;
            case Direction.BOTTOM:
                console.log("改变角色的方向向下")
                break;
            default:
                const foo: never = direction;
                break;
        }
    }
    
    turnDirection(Direction.LEFT)
    turnDirection(Direction.RIGHT)
    turnDirection(Direction.TOP)
    turnDirection(Direction.BOTTOM)

    2. 其它

     枚举类型默认是有值的,比如上面的枚举,默认值是这样的:  当然,我们也可以给枚举其他值:  这个时候会从100进行递增;  我们也可以给他们赋值其他的类型:
    enum Direction {
        LEFT = "LEFT",
        RIGHT = "RIGHT",
        TOP = "TOP",
        BOTTOM = "BOTTOM"
      }
      
      let name: string = "abc"
      let d: Direction = Direction.BOTTOM
      
      function turnDirection(direction: Direction) {
        console.log(direction)
        switch (direction) {
          case Direction.LEFT:
            console.log("改变角色的方向向左")
            break;
          case Direction.RIGHT:
            console.log("改变角色的方向向右")
            break;
          case Direction.TOP:
            console.log("改变角色的方向向上")
            break;
          case Direction.BOTTOM:
            console.log("改变角色的方向向下")
            break;
          default:
            const foo: never = direction;
            break;
        }
      }
      
      turnDirection(Direction.LEFT)
      turnDirection(Direction.RIGHT)
      turnDirection(Direction.TOP)
      turnDirection(Direction.BOTTOM)
    View Code

    !

    • 作       者 : Yaopengfei(姚鹏飞)
    • 博客地址 : http://www.cnblogs.com/yaopengfei/
    • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
    • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
     
  • 相关阅读:
    Codeforces Round #744 (Div. 3) (CF1579) 题解
    Codeforces Round #748 (Div. 3) (CF1593)题解
    NOIP2018初赛游记
    模板:高精度
    博客园,初见安~~
    20200211学习
    nyoj 1103 区域赛系列一多边形划分
    南阳oj 845 无主之地1
    hdu 2080 夹角有多大II
    hdu 分拆素数和
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/15527243.html
Copyright © 2011-2022 走看看