Ts初识3

142 阅读7分钟

Ts的interface接口

初步了解

const screenResume = (name: string, age: number, bust: number) => {
  age < 24 && bust >= 90 && console.log(name + "进入面试");
  age > 24 || (bust < 90 && console.log(name + "你被淘汰"));
};
const getResume = (name: string, age: number, bust: number) => {
  console.log(name + "年龄是:" + age);
  console.log(name + "胸围是:" + bust);
};
getResume("大脚", 18, 94);
screenResume("大脚", 18, 94);

类型别名的知识可以解决代码重复的问题,一个更常用的语法接口(Interface)也可以解决.

我们可以把这两个重复的类型注解,定义成统一的接口。代码如下:

interface Girl {
  name: string;
  age: number;
  bust: number;
}

有了接口后,我们的程序也要作一些修改,需要写成下面的样子。这样就更像是面向对象编程了。

const screenResume = (girl: Girl) => {
  girl.age < 24 && girl.bust >= 90 && console.log(girl.name + "进入面试");
  girl.age > 24 || (girl.bust < 90 && console.log(girl.name + "你被淘汰"));
};

const getResume = (girl: Girl) => {
  console.log(girl.name + "年龄是:" + girl.age);
  console.log(girl.name + "胸围是:" + girl.bust);
};
const girl = {
  name: "大脚",
  age: 18,
  bust: 94,
};

screenResume(girl);
getResume(girl);

接口和类型别名的区别

类型别名可以直接给类型,比如string,而接口必须代表对象

别名可以这样 type Girl1 = stirng;

但是接口就不能这样写,它必须代表的是一个对象,也就是说,你初始化girl的时候,必须写出下面的形式.

const girl = {
 name: "大脚",
 age: 18,
 bust: 94,
};

接口非必选值得定义

:号前加一个?

interface Girl {
 name: string;
 age: number;
 bust: number;
 waistline?: number;
}

这时候在定义girl对象的时候,就可以写saistline,也可以不写了。

允许加入任意值

interface Girl {
 name: string;
 age: number;
 bust: number;
 waistline?: number;
 [propname: string]: any;
}

这个的意思是,属性的名字是字符串类型,属性的值可以是任何类型。

接口里的方法

接口里不仅可以存属性,还可以存方法,比如这时候有个say()方法,返回值是string类型。

interface Girl {
 name: string;
 age: number;
 bust: number;
 waistline?: number;
 [propname: string]: any;
 say(): string;
}

此时我们就要给对象一个 say 方法

const girl = {
 name: "大脚",
 age: 18,
 bust: 94,
 waistline: 21,
 sex: "女",
 say() {
   return "欢迎光临 ,红浪漫洗浴!!";
 },
};

接口和类的约束

class XiaoJieJie implements Girl {}

这时候类会直接报错,所以我们需要把这个类写的完全点。

class XiaoJieJie implements Girl {
 name = "娜美";
 age = 18;
 bust = 90;
 say() {
   return "欢迎光临 ,红浪漫洗浴!!";
 }
}

接口间的继承

interface Teacher extends Girl {
 teach(): string;
}

为这时候传的值必须有teach方法,

const girl = {
 name: "大脚",
 age: 18,
 bust: 94,
 waistline: 21,
 sex: "女",
 say() {
   return "欢迎光临 ,红浪漫洗浴!!";
 },
 teach() {
   return "我是一个老师";
 },
};

getResume(girl);

Ts中的类

类的基本使用

class Lady {
 content = "Hi,帅哥";
 sayHello() {
   return this.content;
 }
}

const goddess = new Lady();
console.log(goddess.sayHello());

类的继承

这里提前说一下 TypeScrip 的继承和ES6中的继承是一样的。关键字也是extends

class Lady {
 content = "Hi,帅哥";
 sayHello() {
   return this.content;
 }
}
class XiaoJieJie extends Lady {
 sayLove() {
   return "I love you";
 }
}

const goddess = new XiaoJieJie();
console.log(goddess.sayHello());
console.log(goddess.sayLove());

super 关键字的使用

我们再多讲一点,就是super关键字的使用,比如我们还是想使用Lady类中说的话,但是在后面,加上你好两个字就可以了。这时候就可以使用super关键字,它代表父类中的方法。那我们的代码就可以写成这个样子了。

class XiaoJieJie extends Lady {
 sayLove() {
   return "I love you!";
 }
 sayHello() {
   return super.sayHello() + "。你好!";
 }
}

TypeScript 中类的访问类型

类的访问类型就是基于三个关键词private、protected和public,也是三种访问类型

public 访问属性讲解

public从英文字面的解释就是公共的或者说是公众的,在程序里的意思就是允许在类的内部和外部被调用.默认不加类型注释为public

class Person {
   public name:string;
}

private 访问属性讲解

private 访问属性的意思是,只允许再类的内部被调用,外部不允许调用.

比如现在我们把name属性改成private,这时候在类的内部使用不会提示错误,而外部使用VSCode直接会报错。

