1、接口(interface)

接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。

a、接口属性

// 接口interface
// 1、属性接口
interface full_name {
  firstName: string;
  secondName: string;
}
// 对批量参数的类型约束
function log_name(name:full_name): void {
  console.log(`${name.firstName}&${name.secondName}`);
}
//直接传参的时候传入的对象的格式需要严格满足接口的规范
log_name({firstName:'tom',secondName:'jerry'})		//tom&jerry

let obj = {
  firstName: "tom",
  secondName: "jerry",
  age:12
};
//传入一个包装的对象的话,必须包含接口所要求的字段即可
log_name(obj);

b、接口的可选属性

interface full_name {
  firstName: string;
  //这样表示secondName可传可不传
  secondName ?: string;
}
function log_name(name: full_name): void {
  console.log(`${name.firstName}&${name.secondName}`);
}

log_name({ firstName: "tom"});		//tom&undefined

c、函数类型接口

//函数类型接口对方法传入的参数,以及返回值进行约束
interface func {
  (key:string,value:string):string
}
let md:func = function(key,value){
  return `${key}${value}`
}
console.log(md('张三','李四'));		//张三李四

d、可索引接口

//可索引接口  :对数组和对象的约束(不常用)
interface arr_obj {
  [index:number]:string
}

let arr:arr_obj = ['hello','world']
//取值的时候索引为number类型,数组元素是string类型
console.log(arr[0]);	//hello

e、类类型接口

//类类型接口和抽象类有点像,也是一种规范
interface Animal {
  name: string;
  eat(str: string): void;
}
//这里用的是 implements  ,继承使用的是extends
class Dog implements Animal{
  name:string
  constructor(name:string){
    this.name = name
  }
  //你可以不给eat传递参数,但是要实现eat方法
  eat(){
    console.log(`${this.name}爱吃肉`);
    
  }
}
let dog = new Dog('小狗')
dog.eat()

f、接口的扩展

//接口的扩展
interface Animal{
  eat():void
}
interface Dog extends Animal{
  work():void
}

class middle_dog {
  name:string
  constructor(name:string){
    this.name = name
  }
  coding():void{
    console.log(`${this.name}在敲代码`);
    
  }
}
//可以在实现类的继承的同时进行类类型接口
class dog extends middle_dog implements Dog{
  constructor(name:string){
    super(name)
  }
  eat():void{
    console.log(`${this.name}吃吃吃`);
    
  }
  work():void{
    console.log(`${this.name}在搬砖`);
    
  }
}
let d1 = new dog('小狗')
d1.eat()
d1.work()
d1.coding()
//小狗吃吃吃
//小狗在搬砖
//小狗在敲代码

2、类(class)

a、类的声明

// 类的声明
class Person {
  name: string;
  constructor(name: string) {
    this.name = name;
  };
  getName(): string {
    return this.name
  }
  setName(name:string) {
     this.name = name
  }
}
let tom = new Person('tom')
console.log(tom.getName());		//tom
tom.setName('Jerry');
console.log(tom.getName());		//Jerry

b、类的继承

// 类的继承  extends 、super
class Person {
  name: string;
  constructor(name: string) {
    this.name = name;
  };
  run():string{
    return `${this.name}在运动`
  }
}
let p = new Person('张三')
console.log(p.run());		//张三在运动

class Student extends Person{
  constructor(name:string){
    super(name)
  }
  work():string{
    return `${this.name}在工作`
  }
  //子类如果有与父类相同的方法,会覆盖父类的方法
}
let s = new Student('李四')
console.log(s.run());		//李四在运动
console.log(s.work());		//李四在工作

c、类的修饰符

//public  		公有属性,在类里面、子类中、类外面都能访问
//protected 	保护类型,在类里面、子类中可以访问
//private		私有属性,只能在类里面访问

//属性修饰符
class Person {
  name: string;
  protected age: number;
  private sex: string;
  constructor(name: string, age: number, sex: string) {
    this.name = name;
    this.age = age;
    this.sex = sex;
  }
  run(): string {
    return `${this.name}在运动${this.age}${this.sex}`;
  }
}
let p = new Person("张三", 23, "男");
console.log(p.run());
console.log(p.name);
console.log(p.age);
console.log(p.sex);

class Student extends Person {
  constructor(name: string, age: number,sex: string) {
    super(name,age,sex);
  }
  // 子类自己的方法
  work(): string {
    return `${this.name}在工作${this.age}${this.sex}`;
  }
}
let s = new Student("李四", 13,'女');
console.log(s.run());
console.log(s.work());
console.log(s.name);
console.log(s.age);
console.log(s.sex);

从下图中可以看到属性修饰符的不同作用

typescript interface 改写父 typescript class interface_抽象类

d、类的静态属性和静态方法

class Person {
  name: string;
  // 静态属性
  static age:number
  constructor(name: string,) {
    this.name = name;
  };
  // 实例方法
  getName(): string {
    return this.name
  }
  setName(name:string) {
     this.name = name
  }
  // 静态方法方法中只能调用静态属性
  static sayHello():string{
    //return `静态方法调用不了声明的属性${this.name}`
    return `静态方法调用不了声明的属性${this.age}`
  }
}


let tom = new Person('tom')
console.log(tom.getName());		//tom
tom.setName('Jerry');
console.log(tom.getName());		//Jerry


// 实例对象调用静态方法和静态属性会报错
// console.log(tom.sayHello());
// tom.age = 12
// console.log(tom.age);		
Person.age = 12
console.log(Person.sayHello());
console.log(Person.age);

e、多态:父类定义一个基础方法,让继承的每个子类实现不同的功能

class Animal {
  name:string;
  constructor(name:string){
    this.name = name
  }
  eat(){
    console.log(`吃的方法`);
    
  }
}

class Dog extends Animal{
  constructor(name:string){
    super(name)
  }
  eat(){
    return this.name + `吃肉`
  }
}

class Cat extends Animal{
  constructor(name:string){
    super(name)
  }
  eat(){
    return this.name + `吃鱼`
  }
}

f、抽象方法抽象类

// 抽象类、抽象方法:使用abstract关键字定义,抽象方法只能放在抽象类中
// 抽象类和抽象方法用来定义标准,Animal这个父类要求他的子类必须有eat方法
abstract class Animal {
  name:string;
  constructor(name:string){
    this.name = name
  }
  abstract eat():any
  // 非抽象方法子类可以不实现
  run():string{
    return this.name+`在跑步`
  }
}

class Dog extends Animal{
  constructor(name:string){
    super(name)
  }
  // 抽象类的子类必须实现抽象类的抽象方法
  eat(){
    return this.name + `吃肉`
  }
}

let dog = new Dog('小狗')
console.log(dog.eat());		//小狗吃肉