在本章中,我们将深入探讨Python中的高级面向对象编程概念,包括封装、继承和多态。让我们开始吧!
目录
- 面向对象简介
- 类和实例
- 属性和方法
- 继承和多态
- 高级面向对象概念
- 私有变量
- 使用 `@property`
- 使用 `__slots__`
- 类的特殊成员
- `__doc__`
- `__call__`
- `__str__`
- `__iter__`
- `__getitem__`, `__setitem__`, `__delitem__`
面向对象简介
面向对象编程(OOP)是一种编程范式,它通过将数据和方法封装在对象中,使代码更加模块化和易于管理。通过这种方式,我们可以避免重复造轮子,提升代码的可维护性和可读性。
类和实例
在OOP中,类是对某类对象的抽象,而实例是类的具体对象。例如,我们可以定义一个Human
类来抽象表示人,并通过实例化该类来创建具体的人对象。
class Human:
def __init__(self, name, age):
self.name = name
self.age = age
def hello(self):
print(f"Hello, I'm {self.name}")
person1 = Human("Yingshan", 25)
person2 = Human(name="Lee", age=23)
person1.hello() # 输出: Hello, I'm Yingshan
person2.hello() # 输出: Hello, I'm Lee
属性和方法
类的属性是类中定义的数据,而方法是类中定义的函数。在上面的例子中,name
和age
是属性,hello
是方法。
继承和多态
继承是OOP的核心概念之一,通过继承,我们可以创建一个新类,该类继承自现有的类,获得其所有属性和方法。例如,我们可以创建一个Animal
类,然后让Human
类继承自Animal
类。
class Animal:
def mobile(self):
return "Yes, animals are mobile"
class Human(Animal):
def __init__(self, name, age):
self.name = name
self.age = age
def hello(self):
print(f"Hello, I'm {self.name}")
human = Human("Yingshan", 25)
print(human.mobile()) # 输出: Yes, animals are mobile
多态允许我们通过父类引用来调用子类的方法。在Python中,这可以通过方法重写实现。例如:
class Animal:
def mobile(self):
return "Yes, this animal is mobile"
class Human(Animal):
def __init__(self, name, age):
self.name = name
self.age = age
def hello(self):
print(f"Hello, I'm {self.name}")
def mobile(self):
return "Yes, this person is mobile"
human = Human("Yingshan", 25)
print(human.mobile()) # 输出: Yes, this person is mobile
高级面向对象概念
私有变量
在类中,通过在变量名前加双下划线,可以将变量设为私有变量,仅在类内部访问。
class Person:
def __init__(self, name):
self.__name = name
def get_name(self):
return self.__name
person = Person("XiaoYang")
print(person.get_name()) # 输出: XiaoYang
# print(person.__name) # 会报错,无法直接访问私有变量
使用 @property
使用 @property
装饰器,我们可以将方法转换为属性,从而更自然地访问和修改类的属性。
class Person:
def __init__(self, weight):
self.__weight = weight
@property
def weight(self):
return self.__weight
@weight.setter
def weight(self, value):
if value < 100:
print("Too light!")
elif value > 400:
print("Too heavy!")
else:
self.__weight = value
p1 = Person(160)
print(p1.weight) # 输出: 160
p1.weight = 450 # 输出: Too heavy!
使用 __slots__
为了限制实例的属性,我们可以使用 __slots__
。这可以节省内存空间。
class Person:
__slots__ = ('name', 'country')
p1 = Person()
p1.name = "XiaoYang"
p1.country = "China"
# p1.weight = 160 # 会报错,`weight` 不在 `__slots__` 中
类的特殊成员
__doc__
__doc__
表示类的文档字符串。
class Person:
"""
This is a person class.
"""
def __init__(self, name):
self.__name = name
print(Person.__doc__)
__call__
通过定义 __call__
方法,可以使对象变得可调用。
class Person:
def __init__(self, name):
self.__name = name
def __call__(self):
print("Calling myself")
yingshan = Person("Yingshan")
yingshan() # 输出: Calling myself
__str__
__str__
方法定义了对象的字符串表示。
class Person:
def __init__(self, name):
self.__name = name
def __str__(self):
return f"This is {self.__name}"
yingshan = Person("Yingshan")
print(yingshan) # 输出: This is Yingshan
__iter__
通过定义 __iter__
方法,可以将对象变为可迭代。
class Person:
def __init__(self, names):
self.__names = names
def __iter__(self):
return iter(self.__names)
friends = Person(["Yingshan", "Mike", "Tim"])
for friend in friends:
print(friend) # 依次输出: Yingshan, Mike, Tim
__getitem__
, __setitem__
, __delitem__
这些方法用于索引操作。
class Person:
def __init__(self):
self.dic = {}
def __setitem__(self, key, value):
self.dic[key] = value
def __getitem__(self, key):
return self.dic[key]
def __delitem__(self, key):
del self.dic[key]
obj = Person()
obj["name"] = "Yingshan"
print(obj["name"]) # 输出: Yingshan
del obj["name"]
通过面向对象编程,复杂的问题变得更易于解决。
希望这篇文章能帮助你更好地理解Python中的面向对象编程。Happy coding!