Loading

ts-类和接口

override继承

class  Info{
    name:string
    age:number

    constructor(name:string,age:number) {
        this.name = name
        this.age = age
    }
    info(){
        console.log(this.name,this.age)
    }
}



class User extends  Info{
    ext:string
    constructor(name:string,age:number,ext:string) {
        super(name,age);
        this.ext = ext
    }


    // 重写方法,可以使用override关键字重写方法,也可以与js一样直接重写方法,不使用关键字
    // 使用关键字可以提高代码的可读性和可维护性,编译时会进行检查父类中不存在对应的可重写方法,会进行报错
    override info() {
        console.log(this.name,this.age,this.ext)
    }
}

属性修饰符

public修饰符

公开的,可以被类内部、子类、类外部访问


class  Info{
    // 公开属性
    public name:string
    // 不写修饰符,默认是public
    age:number

    constructor(name:string,age:number) {
        this.name = name
        this.age = age
    }
}



class User extends  Info{
    ext:string
    constructor(name:string,age:number,ext:string) {
        super(name,age);
        this.ext = ext
    }
    info(){
        // 子类可以访问public属性
        console.log(this.name,this.age)
    }

}
const i = new Info("l",11)
// 类外部可以访问public属性
console.log(i.name,i.age)
属性简写
// 属性简写
class  Info{
    //在 构造方法的参数列表 定义修饰类型、变量名、变量类型
    constructor(public name:string,public age:number) {

    }
    info(){
        // 与完整写法调用一致
        console.log(this.age,this.name)
    }
}

上面代码等同于

class  Info{
    public name:string
    public age:number
    constructor(name:string,age:number) {
        this.name = name
        this.age = age

    }
    info(){
        console.log(this.age,this.name)
    
protected

受保护的,可以被类内部、子类访问


class  Info{

    // name和age是受保护属性,只能在类和子类中访问,不能在类外部访问
    constructor(protected name:string,protected age:number) {


    }
    // 受保护的方法,只能在类和子类中调用,不能在类外部调用
    protected info(){
        // 类中访问受保护属性
        console.log(this.age,this.name)
    }

    // 公开方法
    test(){
        this.info()

    }
}

const i = new Info("1",1)
// 可以在类外部访问test,间接调用info和属性,不能直接调用info和属性
i.test()
private

私有的,可以被类内部访问

class  Info{

    // name是私有属性,只能在类内部使用属性,子类和外部无法使用
    constructor(private name:string) {


    }
    
    // 私有方法,只能在类内部调用,子类和外部无法使用
    private info(){
        console.log(this.name)
    }

}
readonly

只读属性,属性无法修改


class  Info{

    // 公开、只读属性,内外部都可以访问,但是无法修改
    constructor(public  readonly name:string) {


    }

    // 私有方法,只能在类内部调用,子类和外部无法使用
    info(){
        console.log(this.name)
    }

}




const c = new Info("1")

// 可以访问
console.log(c.name) 
c.name = "333" // 修改赋值会报错

抽象类

抽象类是⼀种⽆法被实例化的类,专⻔⽤来定义类的结构和⾏为,类中可以写抽象 ⽅法,也可以写具体实现。抽象类主要⽤来为其派⽣类提供⼀个基础结构,要求其派⽣类 必须实现其中的抽象⽅法

抽象类不能实例化,其意义是可以被继承,抽象类⾥可以有普通⽅法、也可以有抽 象⽅法

使用abstract关键字定义抽象类和方法

// 抽象类
abstract class Shop {

    constructor(public price: number, public weight: number) {
    }


    // 抽象方法 定义参数类型、返回值类型,内部不需要实现,不同的type类型有不同的计算方式
    abstract calculate(type: number): number


    //
    printPrice(type: number) {
        console.log(this.price, this.weight, this.calculate(type))
    }


}

// 抽象类无法实例化,需要子类继承使用
// 抽象方法 必须在子类实现内部逻辑

class UserShop extends Shop{
    constructor(public price: number, public weight: number) {
        super(price,weight);
    }

    // 实现抽象方法
    calculate(type: number): number {
        if (type >= 10){
            return this.weight*this.price *0.8

        }else {
            return  this.price *this.weight
        }

    }

}

const user = new UserShop(10,10)
user.printPrice(10)

使用抽象类:

  1. 定义通用接口:为⼀组相关的类定义通⽤的⾏为(⽅法或属性)
  2. 提供基础实现 :在抽象类中提供某些⽅法或为其提供基础实现,这样派⽣类就可以继承这 些实现
  3. 确保 关键实现:强制派⽣类实现⼀些关键⾏为
  4. 共享代码和逻辑:当多个类需要共享部分代码时,抽象类可以避免代码重复

interface(接口)

interface 是⼀种定义结构的⽅式,主要作⽤是为:类、对象、函数等规定⼀种契约,这样 可以确保代码的⼀致性和类型安全,interface 只能定义格式,不能包含任何实 现 !

类结构
// 定义一个接口,限制类的格式
// 类中需要有对应类型name、age属性,info方法,参数和返回值类型也需要一致,否则会报错
interface UserInterface {
    name:string
    age:number
    info(t:number):string

}


// 定义User类,实现UserInterface接口,使用implements关键字关联类和接口
// 一个类可以实现多个接口,implements a,b,c
class  User implements UserInterface{
    constructor(public name:string,public age:number) {}

    info(t:number):string {
        console.log(t)
        return this.name
    }
}
对象结构

// 定义对象结构接口
interface UserInterface{
    name:string
    age?:number // 可选属性
    readonly gender:string // 只读属性
    info:(n:number) => void // info方法,number参数和void返回值
}


// 实现对象结果接口,对象名:接口名 = {}
const user: UserInterface = {
    name:"a",
    gender:"3",
    info(n:number){
        console.log(n)
    }
}
函数结构
// 定义函数接口
interface UserInterface {
    (a: number, b: number): number
}


// 实现函数接口
const user: UserInterface = (a: number, b: number) => {
    return a + b

}
接口继承
interface UserInterface {
    name:string
    age:number
}


// 使用extends继承
interface  InfoInterface extends UserInterface {
    // 不能重写属性类型,可以写新属性
    f:string
}
接口自动合并
interface UserInterface {
    name:string
    age:number
}



// 给UserInterface接口添加新属性、方法
interface  UserInterface {
    gender:string
    info():string
    
}
使用场景
  1. 定义对象的格式: 描述数据模型、API 响应格式、配置对象........等等,是开发中⽤的最多 的场景
  2. 类的契约:规定⼀个类需要实现哪些属性和⽅法。
  3. 扩展已有接⼝:⼀般⽤于扩展第三⽅库的类型, 这种特性在⼤型项⽬中可能会⽤到。
interface和type的区别

相同点:

  1. interface 和 type 都可以⽤于定义对象结构,在定义对象结构时两者可以互换

不同点:

  1. interface :更专注于定义对象和类的结构,⽀持继承、合并。
  2. type :可以定义类型别名、联合类型、交叉类型,但不⽀持继承和⾃动合并
interface和抽象类的区别

相同点:

  1. 都能定义⼀个类的格式(定义类应遵循的契约)

不相同:

  1. 接⼝:只能描述结构,不能有任何实现代码,⼀个类可以实现多个接⼝。
  2. 抽象类:既可以包含抽象⽅法,也可以包含具体⽅法, ⼀个类只能继承⼀个抽象类。
posted @ 2024-11-07 11:53  木子七  阅读(9)  评论(0编辑  收藏  举报