| 设计模式 | - 面向对象

88 阅读2分钟

面向对象

面向对象的理解,以类和对象作为组织代码的基本单位,并实现封装、抽象、继承、多态四个特性

抽象(Abstraction)

  • 抽象主要是隐藏方法的实现,让调用者只关心有哪些功能而不是关心功能的实现
  • 抽象可以提高代码的可扩展性和维护性,修改实现不需要改变定义,可以减少代码的改动范围
interface IStorage {
    save(key: any, value: any): void;
    read(key: any): void;
}
class LocalStorage implements IStorage {
    save(key: any, value: any) {
        localStorage.setItem(key, value);
    }
    read(key: any) {
        return localStorage.getItem(key);
    }
}
class User {
    constructor(public name: string, public storage: IStorage) {

    }
    save() {
        this.storage.save('userInfo', JSON.stringify(this));
    }
    read() {
        return this.storage.read('userInfo');
    }
}
let user = new User('张三', new LocalStorage());
user.save();
user.read();

继承 (Extends)

过度使用继承或者说继承层次过深会导致代码可读性、可维护性变差 子类和父类高度耦合,修改父类的代码,会直接影响到子类

  • 继承主要的要处是实现代码复用
  • 继承可以把父类和子类的公共方法抽离出来,提高复用,减少冗余
export { };
class Animal {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    eat() {
        console.log(`${this.name} eat`)
    }
}
let animal = new Animal('动物');
animal.eat();

class Dog extends Animal {
    age: number;
    constructor(name: string, age: number) {
        super(name);
        this.age = age;
    }
    speak() {
        console.log(`${this.name} is barking!`);
    }
}
let dog = new Dog('🐶', 5);
dog.eat();
dog.speak();

封装

  • 把数据封装起来,使用 getter setter方法去获取或者修改。

  • 减少耦合,不该外部访问的不要让外部访问

  • 利于数据的接口权限管理

  • 仅暴露有限的必要接口,提高类的易用性

  • 实现

    • public:公有修饰符,可以在类内或者类外使用public修饰的属性或者行为,默认修饰符
    • protected:受保护的修饰符,可以本类和子类中使用protected修饰的属性和行为
    • private : 私有修饰符,只可以在类内使用private修饰的属性和行为
class Animal {
    public name: string;
    protected age: number;
    private weight: number;
    constructor(name: string, age: number, weight: number) {
        this.name = name;
        this.age = age;
        this.weight = weight;
    }
}
class Person extends Animal {
    private money: number;
    constructor(name: string, age: number, weight: number, money: number) {
        super(name, age, weight);
        this.money = money;
    }
    getName() {
        console.log(this.name);
    }
    getAge() {
        console.log(this.age);
    }
    getWeight() {
        console.log(this.weight);
    }
    getMoney() {
        console.log(this.money);
    }
}
let p = new Person('zfpx', 9, 100, 100);
console.log(p.name);
console.log(p.age);
console.log(p.weight);

多态

  • 保持子类的开放性和灵活性,可以重写父类中的方法, 继而实现面向接口编程
class Animal {
    public name: string;
    protected age: number;
    private weight: number;
    constructor(name: string, age: number, weight: number) {
        this.name = name;
        this.age = age;
        this.weight = weight;
    }
    speak() {
        throw new Error('此方法必须由子类实现!');
    }
}
class Person extends Animal {
    private money: number;
    constructor(name: string, age: number, weight: number, money: number) {
        super(name, age, weight);
        this.money = money;
    }
    getName() {
        console.log(this.name);
    }
    getAge() {
        console.log(this.age);
    }
    getMoney() {
        console.log(this.money);
    }
    speak() {
        console.log('你好!');
    }

}
class Dog extends Animal {
    constructor(name: string, age: number, weight: number) {
        super(name, age, weight);
    }
    speak() {
        console.log('汪汪汪!');
    }
}
let p = new Person('zfpx', 10, 10, 10);
p.speak();
let d = new Dog('zfpx', 10, 10);
d.speak();