面向对象编程
类和对象
Python 面向对象编程
基本类定义
python
# Python - 基本类定义
class Person:
"""人类类"""
# 类变量
species = "Homo sapiens"
def __init__(self, name, age):
"""构造函数"""
self.name = name # 实例变量
self.age = age
self._private_var = "私有变量" # 约定私有变量
def introduce(self):
"""自我介绍方法"""
return f"我叫 {self.name},今年 {self.age} 岁"
def have_birthday(self):
"""过生日方法"""
self.age += 1
return f"{self.name} 过生日了,现在 {self.age} 岁"
@property
def is_adult(self):
"""属性方法"""
return self.age >= 18
@classmethod
def create_anonymous(cls):
"""类方法"""
return cls("匿名", 0)
@staticmethod
def is_valid_age(age):
"""静态方法"""
return 0 <= age <= 150
# 创建对象
person1 = Person("Alice", 25)
person2 = Person("Bob", 30)
# 调用方法
print(person1.introduce()) # 我叫 Alice,今年 25 岁
print(person2.have_birthday()) # Bob 过生日了,现在 31 岁
print(person1.is_adult) # True
# 使用类方法
anonymous = Person.create_anonymous()
print(anonymous.introduce()) # 我叫 匿名,今年 0 岁
# 使用静态方法
print(Person.is_valid_age(200)) # False继承
python
# Python - 继承
class Student(Person):
"""学生类,继承自 Person"""
def __init__(self, name, age, student_id, major):
# 调用父类构造函数
super().__init__(name, age)
self.student_id = student_id
self.major = major
self.grades = []
def add_grade(self, grade):
"""添加成绩"""
self.grades.append(grade)
def get_average(self):
"""计算平均分"""
if not self.grades:
return 0
return sum(self.grades) / len(self.grades)
def introduce(self):
"""重写父类方法"""
base_intro = super().introduce()
return f"{base_intro},学号 {self.student_id},专业 {self.major}"
# 创建学生对象
student = Student("Charlie", 20, "2023001", "计算机科学")
student.add_grade(85)
student.add_grade(92)
student.add_grade(78)
print(student.introduce()) # 我叫 Charlie,今年 20 岁,学号 2023001,专业 计算机科学
print(f"平均分: {student.get_average():.1f}") # 平均分: 85.0多态和抽象类
python
# Python - 多态和抽象类
from abc import ABC, abstractmethod
class Animal(ABC):
"""抽象动物类"""
def __init__(self, name):
self.name = name
@abstractmethod
def make_sound(self):
"""抽象方法"""
pass
def introduce(self):
return f"我是 {self.name}"
class Dog(Animal):
"""狗类"""
def make_sound(self):
return "汪汪!"
def fetch(self):
return f"{self.name} 在捡球"
class Cat(Animal):
"""猫类"""
def make_sound(self):
return "喵喵!"
def climb(self):
return f"{self.name} 在爬树"
# 多态示例
animals = [Dog("旺财"), Cat("咪咪")]
for animal in animals:
print(f"{animal.introduce()}: {animal.make_sound()}")
# 我是 旺财: 汪汪!
# 我是 咪咪: 喵喵!特殊方法
python
# Python - 特殊方法
class Vector:
"""向量类"""
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
"""字符串表示"""
return f"Vector({self.x}, {self.y})"
def __repr__(self):
"""详细字符串表示"""
return f"Vector(x={self.x}, y={self.y})"
def __add__(self, other):
"""加法运算"""
return Vector(self.x + other.x, self.y + other.y)
def __sub__(self, other):
"""减法运算"""
return Vector(self.x - other.x, self.y - other.y)
def __eq__(self, other):
"""相等比较"""
return self.x == other.x and self.y == other.y
def __len__(self):
"""长度(模长)"""
return int((self.x ** 2 + self.y ** 2) ** 0.5)
# 使用特殊方法
v1 = Vector(3, 4)
v2 = Vector(1, 2)
print(v1) # Vector(3, 4)
print(v1 + v2) # Vector(4, 6)
print(v1 - v2) # Vector(2, 2)
print(v1 == v2) # False
print(len(v1)) # 5JavaScript 面向对象编程
基本类定义
javascript
// JavaScript - 基本类定义
class Person {
// 类变量(静态属性)
static species = "Homo sapiens";
constructor(name, age) {
this.name = name; // 实例变量
this.age = age;
this._privateVar = "私有变量"; // 约定私有变量
}
introduce() {
return `我叫 ${this.name},今年 ${this.age} 岁`;
}
haveBirthday() {
this.age += 1;
return `${this.name} 过生日了,现在 ${this.age} 岁`;
}
// Getter 属性
get isAdult() {
return this.age >= 18;
}
// 静态方法
static createAnonymous() {
return new Person("匿名", 0);
}
static isValidAge(age) {
return age >= 0 && age <= 150;
}
}
// 创建对象
const person1 = new Person("Alice", 25);
const person2 = new Person("Bob", 30);
// 调用方法
console.log(person1.introduce()); // 我叫 Alice,今年 25 岁
console.log(person2.haveBirthday()); // Bob 过生日了,现在 31 岁
console.log(person1.isAdult); // true
// 使用静态方法
const anonymous = Person.createAnonymous();
console.log(anonymous.introduce()); // 我叫 匿名,今年 0 岁
// 使用静态方法
console.log(Person.isValidAge(200)); // false继承
javascript
// JavaScript - 继承
class Student extends Person {
constructor(name, age, studentId, major) {
super(name, age); // 调用父类构造函数
this.studentId = studentId;
this.major = major;
this.grades = [];
}
addGrade(grade) {
this.grades.push(grade);
}
getAverage() {
if (this.grades.length === 0) {
return 0;
}
return (
this.grades.reduce((sum, grade) => sum + grade, 0) / this.grades.length
);
}
introduce() {
const baseIntro = super.introduce();
return `${baseIntro},学号 ${this.studentId},专业 ${this.major}`;
}
}
// 创建学生对象
const student = new Student("Charlie", 20, "2023001", "计算机科学");
student.addGrade(85);
student.addGrade(92);
student.addGrade(78);
console.log(student.introduce()); // 我叫 Charlie,今年 20 岁,学号 2023001,专业 计算机科学
console.log(`平均分: ${student.getAverage().toFixed(1)}`); // 平均分: 85.0多态和接口
javascript
// JavaScript - 多态(通过继承实现)
class Animal {
constructor(name) {
this.name = name;
}
makeSound() {
throw new Error("子类必须实现 makeSound 方法");
}
introduce() {
return `我是 ${this.name}`;
}
}
class Dog extends Animal {
makeSound() {
return "汪汪!";
}
fetch() {
return `${this.name} 在捡球`;
}
}
class Cat extends Animal {
makeSound() {
return "喵喵!";
}
climb() {
return `${this.name} 在爬树`;
}
}
// 多态示例
const animals = [new Dog("旺财"), new Cat("咪咪")];
animals.forEach((animal) => {
console.log(`${animal.introduce()}: ${animal.makeSound()}`);
// 我是 旺财: 汪汪!
// 我是 咪咪: 喵喵!
});特殊方法和操作符重载
javascript
// JavaScript - 特殊方法(通过 Symbol 实现)
class Vector {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return `Vector(${this.x}, ${this.y})`;
}
valueOf() {
return Math.sqrt(this.x ** 2 + this.y ** 2);
}
// 自定义方法
add(other) {
return new Vector(this.x + other.x, this.y + other.y);
}
subtract(other) {
return new Vector(this.x - other.x, this.y - other.y);
}
equals(other) {
return this.x === other.x && this.y === other.y;
}
get length() {
return Math.sqrt(this.x ** 2 + this.y ** 2);
}
}
// 使用特殊方法
const v1 = new Vector(3, 4);
const v2 = new Vector(1, 2);
console.log(v1.toString()); // Vector(3, 4)
console.log(v1.add(v2).toString()); // Vector(4, 6)
console.log(v1.subtract(v2).toString()); // Vector(2, 2)
console.log(v1.equals(v2)); // false
console.log(v1.length); // 5面向对象特性对比
| 特性 | Python | JavaScript |
|---|---|---|
| 类定义 | class ClassName: | class ClassName {} |
| 构造函数 | __init__(self) | constructor() |
| 继承 | class Child(Parent): | class Child extends Parent |
| 方法调用 | self.method() | this.method() |
| 私有变量 | _variable (约定) | #variable (ES2022) |
| 属性 | @property | get property() |
| 静态方法 | @classmethod | static method() |
| 抽象类 | ABC + @abstractmethod | 无内置支持 |
高级面向对象特性
Python 高级特性
python
# Python - 多重继承
class Flyable:
def fly(self):
return f"{self.name} 在飞行"
class Swimmable:
def swim(self):
return f"{self.name} 在游泳"
class Duck(Animal, Flyable, Swimmable):
def make_sound(self):
return "嘎嘎!"
# 使用多重继承
duck = Duck("唐老鸭")
print(duck.make_sound()) # 嘎嘎!
print(duck.fly()) # 唐老鸭 在飞行
print(duck.swim()) # 唐老鸭 在游泳
# Python - 混入类
class LoggerMixin:
def log(self, message):
print(f"[{self.__class__.__name__}] {message}")
class LoggedPerson(Person, LoggerMixin):
def introduce(self):
self.log("正在自我介绍")
return super().introduce()
# 使用混入类
logged_person = LoggedPerson("Alice", 25)
print(logged_person.introduce())
# [LoggedPerson] 正在自我介绍
# 我叫 Alice,今年 25 岁JavaScript 高级特性
javascript
// JavaScript - 混入模式
const LoggerMixin = {
log(message) {
console.log(`[${this.constructor.name}] ${message}`);
},
};
class LoggedPerson extends Person {
introduce() {
this.log("正在自我介绍");
return super.introduce();
}
}
// 应用混入
Object.assign(LoggedPerson.prototype, LoggerMixin);
// 使用混入
const loggedPerson = new LoggedPerson("Alice", 25);
console.log(loggedPerson.introduce());
// [LoggedPerson] 正在自我介绍
// 我叫 Alice,今年 25 岁
// JavaScript - 组合模式
class Composable {
constructor() {
this.methods = new Map();
}
addMethod(name, method) {
this.methods.set(name, method);
}
callMethod(name, ...args) {
const method = this.methods.get(name);
if (method) {
return method.apply(this, args);
}
throw new Error(`方法 ${name} 不存在`);
}
}
// 使用组合模式
const composable = new Composable();
composable.addMethod("greet", function (name) {
return `Hello, ${name}!`;
});
console.log(composable.callMethod("greet", "World")); // Hello, World!设计模式
Python 设计模式
python
# Python - 单例模式
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self):
if not hasattr(self, 'initialized'):
self.data = []
self.initialized = True
def add_data(self, item):
self.data.append(item)
def get_data(self):
return self.data.copy()
# 使用单例
singleton1 = Singleton()
singleton2 = Singleton()
print(singleton1 is singleton2) # True
# Python - 工厂模式
class AnimalFactory:
@staticmethod
def create_animal(animal_type, name):
if animal_type == "dog":
return Dog(name)
elif animal_type == "cat":
return Cat(name)
else:
raise ValueError(f"未知的动物类型: {animal_type}")
# 使用工厂
dog = AnimalFactory.create_animal("dog", "旺财")
cat = AnimalFactory.create_animal("cat", "咪咪")JavaScript 设计模式
javascript
// JavaScript - 单例模式
class Singleton {
static instance = null;
constructor() {
if (Singleton.instance) {
return Singleton.instance;
}
this.data = [];
Singleton.instance = this;
}
addData(item) {
this.data.push(item);
}
getData() {
return [...this.data];
}
}
// 使用单例
const singleton1 = new Singleton();
const singleton2 = new Singleton();
console.log(singleton1 === singleton2); // true
// JavaScript - 工厂模式
class AnimalFactory {
static createAnimal(animalType, name) {
switch (animalType) {
case "dog":
return new Dog(name);
case "cat":
return new Cat(name);
default:
throw new Error(`未知的动物类型: ${animalType}`);
}
}
}
// 使用工厂
const dog = AnimalFactory.createAnimal("dog", "旺财");
const cat = AnimalFactory.createAnimal("cat", "咪咪");练习
- 创建一个
BankAccount类,包含存款、取款、查询余额功能
参考答案:
python
# Python
class BankAccount:
def __init__(self, balance=0):
self.balance = balance
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount
else:
print("余额不足")
def get_balance(self):
return self.balance
acc = BankAccount(100)
acc.deposit(50)
acc.withdraw(30)
print(acc.get_balance())javascript
// JavaScript
class BankAccount {
constructor(balance = 0) {
this.balance = balance;
}
deposit(amount) {
this.balance += amount;
}
withdraw(amount) {
if (amount <= this.balance) {
this.balance -= amount;
} else {
console.log("余额不足");
}
}
getBalance() {
return this.balance;
}
}
const acc = new BankAccount(100);
acc.deposit(50);
acc.withdraw(30);
console.log(acc.getBalance());- 实现一个
Shape抽象类,创建Circle、Rectangle、Triangle子类
参考答案:
python
# Python
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
class Circle(Shape):
def __init__(self, r):
self.r = r
def area(self):
return 3.14 * self.r ** 2
class Rectangle(Shape):
def __init__(self, w, h):
self.w = w
self.h = h
def area(self):
return self.w * self.h
class Triangle(Shape):
def __init__(self, b, h):
self.b = b
self.h = h
def area(self):
return 0.5 * self.b * self.h
shapes = [Circle(2), Rectangle(3, 4), Triangle(3, 5)]
for s in shapes:
print(s.area())javascript
// JavaScript
class Shape {
area() {
throw new Error("必须实现 area 方法");
}
}
class Circle extends Shape {
constructor(r) {
super();
this.r = r;
}
area() {
return Math.PI * this.r ** 2;
}
}
class Rectangle extends Shape {
constructor(w, h) {
super();
this.w = w;
this.h = h;
}
area() {
return this.w * this.h;
}
}
class Triangle extends Shape {
constructor(b, h) {
super();
this.b = b;
this.h = h;
}
area() {
return 0.5 * this.b * this.h;
}
}
const shapes = [new Circle(2), new Rectangle(3, 4), new Triangle(3, 5)];
shapes.forEach((s) => console.log(s.area()));- 使用继承创建一个简单的游戏角色系统
参考答案:
python
# Python
class Character:
def __init__(self, name, hp):
self.name = name
self.hp = hp
def attack(self, target):
print(f"{self.name} 攻击 {target.name}")
class Warrior(Character):
def attack(self, target):
print(f"{self.name} 用剑砍 {target.name}")
class Mage(Character):
def attack(self, target):
print(f"{self.name} 释放魔法攻击 {target.name}")
hero = Warrior("战士", 100)
villain = Mage("法师", 80)
hero.attack(villain)
villain.attack(hero)javascript
// JavaScript
class Character {
constructor(name, hp) {
this.name = name;
this.hp = hp;
}
attack(target) {
console.log(`${this.name} 攻击 ${target.name}`);
}
}
class Warrior extends Character {
attack(target) {
console.log(`${this.name} 用剑砍 ${target.name}`);
}
}
class Mage extends Character {
attack(target) {
console.log(`${this.name} 释放魔法攻击 ${target.name}`);
}
}
const hero = new Warrior("战士", 100);
const villain = new Mage("法师", 80);
hero.attack(villain);
villain.attack(hero);- 实现单例模式来管理应用程序配置
参考答案:
python
# Python
class Config:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self):
self.value = 42
cfg1 = Config()
cfg2 = Config()
print(cfg1 is cfg2)javascript
// JavaScript
class Config {
constructor() {
if (Config.instance) return Config.instance;
this.value = 42;
Config.instance = this;
}
}
const cfg1 = new Config();
const cfg2 = new Config();
console.log(cfg1 === cfg2);- 比较 Python 和 JavaScript 的面向对象特性差异
参考答案:
- Python 支持多继承、抽象基类、属性装饰器、数据描述符。
- JavaScript 只支持单继承,类本质是语法糖,原型链机制。
- Python 有私有属性(约定 _/__),JS 没有真正私有(ES6 有 # 私有字段)。
- 两者都支持多态、继承、封装。
下一步
现在你已经了解了面向对象编程,接下来我们将学习异常处理。