TypeScript面向对象(笔记)

文章目录

      • 1. 什么是面向对象
      • 2. class 类
        • 2.1构造函数 constructor 和this
        • 2.2 继承 extends
        • 2.3 抽象类 abstract
        • 2.4 接口 interface
        • 2.5 属性的封装
        • 2.6 泛型

1. 什么是面向对象

  • 万物皆是对象,对象有属性和方法,拿人来举例:人的姓名、年龄、性别等这些都是属性,属性可以通过点属性的形式去获取,人可以吃东西、走路、唱歌等这些都是方法,方法可以通过点方法括号的形式去调用
  • 举例来说
    • 操作浏览器要使用window对象
    • 操作网页要使用document对象
    • 操作控制台要使用console对象

2. class 类

2.1构造函数 constructor 和this

class 类名 {
  // static开头 静态属性(类属性),默认属性是需要对象的实例去访问,静态属性是直接通过类去访问
  static 属性名: 类型
  // readonly开头 只读
  readonly 属性名: 类型
  // static在前readonly在后
  static readonly 属性名: 类型
  
  // 在构造函数中使用this.属性名的时候类中要有这个属性才行(js可以没有,但是ts要有)
  constructor(实参: 类型){
    // 在实例中this指向当前实例
    // 在构造函数中指向当前类
    this.属性名 = 参数
  }
    
  方法名(){
    ...
  }
}

let 变量 = new 类名(形参)

2.2 继承 extends

// extends 继承,为什么要使用继承?
// 打个比方动物都有很多相同的特征但是种类又不一样,这个时候可以用一个动物的总类把相同的特征都写在里面
// Animal是一个动物类,使用 Dog extends Animal 表示小狗类继承了动物类
// 继承后的类拥有父类所有的属性和方法
// 如果希望在子类添加一些父类没有的属性和方法直接就可以了
// 如果希望覆盖掉父类的一些方法,直接子类的方法和父类相同即可(方法重写)
// 如果子类写了constructor,需要用个super关键字(super表示当前类的父类)
// 需要把父类和当前类的参数都写入constructor()中
// 父类的参数还要在写入super()中
class Animal {
  name: string
  age: number
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
  say() {
    console.log("动物在叫~~");

  }
}

class Dogs extends Animal {
  run() {
    console.log(this.name + "在跑");
  }
  say() {
    console.log("小狗在叫");
  }
}

class Cal extends Animal {
  sex: string
  constructor(name: string, age: number, sex: string) {
    super(name, age)
    this.sex = sex
  }
  say() {
    console.log("小猫在叫");
  }
}

let dog = new Dogs("泰迪", 5)
let cal = new Cal("咪咪", 4, "nan")

console.log(dog);
dog.run()
dog.say()
console.log(cal);
cal.say()

2.3 抽象类 abstract

// abstract
// 在类前面写为抽象类,表示这个抽象类不能被实例
// 在方法前写为抽象方法,他的子类必须要重写这个方法,抽象方法没有方法体(void类型),抽象方法只能在抽象类中
abstract class Animal {
    name: string
    age: number
    constructor(name: string, age: number) {
      this.name = name
      this.age = age
    }
    abstract say(): void
  }

2.4 接口 interface

// 1.接口可以当成类型声明(type)去使用,可以创建多个相同类名的接口,他们的属性和方法会叠加
// 2.接口主要是用来定义一个类的结构,用来定义一个类中应该包涵哪些属性和方法
//   接口中的属性都不能有实际的值,接口只是定义对象的结构
//   接口中所有的方法都是抽象方法
// 抽象类和接口的区别:
// 抽象类是用来继承的,接口是来限制类必须符合自己的标准(属性和方法),可以追加标准
interface myInter {
  name: string
  age: number
}

interface myInter {
  // say(): void
}

let aaa: myInter = {
  name: '小明',
  age: 18
}

class myClass implements myInter {
  name: string
  age: number
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
  say() {

  }
}

2.5 属性的封装

// 在类中定义的属性可以随意被更改会非常不安全,比如说年龄不能为负数
// 可以使用private或者protected把属性变为私有,再用ts中的get、set方法读取(可以给属性添加约束)
class Animal {
  // public 共有属性(默认值),可以在任意位置访问修改
  // private 私有属性,只能在当前类内部进行访问(子类都不行)
  // protected 私有属性,他的子类也可以访问
  private _name: string
  private _age: number
  constructor(_name: string, _age: number) {
    this._name = _name
    this._age = _age
  }
  get age() {
    console.log("获取了数据");
    return this._age
  }
  set age(value) {
    if (value > 0) {
      console.log("修改了数据");
      this._age = value
    }
  }
}
let animal = new Animal("小狗", 3)
animal.age = 1
console.log(animal);
// 属性语法糖写法,下面这两种写法一样
// 1.
class Animal {
  constructor(name: string, age: number) {

  }
}
let animal = new Animal("小狗", 3)

// 2.
class Animal {
  name: string
  age: number
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
}
let animal = new Animal("小狗", 3)

2.6 泛型

// 在定义函数或者类时,如果遇到类型不明确就可以使用泛型(any不安全)
// 可以写多个 
function fn<T>(a: T): T {
  return a
}
let result = fn(10) // 不指定泛型,会自动进行判断
let result2 = fn<string>("hello") // 指定泛型

interface MyInters {
  name: string
  age: number
}
// T extends MyInters 表示泛型T必须实现MyInters类
function fn2<T extends MyInters>(a: T) {
  return a
}
let result3 = fn2({ name: "小明", age: 18 })// 传的值必须要满足接口中的结构

你可能感兴趣的:(TS,typescript,javascript,前端,面向对象编程)