摘要:在本教程中,你将学习Python中的面向对象编程,包括对象、类、属性、方法、继承、方法重写等基本概念。
Python面向对象编程简介
在Python中,一切皆为对象。对象具有状态(属性)和行为(方法)。要创建对象,首先需要定义一个类。然后,你可以从该类中创建一个或多个对象。这些对象是类的实例。
定义类
要定义一个类,需要使用class
关键字,后跟类名。例如,以下代码定义了一个Person
类:
class Person:
pass
要从Person
类创建一个对象,你可以使用类名后跟一对圆括号()
,这类似于调用一个函数:
person = Person()
在这个例子中的person
是 Person
类的一个实例。类是可调用的(即可以通过类名加括号的方式创建实例)。
定义实例属性
Python是动态类型的语言。这意味着你可以在运行时动态地为类的实例添加属性。
例如,下面的代码为person
对象添加了一个name
属性:
person.name = 'John'
然而,如果你创建另一个Person
对象,这个新对象将不会拥有name
属性。
要为类的所有实例定义并初始化属性,你可以使用__init__
方法。下面的代码定义了一个带有两个实例属性name
和age
的Person
类:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
当你创建一个Person
对象时,Python会自动调用__init__
方法来初始化实例属性。在__init__
方法中,self
参数表示Person
类的实例。
以下代码创建了一个名为person
的Person
对象:
person = Person('John', 25)
person
对象现在拥有name
和age
属性。要访问实例属性,可以使用点号表示法(dot notation)。例如,以下代码返回person
对象的name
属性的值:
person.name
定义实例方法
以下代码向Person
类中添加了一个名为greet()
的实例方法:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"Hi, it's {self.name}."
要调用实例方法,同样需要使用点号表示法(dot notation)。例如:
person = Person('John', 25)
print(person.greet())
输出:
Hi, it's John
定义类属性
与实例属性不同,类属性(class attributes)由类的所有实例共享。如果你需要定义类常量(例如固定值)或全局计数器(例如跟踪类的实例数量),类属性非常有用。
例如,以下代码在Person
类中定义了一个名为counter
的类属性:
class Person:
counter = 0
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"Hi, it's {self.name}."
你可以通过Person
类直接访问counter
属性:
Person.counter
或者从任何 Person
类的实例(对象)中:
person = Person('John',25)
person.counter
为了让计数器变量更有用,你可以在创建一个对象时将其值增加 1。为此,你可以在 __init__
方法中增加计数器的类属性值:
class Person:
counter = 0
def __init__(self, name, age):
self.name = name
self.age = age
Person.counter += 1
def greet(self):
return f"Hi, it's {self.name}."
以下代码创建了两个 Person
类的实例,并展示了计数器的值:
p1 = Person('John', 25)
p2 = Person('Jane', 22)
print(Person.counter)
输出:
2
类方法的定义
与类属性类似,类方法由类的所有实例共享。类方法的第一个参数是类本身。按照惯例,这个参数的名称是 cls
。Python 会自动将这个参数传递给类方法。此外,你可以使用 @classmethod
装饰器来定义一个类方法。
以下示例定义了一个类方法,该方法返回一个匿名的 Person
对象:
class Person:
counter = 0
def __init__(self, name, age):
self.name = name
self.age = age
Person.counter += 1
def greet(self):
return f"Hi, it's {self.name}."
@classmethod
def create_anonymous(cls):
return Person('Anonymous', 22)
以下展示了如何调用 create_anonymous()
类方法:
anonymous = Person.create_anonymous()
print(anonymous.name) # Anonymous
静态方法的定义
静态方法既不绑定到类本身,也不绑定到类的任何实例。在 Python 中,你可以使用静态方法来将逻辑上相关的函数组织在一个类中。要定义一个静态方法,你需要使用 @staticmethod
装饰器。
例如,以下代码定义了一个 TemperatureConverter
类,其中包含两个静态方法,分别用于将摄氏度转换为华氏度,以及将华氏度转换为摄氏度:
class TemperatureConverter:
@staticmethod
def celsius_to_fahrenheit(c):
return 9 * c / 5 + 32
@staticmethod
def fahrenheit_to_celsius(f):
return 5 * (f - 32) / 9
要调用静态方法,你可以使用 ClassName.static_method_name()
的语法。例如:
f = TemperatureConverter.celsius_to_fahrenheit(30)
print(f) # 86
注意,Python 不会隐式地将实例(self
)或类(cls
)作为静态方法的第一个参数传递。
单继承
一个类可以通过继承另一个类来复用其功能。当子类从父类继承时,子类可以访问父类的属性和方法。
例如,你可以定义一个 Employee
类,使其从 Person
类继承:
class Employee(Person):
def __init__(self, name, age, job_title):
super().__init__(name, age)
self.job_title = job_title
在 Employee
类的 __init__
方法中,通过调用 Person
类的 __init__
方法来初始化 name
和 age
属性。super()
函数允许子类访问父类的方法。
Employee
类通过新增一个名为 job_title
的属性,扩展了 Person
类的功能。
Person
类是父类,而 Employee
类是子类。要重写 Person
类中的 greet()
方法,你可以在 Employee
类中按如下方式定义 greet()
方法:
class Employee(Person):
def __init__(self, name, age, job_title):
super().__init__(name, age)
self.job_title = job_title
def greet(self):
return super().greet() + f" I'm a {self.job_title}."
Employee
类中的 greet()
方法也调用了 Person
类的 greet()
方法。换句话说,它委托给了父类的方法。
以下代码创建了一个新的 Employee
类实例,并调用了 greet()
方法:
employee = Employee('John', 25, 'Python Developer')
print(employee.greet())
输出:
Hi, it's John. I'm a Python Developer.
总结
在本教程中,你学习了 Python 中面向对象编程(Object-Oriented Programming,简称 OOP)的简要概述。