TypeScript 的面向对象 + 类

// 面向对象

什么是对象: 就是针对于某个特定的事物,所存在的属性和功能,

面向对象编程: 就是针对于这个事物进行描述的 属性功能 (即:属性 和方法)

// 类

类: 类就是对象的实例化

  • Js中的类是用构造函数的形式来创建

    //用空函数创建一个类
    function Obj(){
    }
    //在类的原型链上添加属性和方法
    Obj.prototype.name="xxx";
    Obj.prototype.say=function(){
        alert("我是xxx");
    }
    //生成对象
    var obj1=new Obj();
    //通过工厂方式创建对象,先定义一个工厂方法
    function createObj(){
        var obj  =  new Object();
        obj.name="xxx";
        obj.say=function(){
            alert("我是xxx");
        }
        return obj;
    }
    //调用工厂方法创建对象:
    var obj1  =  createObj();
    
  • ts的类是使用class

class Person {
    // 定义属性
    // 只读属性 readonly; (仅支持读取,不支持修改)
    name: string = "孙荪",
    // 在属性前使用static关键字,可以定义 类属性 (静态属性)    
    static age: number = '18',
    // 定义方法
    sayHello () {
        console.log('我是类的方法')
    }    
}
// 类的实例化
const  per = new Person()
console.log(per.age) // per.age即 为实例属性
console.log(Person.age)  //   在属性前使用static关键字,可以定义类属性(静态属性
// 声明类的语法糖
  /*
   *
   *  声明类的语法糖
   *
   */
  class C {
    constructor(public name: string, public age: number) {
    }
  }
}) ()
  • 类中的 属性方法 在加入关键字static以后都是可以直接通过类的形式调 如:Person.age Person.sayHello()
    static readonly consloe.log(Person.name): 同时使用时 static 放在前面
    • 实例的属性和方法需要先创建一个实例 再用实例调用属性或方法 ; 类(静态)属性|方法 可以直接通过类调用

类中的 constructor() 是类中的构造函数,构造函数会在 对象创建时调用

class person {
    name: string,
    age: number,
    // constructor 是构造函数,会在对象创建时调用
    constructor(name: string, age: number) {
      // 在实例中, this 指当前的实例 
      // 在构造函数中当前对象是当前调用的对象
      // 可以通过this向新建的对象添加属性的值
      this.name = name
      this.gae = age 
    },
    say () {
      console.log('are you ok ?' + this.name)
    }
}

const per1 = new person(name: '小明', age: 20)
const per2 = new person(name: '小月', age: 18)
console.log(per1, per2)

// 继承

特点: 可以在不修改父类的同时 ,继承了父类的所以属性和方法,并且可以重新添加或修改属相和方法,如果有属性和方法跟父类相同,仅仅是在当前子类中重写该属性和方法 而不会影响到父类

(function () {
  // 构造一个类
  class Animal {
    name: string;
    age: number;
    constructor(name: string, age: number) {
      this.name = name
      this.age = age
    };
    sayFn() {
      console.log('动物在叫')
    }
  }
  // 继承 子类(Dog)继承父类(Animal)的所有属性和方法
  class Dog extends Animal{
    sayFn() {
      console.log('动物在叫:dog')
    }
  }
  class Cat extends Animal {
    // 在子类中添加属性和方法 直接添加
  }
}) ()

// super

  • super: 即是指父类

    /在类的方法中super 就表示当前类的父类

    (function () {
      // 父类
      class Animal {
        name: string;
        constructor(name: string) {
          this.name = name
        }
        sayFn() {
          console.log('a  animal')
        }
      }
      // 子类
      class Dog extends Animal {
        constructor(name: string, age: number) {
          // 在子类中写了构造函数,就相当于把 父类中的构造函数重写了,
          // 因此需要调用父类的来获取属性和方法
          super(name) // 调用父类的构造函数
          this.age = age
        }
        sayFn() {
          // 再类的方法中super 就表示当前类的父类
          // super.sayFn() // 调用之前的父类
          console.log('I am a big dog')
        }
      }
      const dog = new Dog(name: '二狗子', age: 18)
      dog.sayFn()
    })()
    

