面相对象编程
面相对象编程
面向对象编程是编程里通用的概念,不只 Python 中存在。一切事物都可以定义为一个对象。比如一只猫,一个手机等等。通过对象来描述客观事物,由属性和方法组成。
面向对象的主要概念包括类(Class)、对象(Object)、封装(Encapsulation)、继承(Inheritance)和多态(Polymorphism)。
一、 类和对象
类
类是对象的模板。它定义了对象的属性和方法。通过类,我们可以创建多个具有相同属性和方法的对象。
属性是指对象具有的静态特征(变量),方法是指对象具有的各种动态的行为(函数)。
class Cat:
# 初始化方法(构造函数)
def __init__(self, name, age):
self.name = name # 实例属性
self.age = age # 实例属性
# 实例方法
def description(self):
return f"{self.name}{self.age}岁了"
def speak(self, sound):
return f"{self.name}: {sound}"
而对象是类的实例表现。
对于 Cat
类就可以创建出不同的 Cat
的对象
# 创建对象,名字是小猫,年龄是3岁了
my_cat = Cat("小猫", 3)
# 访问属性
print(my_cat.name)
print(my_cat.age)
# 调用方法
print(my_cat.description())
print(my_cat.speak("喵喵喵"))
小猫
3
小猫3岁了
小猫: 喵喵喵
类经过实例化变成对象
构造函数
在类的定义中,__init__
作为函数名称的函数称为构造函数,构造函数只能有一个,在创建对象的时候会被执行。
def __init__(self, name):
self.name = name
方法参数
类中方法都有一个默认的参数 self 放在第一个位置。这个参数必须有,虽然可以使用其他名字(但是不建议)。
在调用方法时,可以忽略 self
参数,依次传递后续的参数。
二、面向对象三大特性
封装
封装是将数据(属性)和行为(方法)绑定在一起,并隐藏对象的内部实现细节,只暴露必要的接口给外界。通过封装,我们可以保护数据不被随意修改。
公有和私有属性
在 Python 中,以单下划线 _
开头的属性是“受保护的”,以双下划线 __
开头的属性是“私有的”。
class Person:
def __init__(self, name, age):
self.name = name # 公有属性
self._age = age # 受保护的属性
def get_age(self):
return self._age
def set_age(self, age):
if age > 0:
self._age = age
else:
print("Age must be positive")
# 创建对象
person = Person("张三", 20)
# 访问公有属性
print(person.name)
# 访问受保护的属性(不建议直接访问)
print(person._age)
# 通过方法访问受保护的属性
print(person.get_age())
# 修改受保护的属性
person.set_age(35)
print(person.get_age())
张三
20
20
35
继承
继承是一个类(子类)从另一个类(父类)获取属性和方法的机制。通过继承,我们可以重用代码,并创建更具层次结构的类。
基本继承
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
# 定义一个通用方法,子类需要重写
return f"{self.name}"
class Cat(Animal):
def speak(self):
return f"{self.name}:喵喵喵"
class Dog(Animal):
def speak(self):
return f"{self.name}:汪汪汪"
# 创建对象
cat = Cat("小猫")
dog = Dog("小狗")
# 调用子类方法
print(cat.speak())
print(dog.speak())
小猫:喵喵喵
小狗:汪汪汪
多态
多态是指同一个方法可以在不同的对象中有不同的表现形式。它允许我们在不考虑对象具体类型的情况下调用方法。
def make_animal_speak(animal):
print(animal.speak())
# 创建对象
cat = Cat("小猫")
dog = Dog("小狗")
# 调用多态方法
make_animal_speak(cat)
make_animal_speak(dog)
小猫:喵喵喵
小狗:汪汪汪
可以看到,虽然 make_animal_speak
中没有指定 animal
的类型,在执行的时候,程序可以自动根据对象的类型调用对象的方法。
三、类相关的方法
1. 判断是否类的实例
通过 isinstance(对象, 类)
函数可以判断一个对象是不是类的实例。
print(isinstance(my_cat, Cat))
print(isinstance(my_cat, dict))
True
False
可以看出 my_cat 是通过 Cat 类创建的。
2. 判断是否子类
通过 issubclass(类A, 类B)
函数可以判断一个类A是不是类B的子类。
print(issubclass(Cat, Animal))
True
3. 调用类中的方法
在类的方法中,可以直接类中其他的方法。可以看到每一个方法都会有一个固定的参数 self
, 表示当前的对象。通过 self.方法名(参数)
就可以调用类中其他的方法。
4. 静态方法
在方法上方加一个 @staticmethod
注解,可以将一个类的方法定义为静态方法。静态方法不需要通过实例访问,也不需要访问类属性。静态方法可以通过类本身直接调用,静态方法无需设置 self
参数。
class MathUtil:
@staticmethod
def add(a, b):
return a + b
@staticmethod
def subtract(a, b):
return a - b
print(MathUtil.add(1,2))
print(MathUtil.add(5,2))
3
7