其他分享
首页 > 其他分享> > TypeScript与面向对象

TypeScript与面向对象

作者:互联网

目录

1、引

简而言之就是程序之中所有的操作都需要通过对象来完成。一切操作都要通过对象,也就是所谓的面向对象,在程序中对象被分成了两个部分数据和功能,以人为例,人的姓名、性别、年龄、身高等属于数据,人可以说话、走路、吃饭、睡觉这些都属于人的功能,数据在对象中被称为属性,而功能被称为方法,所以简而言之在程序中一切皆对象

2、类(class)

// 使用class关键字来定义一个类
/*
*   对象中主要包含了两个部分:
*       属性
*       方法
* */
class Person{

    /*
    *   直接定义的属性是实例属性,需要通过对象的实例去访问:
    *       const per = new Person();
    *       per.name
    *
    *   使用static开头的属性是静态属性(类属性),可以直接通过类去访问
    *       Person.age
    *
    *   readonly开头的属性表示一个只读的属性无法修改
    * */

    // 定义实例属性
    // readonly name: string = '孙悟空';
    name = '孙悟空';

    // 在属性前使用static关键字可以定义类属性(静态属性)
    // static readonly age: number = 18;
    age = 18;


    // 定义方法
    /*
    * 如果方法以static开头则方法就是类方法,可以直接通过类去调用
    * */
    sayHello(){
        console.log('Hello 大家好!');
    }

}

const per = new Person();

// console.log(per);
// console.log(per.name, per.age);

// console.log(Person.age);

// console.log(per.name);
// per.name = 'tom';
// console.log(per.name);

// per.sayHello();

// Person.sayHello();
per.sayHello();

readonly 表示一个只读属性,不能修改,是在实例上的

static 表示一个静态属性,通过类的点语法

3、构造函数和this

class Dog{
    name: string;
    age: number;

    // constructor 被称为构造函数
    //  构造函数会在对象创建时调用
    constructor(name: string, age: number) {
        // 在实例方法中,this就表示当前当前的实例
        // 在构造函数中当前对象就是当前新建的那个对象
        // 可以通过this向新建的对象中添加属性
        this.name = name;//第一个name是类的属性,第二个name是传进的参数的类型
        this.age = age;
    }

    bark(){
        // alert('汪汪汪!');
        // 在方法中可以通过this来表示当前调用方法的对象
        console.log(this.name);
    }
}

const dog = new Dog('小黑', 4);
const dog2 = new Dog('小白', 2);

// console.log(dog);
// console.log(dog2);

dog2.bark();

4、继承

(function (){

    // 定义一个Animal类
    class Animal{
        name: string;
        age: number;

        constructor(name: string, age: number) {
            this.name = name;
            this.age = age;
        }

        sayHello(){
            console.log('动物在叫~');
        }
    }

    /*
    * Dog extends Animal
    *   - 此时,Animal被称为父类,Dog被称为子类
    *   - 使用继承后,子类将会拥有父类所有的方法和属性
    *   - 通过继承可以将多个类中共有的代码写在一个父类中,
    *       这样只需要写一次即可让所有的子类都同时拥有父类中的属性和方法
    *       如果希望在子类中添加一些父类中没有的属性或方法直接加就行
    *   - 如果在子类中添加了和父类相同的方法,则子类方法会覆盖掉父类的方法,方法可以重写!!
    *       这种子类覆盖掉父类方法的形式,我们称为方法重写
    *
    * */
    // 定义一个表示狗的类
    // 使Dog类继承Animal类
    class Dog extends Animal{

        run(){
            console.log(`${this.name}在跑~~~`);
        }

        sayHello() {
            console.log('汪汪汪汪!');
        }

    }

    // 定义一个表示猫的类
    // 使Cat类继承Animal类
    class Cat extends Animal{
        sayHello() {
            console.log('喵喵喵喵!');
        }
    }

    const dog = new Dog('旺财', 5);
    const cat = new Cat('咪咪', 3);
    console.log(dog);
    dog.sayHello();
    dog.run();
    console.log(cat);
    cat.sayHello();


})();

5、super

子类写了constructor构造函数必须使用super继承父类constructor构造函数的属性

