面向对象
面向对象(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);