class Person {
   private name:string;
   public sayHello(){
       console.log(this.name + 'say Hello')  //此处不报错
   }
}
//-------以下属于类的外部--------
const person = new Person()
person.name = 'jspang.com'    //此处报错
person.sayHello()
console.log(person.name)  //此处报错

protected 访问属性讲解

protected 允许在类内继承的子类中使用

做一个例子,把name的访问属性换成protected,这时候外部调用name的代码会报错,内部的不会报错,和private一样。这时候我们再写一个Teacher类,继承于Person,代码如下:

class Person {
   protected name:string;
   public sayHello(){
       console.log(this.name + 'say Hello')  //此处不报错
   }
}

class Teacher extends Person{
   public sayBye(){
       this.name;
   }
}
这时候在子类中使用this.name是不报错的。

Ts 类的构造函数

类的构造函数

class Person{
   public name :string ;
   constructor(name:string){
       this.name=name
   }

}

const person= new Person('jspang')
console.log(person.name)

最常规和好理解的写法:

class Person{
   constructor(public name:string){
   }
}

const person= new Person('jspang')
console.log(person.name)

这种写法就相当于你定义了一个name,然后在构造函数里进行了赋值,这是一种简化的语法.

类继承中的构造器写法

普通类的构造器我们已经会了,在子类中使用构造函数需要用super()调用父类的构造函数。

class Person{
   constructor(public name:string){}
}

class Teacher extends Person{
   constructor(public age:number){
       super('jspang')
   }
}

const teacher = new Teacher(18)
console.log(teacher.age)
console.log(teacher.name)

这就是子类继承父类并有构造函数的原则,就是在子类里写构造函数时,必须用super()调用父类的构造函数,如果需要传值,也必须进行传值操作。就是是父类没有构造函数,子类也要使用super()进行调用,否则就会报错。

class Person{}

class Teacher extends Person{
    constructor(public age:number){
        super()
    }
}

const teacher = new Teacher(18)
console.log(teacher.age)

类的 Getter、Setter 和 static 使用

类的 Getter 和 Setter

类的访问类型private,那这个东西如何使用?其实他的最大用处是封装一个属性,然后通过 GetterSetter的形式来访问和修改这个属性。

class Xiaojiejie {
  constructor(private _age:number){}
}

如果别人想知道,就必须通过getter属性知道,注意我这里用的是属性,对他就是一个属性。getter属性的关键字是get,后边跟着类似方法的东西,但是你要注意,它并不是方法,归根到底还是属性。

class Xiaojiejie {
  constructor(private _age:number){}
  get age(){
      return this._age
  }
}

const dajiao = new Xiaojiejie(28)

console.log(dajiao.age)

玄妙就在于getter里,我们可以对_age进行处理,比如别人问的时候我们就偷摸的减少 10 岁。

class Xiaojiejie {
 constructor(private _age:number){}
 get age(){
     return this._age-10
 }
}

_age是私有的,那类的外部就没办法改变,所以这时候可以用setter属性进行改变,代码如下:

 set age(age:number){
   this._age=age+3
 }

这是想通过这个例子让小伙伴们清楚的明白gettersetter的使用,很多小伙伴刚学这部分,都不太清楚为什么要使用gettersetter ,你也能更清楚private访问类型的意义。

类中的 static

class Girl {
 sayLove() {
   return "I Love you";
 }
}

const girl = new Girl();
console.log(girl.sayLove());

但是现在你不想new出对象,而直接使用这个方法,那TypeScript为你提供了快捷的方式,用static声明的属性和方法,不需要进行声明对象,就可以直接使用,代码如下。

class Girl {
 static sayLove() {
   return "I Love you";
 }
}
console.log(Girl.sayLove());

这节课我们就学到了这里,复习一下,我们学了private的使用意义,学了gettersetter属性,还学习了静态修饰符static,这样就不用 new 出对象就可以使用类里的方法了。

类的只读属性和抽象类

只读属性

这时候就可以用一个关键词readonly,也就是只读的意思,来修改Person类代码。

class Person {
   public readonly _name :string;
   constructor(name:string ){
       this._name = name;
   }
}

const person = new Person('jspang')
person._name= '谢广坤'
console.log(person._name)

这样写完后,VSCode就回直接给我们报错,告诉我们_name属性是只读属性,不能修改。

抽象类

抽象类的关键词是abstract,里边的抽象方法也是abstract开头的,现在我们就写一个Girl的抽象类。

abstract class Girl{
    abstract skill()  //因为没有具体的方法,所以我们这里不写括号

}

有了这个抽象类,三个类就可以继承这个类,然后会要求必须实现skill()方法,代码如下:

abstract class Girl{
    abstract skill()  //因为没有具体的方法,所以我们这里不写括号

}

class Waiter extends Girl{
    skill(){
        console.log('大爷,请喝水!')
    }
}

class BaseTeacher extends Girl{
    skill(){
        console.log('大爷,来个泰式按摩吧!')
    }
}

class seniorTeacher extends Girl{
    skill(){
        console.log('大爷,来个SPA全身按摩吧!')
    }
}