从零开始学习typescript系列8: typescript面向对象编程之类和对象以及继承相关使用详解含demo

demo:ts:class基本使用和本质

class Greeter {    
    // 1. 基本使用:成员变量/构造函数/成员函数(原型方法)
    greeting: string;  
    constructor(message: string){ this.greeting = message; };
    sayHi() { console.log(this.greeting); }
}
let myGreeter1 = new Greeter('你好');
myGreeter1.sayHi(); // hi, nice to meet you!
// 2. class本质是function
console.log(`type of Greeter: `, typeof Greeter) // type of Greeter:  function
console.log(`type of myGreeter1: `, typeof myGreeter1) // type of myGreeter1:  object

demo:ts:public protected private

修饰器+属性或方法,可以限制访问

  • public,TypeScript里,成员(包括属性和方法)都默认为 public
  • private,只能当前类内部访问, 子类和实例不能访问
  • protected,可在当前类和子类内部访问, 实例不能直接访问

修饰+构造函数

  • private ,该类不允许被继承或者实例化
  • protected,该类运行被继承,不允许实例化
class Plant {    
    public name:string;         // public 子类和实例都可访问
    protected age: number;     // protected 子类可访问,实例不可访问
    private region: string;     // private:子类和实例都不可访问
  	// protected修饰构造函数,意味着Plant不能被实例化
    protected constructor(name:string, age: number, region:string){
        this.name = name;
        this.age = age;
        this.region = region;
    }
};
class Bamboo extends Plant {
    public color: string;
    // public修饰构造函数,意味着Bamboo可以被实例化
    public constructor(name: string, age:number, region:string, color: string){
        super(name, age, region);
        this.color = color;
    }
    // 1. 继承的属性访问限制
    public getInfo(){
        console.log(`my name is ${this.name}`); // public 子类可访问
        console.log(`my age is ${this.age}`); // protected 子类可访问
        console.log(`my region is ${this.region}`); // compile error! private  子类不可访问
    }
};
// 2. 实例化的构造函数访问限制
let plant1 = new Plant('tree', 2, 'south'); // compile error! Plant不可实例化
let bamboo1 = new Bamboo('boom1', 1, 'north','lightGreen'); // Bamboo可实例化

// 3. 实例对象的属性访问限制
// 不可以访问bamboo1.age和bamboo1.region
console.log(`bamboo1.name=${bamboo1.name}, bamboo1.color=${bamboo1.color}`);  // OK 

demo:ts:readonly

readonly

  • 修饰成员属性
  • 声明时和构造时,可写
  • 实例化对象时,不可泄
class Octopus {
    // readonly变量声明时初始化可写
    public readonly enviroment: string; // 只读
    public readonly legs: number = 8;  // 只读
    public name: string;
    // readonly变量构造函数时初始化可写
    public constructor(enviroment: string, name: string, legs: number) {
        this.enviroment = enviroment;
        this.legs = legs;
        this.name = name;
    }
}
// 运行
let oct1 = new Octopus('海洋', '1号章鱼', 9);
oct1.name = '1号巨型章鱼' // ✅
oct1.enviroment = '深海' // ts编译❌ Cannot assign to 'enviroment' because it is a read-only property.
oct1.legs = 10 // ts编译❌ Cannot assign to 'legs' because it is a read-only property.ts(2540)

demo:ts:构造函数

// 1. 构造函数普通方式
class OriginalAnimal{
    private name:string;
    public constructor(name: string){
        this.name = name;
    }
    getInfo(){console.log(`OriginalAnimal: name=${this.name}`);}
}
let myOrigin1 = new OriginalAnimal('kawa1');
myOrigin1.getInfo(); // OriginalAnimal: name=kawa   

// 2. 构造函数语法糖模式
class OriginalAnimal{
    // 修饰词默认是public,ts中此构造函数和上面的OriginalAnimal构造函数是等价的
    // 一条语句完成: 成员属性定义和构造函数定义
    constructor(private name:string){}; 
    getInfo(){console.log(`OriginalAnimal: name=${this.name}`);}
}
let myOrigin1 = new OriginalAnimal('kawa2');
myOrigin1.getInfo();  // OriginalAnimal: name=kawa2

demo:ts:静态属性

静态属性

  • static关键字声明
  • 属于类,不属于实例
  • 可以通过类名.静态属性来访问
class Movie{
    public static goal:string = '科幻'; // 静态属性
    public constructor(public name:string) { };
    public getInfo(){console.log(`name=${this.name} goal=${Movie.goal}`);}
};
// 运行
let myMovie = new Movie('黑客帝国');
// 类内部访问静态属性 ✅
myMovie.getInfo();  // name=黑客帝国 goal=科幻
// 类外部访问静态属性 ✅
console.log(Movie.goal);  // 科幻