// 抽象类

抽象类:是由关键字 abstract 声明的特殊类,是不能被创建对象(实例化)的类,故而专门用作于父类

  • 抽象类可以添加抽象方法;=>

    • 抽象方法是使用 abstract 开头,并没有方法体
    • 抽象方法只能定义到抽象类中, 子类必须对抽象方法进项重写才能使用
    (function () {
      // 父类
      abstract class Animal {
        name: string;
        constructor(name: string) {
          this.name = name
        }
        // 定义抽象方法
        // 必须使用 abstract 开头, 且没有实体
        // 抽象方法只能在抽象类中创建,子类必须重写
        abstract sayFn(): void
      }
      // 子类
      class Dog extends Animal {
        sayFn() {
          // 再类的方法中super 就表示当前类的父类
          // super.sayFn() // 调用之前的父类
          console.log('I am a big dog')
        }
      }
      const dog = new Dog(name: '二狗子')
      dog.sayFn()
    })()
    

// 接口

​ 接口的声明 要用关键字 interface

  • 接口跟声明基本类似,但是接口会在定义类的时候限制类的结构
  • 类型不可以重复声明, 接口可以重复声明
  • 接口的重复声明是多个属性的添加
  • 接口的所有属性和方法 都没有一个实际的值即:只定义结构,不定义方法
  • 接口的所有方法都是抽象方法
(function () {
  // 描述一个对象的类型
  type myType = {
    name: string,
    age: number
  };
  /*
   *
   *  接口用来定义一个类结构, 也可以定义一个类中所包含的属性和方法
   *  接口也可以当做了类型的声明去使用
   */
  //  类型不可以重复声明, 接口可以重复声明
  interface myInterface {
    name: string;
    age: number;
  }
  // 声明多个接口时, 就是在原本的基础上,有重复的属性就重写,没有就新增
  interface myInterface {
    gender: 'man'
  }
  // 接口的实例
  // const obj: myInterface = {
  //   name: 'Jack',
  //   age: 18,
  //   gender: 'Girl'
  // }


  // 接口可以在定义类的时候去限制类的结构
  // 接口所有的属性和方法 都不能有实际的值
  // 接口中所有的方法都是抽象方法
  interface myInter {
    name: string;
    sayFn(): void;
  }
  /*
   *
   *  定义类时,可以用类去实现一个接口的实例
   *  类在实现接口的时候,必须继承所有的接口 属性 和 方法 
   */ 
  class myClass implements myInter {
    name: string;
    constructor (name: string) {
      this.name = name;
    }
    sayFn() {
      console.log('Hi~')
    }
  }
}) ()

// 属性封装

// Ts属性修饰符:

  • public: 表任意位置都可访问;默认值
  • protected: 表示保护属性,只能在父类跟其子类才能访问
  • private: 表示私有属性,仅在所在类的内部进行访问 => 可以在类中添加方法使得私有属性 可以被外部访问
(function () {
  /*
   *  public: 表任意位置都可访问;默认值
   *  private: 表示私有属性,仅在所在类的内部进行访问
   *  protected: 表示保护属性,只能在父类跟其子类才能访问
   *
   */ 
  // 可以利用 `private` 的私有性对属性进行操作,从而达到对属性值的控制 
  class Person {
    private _name: string;
    private _age: number
    constructor(name: string, age: number) {
      this._name = name;
      this._age = age;      
    }
    //ts自带 获取
    get name() {
      return this._name;
    }
    set name(val: string) {
       this._name = val;
    }
    //ts自带 设置
    set age(val: number) {
      if (val > 0) {
        this._age = val;
      } else {
        console.log('是负的');
      }
    }
  }

  const per = new Person(name: '小明', age: 15)
  // 目前可修改(使用私有修饰符对属性进行封装后的引用跟修改与之前一致)
  per._name = '老王';
  per._age = 51; 
  console.log(per);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容