【愚公系列】2021年12月 Typescript-类的使用(封装,继承,多态)

2022-12-01 09:17:45 浏览数 (1)

文章目录

  • 一、TS中类的定义
    • 1. ES5的构造函数
    • 2. ES6的构造函数
    • 2. TS的构造函数,需要添加类型
    • 3. 继承
    • 4. 静态属性
    • 5.修饰属性和方法
    • 6 typescript中的多态
    • 7. typescript中的抽象类
  • 二、命名空间

一、TS中类的定义

1. ES5的构造函数

代码语言:javascript复制
function Cat(name,color) {
    this.name=name;
    this.color=color;
    //this.type='动物';
    //this.eat = function(){
    //    console.log('吃老鼠')
    // }
}
//原型中
Cat.prototype.type='动物';
Cat.prototype.eat = function(){
    console.log('吃老鼠')
};
var c1 = new Cat('小皮','白色');

2. ES6的构造函数

ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。

constructor:类的构造函数,在类被实例化时仅被调用一次,类外部无法使用

代码语言:javascript复制
class Cat {
    constructor(name,color){
        this.name=name;
        this.color=color;
    }
    eat(){
        console.log('吃老鼠')
    }
};
var c2 = new Cat('小皮','白色');

2. TS的构造函数,需要添加类型

我们声明一个 Cat类。这个类有4个成员:一个叫做 name,color的属性,一个构造函数和一个 eat方法。

代码语言:javascript复制
class Cat {
    name:string;
    color:string;
    constructor(name:string,color:string){   //构造函数   实例化类的时候触发的方法
        this.name=name;
        this.color=color;
    }
    eat(){
        console.log('吃老鼠')
    }
};
var c2 = new Cat('大明','白色');

c2.eat();

最后一行,我们使用 new构造了 Cat类的一个实例。 它会调用之前定义的构造函数,创建一个 Cat类型的新对象,并执行构造函数初始化它。

3. 继承

ts中实现继承 extends、 super

在TypeScript里,我们可以使用常用的面向对象模式。 基于类的程序设计中一种最基本的模式是允许使用继承来扩展现有的类。

代码语言:javascript复制
class Animal{ 
    name:string;
    color:string;
    constructor(name:string,color:string){
        this.name = name;
        this.color = color;
    }
    say(){
        console.log('喜欢吃肉');
    }
}

class Dog extends Animal{
    weight:string;
    constructor(name:string,color:string){
        super(name,color);   //关键字   调用父类构造函数和方法   
        this.weight = '456'
    }
}

var dog02 = new Dog('小花','红色');

这个例子展示了最基本的继承:类从基类中继承了属性和方法。 这里, Dog是一个 派生类,它派生自 Animal 基类,通过 extends关键字。 派生类通常被称作 子类,基类通常被称作 超类。

派生类包含了一个构造函数,它 必须调用 super(),即在构造函数里访问 this 的属性之前, 我们一定要调用 super(),它会执行基类的构造函数。

基类是指父类,也被叫做“超类”,派生类则是子类。

4. 静态属性

静态成员,这些属性存在于类本身上面而不是类的实例上 static 不需要实例化处理 可以直接通过类来调用

代码语言:javascript复制
class Animal{
    static uname='动物';
    static eat(){
        console.log('吃老鼠')
    }
    run(){
        console.log('跑');
    }
}

//var a = new Animal()   a.eat()  //error
Animal.eat()

5.修饰属性和方法

ts中三种修饰符 修饰属性和方法 public private protected public 公共的, 在当前类里面、 子类 、类外面都可以访问 protected 保护类型 在当前类里面、子类里面可以访问 ,在类外部没法访问 private 私有的 在当前类里面可以访问,子类、类外部都没法访问 constructor:类的构造函数,在类被实例化时仅被调用一次,类外部无法使用

属性如果不加修饰符 默认就是 公有 (public)