demo:ts:私有属性语法糖

class Person {
    // 公有属性 name  私有属性: age/weight
    name; #age; #weight;
    constructor(name: string, age: number, weight: string) {
        this.name = name;
        this.#age = age;
        this.#weight = weight;
    }
    intro() {
        console.log('age=', this.#age)
        console.log('weight=', this.#weight)
    }
}
// 运行: 
// 1. 配置选项("target": "ES2015") 
// 2. 运行命令(tsc --build tsconfig.json  && node script.js)
let p = new Person('小丽', 18, '45kg')
// 公有属性可以直接访问
console.log('name=', p.name) // name=小丽
// 私有属性可以通过方法访问 
p.intro() // age= 18 weight= 45kg
// 私有属性不可以直接访问,编译报错
// error: Property '#age' is not accessible outside class 'Person' because it has a private identifier.
// console.log('age=', p.#age)
// console.log('weight=', p.#weight)   

demo:class原型链

class Cpoint {
    constructor(x,y){
        console.log('@Cpoint 构造函数...',x,y);
        this.x = x;
        this.y = y;
    }
}
let p1 = new Cpoint(1,2); // test
console.log(Cpoint.prototype.__proto__ === Object.prototype); // true

// 不带继承的原型链关系
// - 原型链关系 可以把Point看成是function
// 父类
class Point {
    constructor(x,y){
        this.x = x;
        this.y = y;
    }
}
// 子类
class Cpoint extends Point{
    constructor(x,y,color){          
        super(x,y);
        this.color = color;
    }
}    
let cp1 = new Cpoint(100,50,'red');
console.log("cp1: ", cp1); // cp1 {x:100,y:50,color:'red'}
console.log('原型链:', cp1.__proto__ === Cpoint.prototype); // true
console.log('原型链:', Cpoint.prototype.__proto__ === Point.prototype); // true
console.log('原型链:', Point.prototype.__proto__ === Object.prototype); // true

// 有继承的原型链关系
// - 可以把CPoint和Point看成是function
// - 两个class的关系可以看成是es5中类似寄生组合关系

总结

class本质

  • 本质: 依然是function,class语法让对象原型更清晰、更面向对象编程
  • 作用: 代码复用,比如继承,实例化

构造方法

  • 作用: 初始化实例,构造方法可被子类继承
  • 父类 constructor() { return this }
  • 子类 constructor(...args) { super(...args);}

原型方法

  • class内部成员方法
  • 相当于es5语法中prototype方法
  • 原型方法是所有实例对象所共享和继承的,public修饰词

静态方法

  • static关键字 + class内方法
  • 静态方法属于类,可被class名调用,无法访问实例的this(undefined)
  • 静态方法可与原型方法重名
  • 父类的静态方法,可以被子类继承

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-22 22:04:04       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-22 22:04:04       106 阅读
  3. 在Django里面运行非项目文件

    2024-03-22 22:04:04       87 阅读
  4. Python语言-面向对象

    2024-03-22 22:04:04       96 阅读

热门阅读

  1. 数据科学详解与人工智能关系

    2024-03-22 22:04:04       44 阅读
  2. 前端逻辑错误或UI崩溃解决问题

    2024-03-22 22:04:04       38 阅读
  3. SQL Server创建存储过程

    2024-03-22 22:04:04       45 阅读
  4. 力扣-283. 移动零

    2024-03-22 22:04:04       47 阅读
  5. 基于STM32的寻迹小车设计详细论文

    2024-03-22 22:04:04       34 阅读
  6. Thingworx高可用集群部署(七)-Zookeeper集群部署

    2024-03-22 22:04:04       42 阅读
  7. Redis切换数据库的详细介绍

    2024-03-22 22:04:04       45 阅读
  8. 洛克王国卡小游戏2

    2024-03-22 22:04:04       39 阅读
  9. Yarn 管理的前端项目转换为使用 npm

    2024-03-22 22:04:04       41 阅读
  10. Redis 产生阻塞的原因,如何找到阻塞的原因

    2024-03-22 22:04:04       39 阅读
  11. 快速排序--C语言

    2024-03-22 22:04:04       44 阅读
  12. 【大数据技术】Hive基本原理以及使用教程

    2024-03-22 22:04:04       44 阅读
  13. docker 修改默认存储位置

    2024-03-22 22:04:04       38 阅读
  14. CSS color-mix() 函数

    2024-03-22 22:04:04       44 阅读
  15. less与sass哪个更好用

    2024-03-22 22:04:04       47 阅读