Skip to content

面向对象

面向对象(Object-Oriented)是一种程序设计的范式,它以对象为基本单位,通过封装、继承和多态等机制来组织和管理代码。核心思想是将现实世界中的事物抽象成对象,对象之间通过消息传递进行交互。每个对象都有自己的状态(数据)和行为(方法),对象之间可以通过方法调用来进行信息交换。这种方式使得程序的设计更加模块化和可维护,能够更好地应对复杂性。

JS-OOP 是将相同的事物抽象成, 每个事物都是类的实例化后的对象,通过封装继承多态等机制来组织和管理代码,提高软件的重用性、灵活性和扩展性等目的。

js
/**
 * 标准的 OOP 需要具备封装、继承、多态能力
 * 封装:JS 可以通过 "function 函数作用域" 实现
 * 继承:JS 可以通过 "this 作用域链" 、 "prototype 原型链" 实现
 * 多态:JS 可以通过 "属性重写/属性拓展"、"方法重写/方法拓展" 实现
 * ====
 * 私有成员:只能在类内部访问
 * 公有成员:类可以访问,实例对象通过继承可以访问,内部外部不受限制
 * 静态成员:只有类可以访问,内部外部不受限制
 */

// ===== "仿 Class" 模式 =====
function AnimalClass(username, language) {
    // 函数作用域封装属性
    let username = "私有名字"; // 私有属性
    let language = "私有语言"; // 私有属性
    let say = /*私有方法*/ function () {
        console.log("私有方式:动物 %s 说 %s", username, language);
    };
    this.username = username; // 公有属性
    this.language = language; // 公有属性
}
AnimalClass.prototype.say = /*公有方法*/ function () {
    console.log("动物 %s 说 %s", this.username, this.language);
};
AnimalClass.prototype.skill = /*公有方法*/ function () {
    console.log("%s 可以上树", this.username);
};
AnimalClass.username = "原始动物"; // 静态方法
AnimalClass.say = /*静态方法*/ function () {
    console.log("我是一个 %s", AnimalClass.username);
};
const cat = new AnimalClass("猫", "喵喵喵"); // "仿 Class" 实例化对象
const dog = new AnimalClass("狗", "汪汪汪"); // "仿 Class" 实例化对象
dog.skill = /*方法重写创建多态*/ function () {
    console.log("%s 不可以上树", this.username);
};
cat.say(); // 继承 say 方法
dog.say(); // 继承 say 方法
cat.skill(); // 多态 skill 方法
dog.skill(); // 多态 skill 方法
// 类和实例都有自己的属性和方法
AnimalClass.say();

// ===== class 模式 =====
class AnimalClass {
    #username = "私有名字"; // 私有属性
    #language = "私有语言"; // 私有属性
    /*私有方法*/ #say() {
        console.log("私有方式:动物 %s 说 %s", this.#username, this.#language);
    }
    /*执行私有方法*/ privateSay() {
        this.#say();
    }
    /* 构造函数*/ constructor(username, language) {
        this.username = username; // 公有属性
        this.language = language; // 公有属性
    }
    /*公有方法*/ say() {
        console.log("动物 %s 说 %s", this.username, this.language);
    }
    /*公有方法*/ skill() {
        console.log("%s 可以上树", this.username);
    }
    /*静态属性*/ static username = "原始动物";
    /*静态方法*/ static say() {
        console.log("我是一个 %s", AnimalClass.username);
    }
}
const cat = new AnimalClass("猫", "喵喵喵"); // Class 实例化对象
const dog = new AnimalClass("狗", "汪汪汪"); // Class 实例化对象
dog.skill = /*方法重写创建多态*/ function () {
    console.log("%s 不可以上树", this.username);
};
cat.say(); // 继承 say 方法
dog.say(); // 继承 say 方法
cat.skill(); // 多态 skill 方法
dog.skill(); // 多态 skill 方法
// 类和实例都有自己的属性和方法
AnimalClass.say();

