• ts-面向对象


    什么是面向对象?

    面向对象: Oriented(基于)Object(事物), 简称OO。

    是一种编程思想, 他提出一切以类为切入点思考问题。
    其他编程思想: 面向过程、函数式编程。

    学开发最难的是什么? 思维

    面向过程: 以功能流程为思考切入点,不太适合大型应用。

    函数式编程: 以数学运算为思考切入点。

    面向对象: 以划分类为思考切入点

    类:可以产生对象的模版。类是最小的功能单元

    人(类): 特征: 鼻子、眼睛、四肢、性别, 动作: 说话、运动、制造工具

    new 人()

    如何学习

    1. TS中的OOP(面向对象编程,Oriented Object Programing)

    成员的重写

    重写(override):子类中覆盖父类的成员

    类成员不能改变父类成员的类型

    无论是属性还是方法,子类都可以对父类的相应成员进行重写,但是重写时, 需要保证类型的匹配

    注意this关键字: 在继承关系中,this的指向是动态调用方法时,根据具体的调用者确定this指向

    super关键字: 在子类的方法中,可以使用super关键字读取父类成员

    类型匹配

    鸭子辨型法

    子类的对象,始终可以赋值给父类

    面向对象中,这种现象,叫做里氏替换原则

    如果需要判断一个数据的具体子类类型, 可以使用instanceof

    protetcted 修饰符

    readonly:只读修饰符

    访问权限修饰符: private public protected

    protected: 受保护的成员,只能在自身和子类中访问

    ts的编译结果里没有访问修饰符

    export class Tank {
        name: string = "坦克"
        
        sayHello() {
            console.log(`我是一个${this.name}`)
        }
    }
    
    
    export class PlayerTank extends Tank{
        name:string = "玩家坦克"
        sayHello() {
            console.log('lalala')
        }
        test() {
            super.sayHello();
            this.sayHello();
        }
    }
    
    
    export class EnemyTank extends Tank {
        name:string = "敌方坦克"
    }
    
    const p: Tank = new PlayerTank();
    
    p.sayHello();
    
    <!我是一个玩家坦克 ---->
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    单根性和传递性

    单根性: 每个类最多只能拥有一个父类

    传递性: 如果A是B的父类,并且B是C的父类,则可以认为A也是C的父类

    抽象类

    有时,某个类只表示一个抽象概念, 主要用于提取子类共有的成员,而不能直接创建它的对象,该类可以作为抽象类。

    给类前面加上abstract, 表示该类是一个抽象类,不可以创建一个抽象类

    抽象成员

    父类中,可能知道有哪些成员是必须存在的,但是不知道该成员的值或实现是设么,因此,需要有一种强约束,让继承该类的子类,必须要实现该成员

    抽象类中, 可以有抽象成员, 这些抽象成员必须在子类中实现。

    abstract class Chess{
        x: number
        y: number
        
        abstract readonly name: string;
    }
    
    class Horse extends Chess{
        readonly name: string = "马";
    }
    
    class Pao extends Chess{
        readonly name: string;
        
        constructor() {
            super();
            this.name = "炮"
        }
    }
    
    class Solider extends Chess{
        get name() {
            return "兵"
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    abstract class Chess{
        x: number
        y: number
        
        abstract readonly name: string;
        
        abstract move(targetX:number, targetY:number): boolean;
    }
    
    class Horse extends Chess{
        readonly name: string = "马";
        
        move(targetX: number, targetY:number): boolean{
            this.x = targetX;
            this.y = targetY;
            console.log("马移动成功")
            return true;
        }
    }
    
    class Pao extends Chess{
    
    move(targetX: number, targetY:number): boolean{
            this.x = targetX;
            this.y = targetY;
            console.log("炮移动成功")
            return true;
        }
        readonly name: string;
        
        constructor() {
            super();
            this.name = "炮"
        }
    }
    
    class Solider extends Chess{
        get name() {
            return "兵"
        }
        
        move(targetX: number, targetY:number): boolean{
            this.x = targetX;
            this.y = targetY;
            console.log("兵移动成功")
            return true;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    设计模式 - 模版模式

    设计模式: 面对一些常见的功能场景,有一些固定的、经过多年实践的成熟方法,这些方法称之为设计模式。

    模版模式: 有些方法,所有的子类实现的流程完全一致。只是流程中的某个步骤的具体实现不一致,可以将该方法提取到父类,在父类中完成整个流程的实现, 遇到实现不一致的方法时,将该方法做成抽象方法。

    abstract class Chess{
        x: number
        y: number
        
        abstract readonly name: string;
        
         move(targetX:number, targetY:number): boolean {
             console.log("1. 边界判断");
             console.log("2. 目标位置是否有棋子")
             <!3. 规则判断---->
             this.rule(targetX, targetY);
         };
         
        protected abstract rule(targetX:number, targetY: number): boolean
    }
    
    class Horse extends Chess{
        readonly name: string = "马";
        
        move(targetX: number, targetY:number): boolean{
            this.x = targetX;
            this.y = targetY;
            console.log("马移动成功")
            return true;
        }
    }
    
    class Pao extends Chess{
    
    move(targetX: number, targetY:number): boolean{
            this.x = targetX;
            this.y = targetY;
            console.log("炮移动成功")
            return true;
        }
        readonly name: string;
        
        constructor() {
            super();
            this.name = "炮"
        }
    }
    
    class Solider extends Chess{
        get name() {
            return "兵"
        }
        
        move(targetX: number, targetY:number): boolean{
            this.x = targetX;
            this.y = targetY;
            console.log("兵移动成功")
            return true;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    ## 什么是静态成员

    静态成员是指,附着在类上的成员(属于某个构造函数的成员)

    使用static修饰的成员,是静态成员。

    实例成员:对象成员,属于某个类的对象。

    静态成员: 非实例成员,属于某个类

    静态方法中的this

    实例方法中的this指向的是当前对象

    而静态方法中的this指向的是当前类

    class User {
        static users: User[] = [];
        
        constructor(public loginId: string, public loginPwd: string, public name: string, public age: number) {
            this.loginId = loginId;
            this.loginPwd = loginPwd;
            this.name = name;
            this.age = age;
        }
        
        sayHello() {
            console.log(`大家好,我叫${this.name}, 今年${this.age}岁了, 我的账号是${this.loginId}`)
        }
        
        static login(loginId: string, loginPwd: string) {
            return this.users.find(e => e.loginId === loginId && e.loginPwd === loginPwd);
        }
    }
    
    new User('u1', '123', '李', age: 23)
    
    const result = User.login('u1', '123');
    if(result) {
        result.sayHello();
    }
    else {
    console.log('登录失败,账号或密码不正确')
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    设计模式 -单例模式

    单例模式: 某些类的对象,在系统中最多只能有一个,为了避免开发者造成随意创建多个类对象的错误,可以使用单例模式进行强约束。

    class Board {
        width: number = 500;
        height: number = 300;
        init() {
            console.log('初始化棋盘')
        }
        
        private constructor() {}
        
        private static _board?: Board;
        
        static createBoard(): Board{
            if(this._board) {
                return this._board;
            }else {
                this._board = new Board();
                return this._board;
            }
        }
    }
    
    const b = new Board();
    
    const b1 = Board.createBoard();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    接口

    接口用于约束类、对象、函数, 是一个类型契约。

    有一个马戏团,马戏团中有很多动物, 包括:狮子、老虎、猴子、狗,这些动物都具有共同的特征: 名字、年龄、种类名称,还包含一个共同的方法: 打招呼,它们各自有各自的技能, 技能是可以通过训练改变的。狮子和老虎能进行
    火圈表演,猴子能进行平衡表演,狗能进行智慧表演。

    class Animal {
    abstract type: string
        consuctor(name: string, age: number) {
            this.name = name
            this.age = age
        }
        
        sayHello() {
            console.log(`大家好,我是${this.type},我的名字是${this.name}`)
        }
    }
    
    
    class Lion extends Animal{
    type: string = '狮子';
        oneFire() {
            
        }
        doubleFire() {}
    }
    
    class Tiger extends Animal {
    type: string = '老虎';
        oneFire() {
            
        }
        doubleFire() {
            
        }
    }
    
    class Monkey extends Animal{
    type: string = '猴子';
        banlance() {
            
        }
    }
    
    class Dog extends Animal{
    type: string = '狗';
        wisdom() {
            
        }
    }
    
    
    var animals: Animal[] = [
        new Lion('李四', 12),
        new Tiger('李敌', 4),
        new Monkey('李空', 5),
        new Dog('李昂', 18)
    ];
    
    animals.forEach(e => e.sayHello());
    
    animals.forEach(e => {
        if(e instanceof Lion) {
            e.oneFire();
            e.doubleFire();
        }
    })
    
    interface IShowFire {
        oneFire:() => void,
        doubleFire: () => void
    }
    
    class Lion extends Animal implements IShowFiere{
        type: string = '狮子';
        oneFire() {
            
        }
        
        doubleFire() {
            
        }
    }
    function hasShowFire(ani:object) : ani is IShowFire{
        if((ani as IShowFire).oneFire && (ani as IShowFire).doubleFire)) {
            return true;
        }
        return false;
    }
    animals.forEach(e => {
        if(hasShowFire(e)) {
            e.oneFire();
            e.doubleFire();
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89

    不使用接口实现时:

    • 对能力(成员函数)没有强约束力
    • 容易将类型和能力耦合在一起

    系统中缺少对能力的接口 ———— 接口

    面向对象领域中的语义: 表达了某个类是否拥有某种能力

    某个类具有某种能力,其实,就是实现了某种接口

    类型保护函数: 通过调用该函数,会触发Ts的类型保护,该函数必须返回boolean

    接口和类型别名的最大区别: 接口可以被类实现,而类型别名不可以

    接口可以继承类,表示该类的所有成员都在接口中。

    索引器

    对象[值], 使用成员表达式
    在TS中,默认情况下,不对索引(成员表达式)做严格的类型检查

    使用配置noImplicitAny开启对隐式any的检查

    隐式any:TS根据实际情况推导出的any类型

    在索引器中,键的类型可以是字符串,也可以是数字

    在类中,索引器书写的位置应该是所有成员之前

    TS中索引器的作用

    • 在严格的检查下,可以实现为类动态增加成员
    • 可以实现动态的操作类成员

    在JS中,所有的成员名本质上,都是字符串,如果使用数字作为成员名,会自动转化为字符串。

    在TS中,如果某个类中使用了两种类型的索引器, 要求两种所引起的值类型必须匹配(相同)。

  • 相关阅读:
    [附源码]计算机毕业设计基于web的羽毛球管理系统
    Pandas ExcelWrite()读写Excel
    《进阶篇第9章》学习vuex知识点后练习:求和案例_纯vue版代码
    按位异或的应用
    给女朋友开发个小程序低价点外卖吃还能赚钱
    java ssm教师工作量统计系统
    iOS——类与对象底层探索
    C语言系统化精讲(一):编程基础
    109.(leaflet篇)leaflet实现沿轨迹线播放
    前端的多种克隆方式和注意事项
  • 原文地址:https://blog.csdn.net/qq_43554231/article/details/127553542