(function () {
    class Animal {
        name: string;
        constructor(name: string) {
            this.name = name;
        }

        sayHello() {
            console.log('动物在叫~');
        }
    }

    class Dog extends Animal{
        age: number;
        constructor(name: string, age: number) {
            // 如果在子类中写了构造函数,在子类构造函数中必须对父类的构造函数进行调用
            //super(name) === this.name = name,伪代码
            super(name); // 调用父类的构造函数
            //如果在子类的构造函数直接super父类构造函数
            this.age = age;
        }
        // 重写父类方法
        sayHello() {
            // 在类的方法中 super就表示当前类的父类
            // super.sayHello();
            console.log('汪汪汪汪!');
        }
    }

    const dog = new Dog('旺财', 3);
    dog.sayHello()
})();


6、抽象类

(function () {

    /*
    *   以abstract开头的类是抽象类,
    *       抽象类和其他类区别不大,只是不能用来创建对象
    *       抽象类就是专门用来被继承的类
    *
    *       抽象类中可以添加抽象方法
    * */
    abstract class Animal {
        name: string;

        constructor(name: string) {
            this.name = name;
        }

        // 定义一个抽象方法
        // 抽象方法使用 abstract开头,没有方法体
        // 抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写
        abstract sayHello():void;
    }

    class Dog extends Animal{
        sayHello() {
            console.log('汪汪汪汪!');
        }

    }

    class Cat extends Animal{
        sayHello() {
            console.log('喵喵喵喵!');
        }

    }

    const dog = new Dog('旺财');
    dog.sayHello();

})();

抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写

7、接口

接口的作用类似于抽象类,不同点在于接口中的所有方法和属性都是没有实值的,换句话说接口中的所有方法都是抽象方法。接口主要负责定义一个类的结构,接口可以去限制一个对象的接口,对象只有包含接口中定义的所有属性和方法时才能匹配接口。同时,可以让一个类去实现接口,实现接口时类中要保护接口中的所有属性。

8、属性的封装

(function (){
    // 定义一个表示人的类
    class Person{
        // TS可以在属性前添加属性的修饰符
        /*
        *   public 修饰的属性可以在任意位置访问(修改) 默认值
        *   private 私有属性,私有属性只能在类内部进行访问(修改)
        *       - 通过在类中添加方法使得私有属性可以被外部访问
        *   protected 受包含的属性,只能在当前类和当前类的子类中访问(修改)
        *
        * */
        private _name: string;
        private _age: number;

        constructor(name: string, age: number) {
            this._name = name;
            this._age = age;
        }

        /*
        *   getter方法用来读取属性
        *   setter方法用来设置属性
        *       - 它们被称为属性的存取器
        * */
        // TS中设置getter方法的方式
        get name(){
            // console.log('get name()执行了!!');
            return this._name;
        }
        set name(value){
            this._name = value;
        }
        get age(){
            return this._age;
        }
        set age(value){
            if(value >= 0){
                this._age = value
            }
        }
    }

    const per = new Person('孙悟空', 18);

    /*
    * 现在属性是在对象中设置的,属性可以任意的被修改,
    *   属性可以任意被修改将会导致对象中的数据变得非常不安全
    * */
    // per.setName('猪八戒');
    // per.setAge(-33);
    per.name = '猪八戒';
    per.age = -33;
    // console.log(per);
    class A{
        //protected是保护的属性,只能在当前类和子类中设置
        //protected只能在当前类和当前类的子类中设置
        protected num: number;
        constructor(num: number) {
            this.num = num;
        }
    }
    class B extends A{
        test(){
            console.log(this.num);
        }
    }
    const b = new B(123);
    // b.num = 33;
   /* class C{

        name: string;
        age: number

        // 可以直接将属性定义在构造函数中
        constructor(name: string, age: number) {
            this.name = name;
             this.age = age;
        }
    }*/
    class C{
        // 直接将属性定义在构造函数中
        constructor(public name: string, public age: number) {
        }
    }
    const c = new C('xxx', 111);
    console.log(c);
})();

9、泛型

定义一个函数或类时,有些情况下无法确定其中要使用的具体类型(返回值、属性、参数的类型不能确定),此时泛型便能通够发挥作用

标签:TypeScript,console,name,age,面向对象,sayHello,log,属性
来源: https://www.cnblogs.com/Code-Is-Fun/p/15319060.html