代码语言:javascript复制
class Animal{
    // public username:string;    //公共的  在类里面、 子类  、类外面都可以访问
    // private username:string;    //私有的  在当前类里面可以访问,子类、类外部都没法访问
    protected username:string;   //保护类型 在当前类里面、子类里面可以访问 ,在类外部没法访问

    constructor(username:string){
        this.username = username;
    }
    public eat():string{
        return '吃老鼠';
    }
}

class Dog extends Animal {
    age:string;
    constructor(username:string){
        super(username);
        this.age= '124'
    }
    action():string{
        return this.username;   //调用父类的
    }
}

var d1 = new Dog('abc');

总结: public:类内部,子类和外部都可引用; protected:只能有类的内部和它的子类访问 private:只能类内部访问;

6 typescript中的多态

多态:父类定义一个方法不去实现,让继承它的子类去实现 每一个子类有不同的表现

多态属于继承

代码语言:javascript复制
class Animal {

    name:string;
    constructor(name:string) {
        this.name=name;
    }
    eat(){   //具体吃什么 ,不知道,具体吃什么?继承它的子类去实现 ,每一个子类的表现不一样
        console.log('吃的方法')
    }
}

class Dog extends Animal{
    constructor(name:string){
        super(name)
    }
    eat(){
        return this.name '吃粮食'
    }
}

class Cat extends Animal{
    constructor(name:string){
        super(name)
    }
    eat(){
        return this.name '吃老鼠'
    }
}

7. typescript中的抽象类

它是提供其他类继承的基类,不能直接被实例化。 用abstract关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体实现并且必须在派生类中实现。

abstract抽象方法只能放在抽象类里面 抽象类和抽象方法用来定义标准 。 标准:Animal 这个类要求它的子类必须包含eat方法

代码语言:javascript复制
//标准:

abstract class Animal{
    public name:string;
    constructor(name:string){
        this.name=name;
    }
    abstract eat():any;  //抽象方法不包含具体实现并且必须在派生类中实现。
    run(){
        console.log('其他方法可以不实现')
    }
}
// var a=new Animal('猫类') /*错误的写法*/

class Dog extends Animal{
    //抽象类的子类必须实现抽象类里面的抽象方法
    constructor(name:any){
        super(name)
    }
    eat(){
        console.log(this.name '吃粮食')
    }
}

var d=new Dog('小花花');
d.eat();

二、命名空间

在代码量较大的情况下,为了避免各种变量命名相冲突,可将相似功能的函数、类、接口等放置到命名空间内 同Java的包、.Net的命名空间一样,TypeScript的命名空间可以将代码包裹起来,只对外暴露需要在外部访问的对象。命名空间内的对象通过export关键字对外暴露。

命名空间和模块的区别:

  • 命名空间:内部模块,主要用于组织代码,避免命名冲突。
  • 模 块:ts的外部模块的简称,侧重代码的复用,一个模块里可能会有多个命名空间。
代码语言:javascript复制
namespace A{
    interface Animal {
        name: string;
        eat(): void;
    }
    export class Dog implements Animal {
        name: string;
        constructor(theName: string) {
            this.name = theName;
        }

        eat() {
            console.log(`${this.name} 在吃狗粮。`);
        }
    }

    export class Cat implements Animal {
        name: string;
        constructor(theName: string) {
            this.name = theName;
        }

        eat() {
            console.log(`${this.name} 吃猫粮。`);
        }
    }   

}


namespace B{
    interface Animal {
        name: string;
        eat(): void;
    }
    export class Dog implements Animal {
        name: string;
        constructor(theName: string) {
            this.name = theName;
        }

        eat() {
            console.log(`${this.name} 在吃狗粮。`);
        }
    }

    export class Cat implements Animal {
        name: string;
        constructor(theName: string) {
            this.name = theName;
        }

        eat() {
            console.log(`${this.name} 在吃猫粮。`);
        }
    }   

}


var c=new B.Cat('小花');

c.eat();

0 人点赞