TypeScript の 类 接口

  • A+
所属分类:Web前端
摘要

由图可见,上面的继承是不正常的,所以这里需要调用其super方法通过上述的get修饰的属性(看起来更像一个方法),便可以获取到私有属性,最后可以通过c.getName获取到


创建一个对象

class Person{     public name:string;     public age:number;     constructor(name:string, age:number){         this.name = name;         this.age = age;     } } let a = new Person("测试", 15);  console.log(a.name  + " --- " + a.age) 

TypeScript の 类  接口

继承

class NewPerson extends Person{     public sex: number;     constructor(sex: number){         this.sex = sex;     } } 

TypeScript の 类  接口

由图可见,上面的继承是不正常的,所以这里需要调用其super方法

class NewPerson extends Person{     public sex: number;     constructor(name:string,age:number,sex: number){         super(name,age);         this.sex = sex;     } } 

TypeScript の 类  接口

私有属性

class PrivatePerson{     private name:string;     constructor(name:string){         this.name = name;     } }  let c = new PrivatePerson("wz"); console.log(c.name) // 提示报错 

TypeScript の 类  接口

这个就是私有属性,那么我们该怎么访问这个私有属性呢?
class PrivatePerson{     private name:string;     constructor(name:string){         this.name = name;     }     get getName(){         return this.name;     } }  let c = new PrivatePerson("wz"); console.log(c.getName) 

通过上述的get修饰的属性(看起来更像一个方法),便可以获取到私有属性,最后可以通过c.getName获取到

get获取属性,那么是否有set设置属性呢???
class PrivatePerson{     private name:string;     constructor(name:string){         this.name = name;     }     get getName(){         return this.name;     }     set setName(name: string){         this.name = name     } }  let c = new PrivatePerson("wz"); console.log(c.getName) c.setName = "哈哈";  console.log(c.getName) 

通过上面set的案例,我们应该清楚的看到,其实getset修饰的都不是方法,而是属性,因为方法的调用fn(),而这个看起来更像是属性的写法,所以这里注意c.setName = "哈哈",既然这样,为了美观,我们将上面的进行一个修改

class PrivatePerson{     private _name:string;     constructor(name:string){         this._name = name;     }     get name(){         return this._name;     }     set name(name: string){         this._name = name     } }  let c = new PrivatePerson("wz"); console.log(c.name) c.name = "哈哈";  console.log(c.name) 

这样看起来就完全一样了

私有属性作用是什么呢?
实现单例模式
class SimpleObject {     //静态方法中只能调用静态变量     private static simpleInfo: SimpleObject;          //私有化构造函数,让其无法被外界`new`出来     private constructor(){}          //提供公共的静态的获取实例方法     public static getInstance(){         //判断实例是否存在         if(!this.simpleInfo){             //不存在就实例化一个             this.simpleInfo = new SimpleObject();         }         //返回实例         return this.simpleInfo;     } } 

以上的单例模式很简单,但是也需要注意几个小点

  • 因为我们需要实现"单例模式",所以必须要限制实例化的方式,只能由我们内部提供,所以将构造函数私有化,在前面加上private
  • 获取实例方法: 因为我们把构造函数constructor私有化了,所以外部无法使用new关键字实例化对象,我们必须要提供的获取实例方法getInstance必须可以在不实例化的情况下调用,所以这个方法必须使用static修饰
  • 静态方法只能访问静态的数据,所以这里的实例simpleInfo也是静态的,并且为了不让其被外部直接调用,所以加上private
实现部分属性只能获取,而无法修改
  • 私有属性实现
class PriPerson{     private _name:string;     constructor(name :string){         this._name = name;     }     get name(){         return this._name     } } let e = new PriPerson("一个人"); console.log(e.name)  e.name = "不可修改" //报错 
  • readonly实现
class PriPerson{     public readonly name:string;          constructor(name :string){         this.name = name;     }  } let e = new PriPerson("一个人"); console.log(e.name) e.name = "不可修改" //报错 

抽象类

有时候需要分类,同一类事物有着公共的特性,公共的方法(但是每个之间实现不同),这个时候我们就可以定义个抽象类,抽出相同的,相同的方法

abstract class Animal{      getEatOrgan(){         return "嘴";     }      abstract eat():string; }  class People extends Animal{     eat(){         return "使用手抓吃饭";     }  } class Pig extends Animal{     eat(){         return "使用嘴拱着吃";     } }  let animals : [string, string] = ["man", "pig"];  animals.forEach((animal) => {     let unknownAnimal:Animal;     unknownAnimal = animal === "man" ? new People() : new Pig();      console.log("吃饭通用器官:" + unknownAnimal.getEatOrgan(),      "各自吃饭方式: " + unknownAnimal.eat());   })  

结果
TypeScript の 类  接口

接口的继承

我们常常会定义一些接口,用于类型定义及检测,像下面一样

interface Student{     name:string,     age:number }  interface Teacher{     name:string,     sex:string }  const sayHello = (user) => {     console.log(user.name) } let st: Student ={     name: '张珊',     age:18 }  let te :Teacher = {     name:"历史",     sex:"男" } sayHello(st); sayHello(te); 

但是我们发现,sayHello中参数user的推断类型是
TypeScript の 类  接口

这个不是我们想要的,所以我们去定义这个user的类型,用什么呢?是Student还是Teacher,当然是我全都要了

 const sayHello = (user: Student | Teacher) => {     console.log(user.name) } 
思考,当我们新建对象的时候,这个参数类型是不是一直在添加呢?

这个时候就需要使用我们的接口继承(提取出相同的属性,方法,然后其他子类继承该接口)

interface Person{     name:string }  interface Student extends Person{      age:number }  interface Teacher  extends Person{      sex:string }  const sayHello = (user:Person) => {     console.log(user.name) } let st: Student ={     name: '张珊',     age:18 }  let te :Teacher = {     name:"历史",     sex:"男" } sayHello(st); sayHello(te);