Typescript中类的基本方法

142 阅读4分钟

Typescript中的类

readonly为只读属性,不能对其进行修改.static为静态属性,只能通过类的属性去访问,不能通过实例的属性去访问.

class Person {
  // 定义属性
 readonly name:string = '孙悟空';
  // 静态属性只能通过类的属性去访问
 static age:number = 10;
  info(){
  }
}
// 类中主要包含两部分  属性和方法
const per = new Person()
console.log(per.info)    // info() {} 
console.log(Person.age)  //10
// per.name = '白'       //报错  readonly为只读属性
console.log(per.name)    //孙悟空

class info{
  name = '猪八戒';
  age=10;
  static sayHello(){
    console.log('hello 大家好!!!!!!!!!!!')
  }
}

const per2 = new info()
per2.sayHello()     //报错 静态属性只能通过类的属性去访问
info.sayHello()     //hello 大家好!!!!!!!!!!!

constructor构造函数,对象创建时调用

class Person2{
  name:string;
  age:number;
  // 构造函数 对象创建时调用
  constructor(name:string,age:number){
    this.name = name
    this.age = age
    console.log('constructor被调用了.')
  };
  bark(){
    console.log('玩哇哇哇!')
  }
}

const pe = new Person2('旺财',10)      //constructor被调用了.
const pe2 = new Person2('小花',10)     //constructor被调用了.
const pe3 = new Person2('哈普',5)      //constructor被调用了.
const pe4 = new Person2('宙斯',6)      //constructor被调用了.
console.log(pe.bark())                 //玩哇哇哇!
console.log(pe2)                       //Person2: {"name": "旺财","age": 10} 
console.log(pe3.bark())                //玩哇哇哇!
console.log(pe4)                       ////Person2: {"name": "宙斯","age": 6} 

继承:子类继承父类的属性和方法. 子类可以对父类的方法进行重写并且可以添加新的方法.

super:调用父类的构造函数和方法.

// 继承
class Animal{
  name:string;
  age:number;
  constructor(name:string,age:number){
    this.name = name
    this.age = age
  };
  sayHello(){
    console.log('动物在叫!!')
  };
  run(){
    console.log('动物再跑!')
  }
}


/*class Dog{
  name:string;
  age:number;
  constructor(name:string,age:number){
    this.name = name
    this.age = age
  };
  sayHello(){
    console.log('汪汪汪!!')
  }
}*/

// dog继承 Animal
class Dog extends Animal{
  sayHello(){
    console.log('汪汪汪!!')
  };
  run(){
    console.log(`${this.name}再跑!`)
  }
}

/*class Cat{
  name:string;
  age:number;
  constructor(name:string,age:number){
    this.name = name
    this.age = age
  };
  sayHello(){
    console.log('喵喵喵!!')
  }
}*/

// cat继承 Animal
class Cat extends Animal{
  // 方法的重写
  sayHello(){
    console.log('喵喵喵!!')
  }
}

const dog = new Dog('旺财',5)
console.log(dog)
dog.sayHello()
dog.run()

const cat = new Cat('咪咪',3)
console.log(cat)
cat.sayHello()

// super
class Dog1 extends Animal{
  sex:string;
  constructor(name:string,age:number,sex:string){
    super(name,age) //调用父类的构造函数
    this.sex = sex
  };
  sayHello(){
    // super 调用父类中的方法
    super.sayHello();
    super.run();
    console.log(`${this.name}再叫!`);
  }
}
const dog1 = new Dog1('旺财',5,'male')
console.log(dog1)
dog1.sayHello()

abstract: 定义抽象类

抽象类: 抽象类不能实例化

抽象方法: 子类必须对抽象方法进行重写

// 抽象类和抽象方法
// 抽象类不能实例化
abstract class Animal2{
  name:string;
  constructor(name:string){
    this.name = name
  };
  // sayHello(){
  //   console.log('动物再叫!!')
  // }

  // 抽象方法  子类必须对抽象方法就行重写
  abstract sayHello():void;
}

class Dog2 extends Animal2{
  //不重写会报错
  sayHello(){
    console.log('汪汪汪')
  }
}

class Cat2 extends Animal2{
 sayHello(){
    console.log('喵喵喵!!')
  }
}

接口

//接口

// 描述一个对象的类型
type myType  =  {
  name:string,
  age:number
}
// 不允许重复定义
// type myType = {

// }