// ===== 子类 extends =====
class Dog extends AnimalClass {
    // constructor 可选,在派生类中选了就必须 super() 或者 返回一个对象
    constructor(race) {
        // super 之前没有 this
        // super 只属于派生类
        // super 不能单独使用,只能 super() 或者 super.parentStaticeFunc()
        super("狗", "汪汪汪"); // 等同于 super.constructor(), 调用父类的构造函数,将返回的实例赋值给 this
        this.dogRace = race; // 狗的品种
    }
}
const dog_husky = new Dog("哈士奇");
console.log(dog_husky);
/**
 * 标准的 OOP 需要具备封装、继承、多态能力
 * 封装:JS 可以通过 "function 函数作用域" 实现
 * 继承:JS 可以通过 "this 作用域链" 、 "prototype 原型链" 实现
 * 多态:JS 可以通过 "属性重写/属性拓展"、"方法重写/方法拓展" 实现
 * ====
 * 私有成员:只能在类内部访问
 * 公有成员:类可以访问,实例对象通过继承可以访问,内部外部不受限制
 * 静态成员:只有类可以访问,内部外部不受限制
 */

// ===== "仿 Class" 模式 =====
function AnimalClass(username, language) {
    // 函数作用域封装属性
    let username = "私有名字"; // 私有属性
    let language = "私有语言"; // 私有属性
    let say = /*私有方法*/ function () {
        console.log("私有方式:动物 %s 说 %s", username, language);
    };
    this.username = username; // 公有属性
    this.language = language; // 公有属性
}
AnimalClass.prototype.say = /*公有方法*/ function () {
    console.log("动物 %s 说 %s", this.username, this.language);
};
AnimalClass.prototype.skill = /*公有方法*/ function () {
    console.log("%s 可以上树", this.username);
};
AnimalClass.username = "原始动物"; // 静态方法
AnimalClass.say = /*静态方法*/ function () {
    console.log("我是一个 %s", AnimalClass.username);
};
const cat = new AnimalClass("猫", "喵喵喵"); // "仿 Class" 实例化对象
const dog = new AnimalClass("狗", "汪汪汪"); // "仿 Class" 实例化对象
dog.skill = /*方法重写创建多态*/ function () {
    console.log("%s 不可以上树", this.username);
};
cat.say(); // 继承 say 方法
dog.say(); // 继承 say 方法
cat.skill(); // 多态 skill 方法
dog.skill(); // 多态 skill 方法
// 类和实例都有自己的属性和方法
AnimalClass.say();

// ===== class 模式 =====
class AnimalClass {
    #username = "私有名字"; // 私有属性
    #language = "私有语言"; // 私有属性
    /*私有方法*/ #say() {
        console.log("私有方式:动物 %s 说 %s", this.#username, this.#language);
    }
    /*执行私有方法*/ privateSay() {
        this.#say();
    }
    /* 构造函数*/ constructor(username, language) {
        this.username = username; // 公有属性
        this.language = language; // 公有属性
    }
    /*公有方法*/ say() {
        console.log("动物 %s 说 %s", this.username, this.language);
    }
    /*公有方法*/ skill() {
        console.log("%s 可以上树", this.username);
    }
    /*静态属性*/ static username = "原始动物";
    /*静态方法*/ static say() {
        console.log("我是一个 %s", AnimalClass.username);
    }
}
const cat = new AnimalClass("猫", "喵喵喵"); // Class 实例化对象
const dog = new AnimalClass("狗", "汪汪汪"); // Class 实例化对象
dog.skill = /*方法重写创建多态*/ function () {
    console.log("%s 不可以上树", this.username);
};
cat.say(); // 继承 say 方法
dog.say(); // 继承 say 方法
cat.skill(); // 多态 skill 方法
dog.skill(); // 多态 skill 方法
// 类和实例都有自己的属性和方法
AnimalClass.say();

// ===== 子类 extends =====
class Dog extends AnimalClass {
    // constructor 可选,在派生类中选了就必须 super() 或者 返回一个对象
    constructor(race) {
        // super 之前没有 this
        // super 只属于派生类
        // super 不能单独使用,只能 super() 或者 super.parentStaticeFunc()
        super("狗", "汪汪汪"); // 等同于 super.constructor(), 调用父类的构造函数,将返回的实例赋值给 this
        this.dogRace = race; // 狗的品种
    }
}
const dog_husky = new Dog("哈士奇");
console.log(dog_husky);

༼ つ/̵͇̿̿/’̿’̿ ̿ ̿̿ ̿̿◕ _◕ ༽つ/̵͇̿̿/’̿’̿ ̿ ̿̿ ̿̿ ̿̿