// 接口用来定义一个类结构
// 允许重复定义
interface myInstance{
  name:string;
  age:number
}
interface myInstance{
  gender:String
}


const obj:myInstance={
  name:'梨花',
  age:10,
  gender:'女'
}

// 接口能够限制结构
// 接口中的所有值都不能有实际值
// 接口中的所有方法都是抽象方法
interface myInter{
  name:string;
  sayHello():void;
}

//定义类时,可以去实现一个接口
class myClass implements myInter{
  name:string;
  constructor(name:string){
    this.name = name
  };
  sayHello(){

  }
}

public private protected

public 修饰的属性可以在任意位置(包括子类)访问(修改) 默认值
private 私有属性,私有属性只能在类的内部进行访问(修改)
protected 受保护的属性,只能在类和其子类中访问
//定义一个类
class Person{
    // public 修饰的属性可以在任意位置(包括子类)访问(修改) 默认值
    // private 私有属性,私有属性只能在类的内部进行访问(修改)
    // protected 受保护的属性,只能在类和其子类中访问
    protected name:string;
    public age:number;
    constructor(name:string,age:number){
        this.name = name
        this.age = age
    }

}

const per = new Person('孙悟空',18)
console.log(per)     //Person: {"name": "孙悟空","age": 18} 

//现在属性是在对象中设置的.属性值可以被任意修改.
//属性值可以被任意修改会导致对象中的数据非常不安全.
// per.name = '猪八戒' //不能访问
per.age = -10
console.log(per)     //Person: {"name": "猪八戒","age": -10} 

class A extends Person{
    test(){
        console.log(this.name)
    }
}
// per.name = '猪八戒' //不能访问
const a = new A('李白',20)
a.test()   // 李白



//定义一个类
class Person{
    private _name:string;
    private _age:number;
    constructor(name:string,age:number){
        this._name = name
        this._age = age
    }

    /*
      getter方法: 用来获取属性
      setter方法: 用来设置属性
            --他们被称为属性的存取器
    */
    //定义方法 用来获取name的值
    // getName(){
    //     return this._name
    // }

    // // 定义方法 用来修改name的值
    // setName(value:string){
    //     this._name = value
    // }

    // getAge(){
    //     return this._age
    // }

    // setAge(age:number){
    //     // 逻辑判断
    //     if(age<0) return console.log('错误!')
    //     this._age = age
    // }

    // TS 中设置getter和setter的方法
    get name(){
        return this._name
    }

    set name(val:string){
        this._name = val
    }

    get age(){
        return this._age
    }

    set age(val:number){
        if(val>=0){
            this._age = val
        }
    }
}

const per = new Person('孙悟空',18)
console.log(per)     //Person: {"name": "孙悟空","age": 18} 

//现在属性是在对象中设置的.属性值可以被任意修改.
//属性值可以被任意修改会导致对象中的数据非常不安全.
// per._name = '猪八戒'    //私有属性不再能直接修改
// per._age = -10
// console.log(per)     //Person: {"name": "猪八戒","age": -10} 

// per.setName('猪八戒')
// per.setAge(-33)

per.name = '猪八戒'
per.age = 5
per.age = -10
console.log(per)  //Person: {"_name": "猪八戒","_age": 5} 

简写方式 C1和C2类等价

//  C1 和 C2 等价
class C1{
    name:string;
    age:number;
    constructor(name:string,age:number){
        this.name = name
        this.age = age
    }
}

class C2{
    // 可以直接将属性定义在构造函数中
    constructor(public name:string,public age:number){}
}

泛型 在定义函数或类时.如果遇到类型不明确就可以使用泛型.

// any会跳过类型检查
function fn(a:any):any{
    return a
}

/* 
    在定义函数或类时.如果遇到类型不明确就可以使用泛型.
*/


function fn1<T>(a: T): T{
    return a
}

//可以直接调用具有泛型的函数
let f1 = fn1(10)  //不指定泛型,TS自动推断
let f2 = fn1<string>('hello') //指定泛型

function fn2<T,K>(a:T,b:K):T{
    console.log(b)
    return a
}
let f3 = fn2<number,string>(123,'hello')



interface Inter {
    length:number
}
// T extends Inter 表示泛型必须是 Inter 实现类(子类)
function fn3<T extends Inter>(a: T):T{
    return a
}

class MyClass<T>{
    name:T;
    constructor(name:T){
        this.name = name
    }
}
const per = new MyClass<string>('孙悟空')
console.log(per)