在Python中,一切都是对象,对象是类的实例,类是对象的蓝图和模板。类是一个抽象的概念,对象是一个类具体的实例。每个对象都有属性和行为,它们都是独一无二的,而且对象一定属于某个类。当我们把一大堆拥有共同特征的对象的静态特征(属性)和动态特征(行为)都抽取出来后,就可以定义出一个类。例如:学生都有学号、姓名等信息(属性),并且都有学习、吃饭等行为,我们就可以把所有学生抽象成一个学生类,而一个具体的学生就是一个对象。
定义类
使用 class 定义类,在类中定义的函数称为方法,下面的例子演示了如何定义一个学生类以及在类中定义方法。
class Student:
"""一个简单的学生类"""
def __init__(self, id, name):
"""初始化属性 id 和 name """
self.id = id
self.name = name
def study(self, course):
"""学生正在学习的课程"""
print(f'{self.name} 正在学习 {course}')
def eat(self):
"""模拟学生正在吃饭"""
print(f'{self.name} 正在吃饭')
其中,形参 self 必不可少,形参 self 代表类的实例,类的方法都必须有一个额外的参数 self ,必须位于其他形参的前面。 __init__() 是一个特殊方法,该方法用于在创建对象时进行初始化操作,即用户创建新实例时,都会自动运行它,请务必保证 __init__() 左右两边都有两个下划线。
使用类创建对象
当我们创建好类之后,就可以通过下面的方式创建类的实例(对象),并调用该实例的方法。
stu = Student('10010', 'Mary')
stu.study('Chinese')
stu.eat()
运行后的结果如下
Mary 正在学习 Chinese Mary 正在吃饭 |
属性和方法的访问权限
在大多数面向对象编程语言中,通常会对对象的属性以及方法进行权限设置,例如在C++中有公有的(public)、私有的(private)和受保护的(protected)三种权限设置。而在Python中,属性和方法的访问权限只有两种,即公开的和私有的。默认属性是公开的,如果想要把属性设置成私有的,在属性命名时可以用两个下划线作为开头,以示此属性为私有的。
class Teacher:
"""一个简单的老师类"""
def __init__(self, name, age):
"""初始化属性 name 和 age """
self.name = name
self.__age = age
def __get_age(self):
"""获取 age"""
print(self.__age)
if __name__ == '__main__':
tea1 = Teacher('Mary', 30)
print(tea1.name)
print(tea1.__age)
tea1.__get_age()
当运行上面的程序时,tea1 的 name 会被打印出来,因为 name 是公有的属性。但是打印不了 __age 信息,因为 __age 属性和 __get_age() 方法都是私有的。
获取和修改属性
在Python中,如果想要获取或者修改对象的属性,可以直接写获取或者修改属性值的方法。当然,我们也可以使用 @property包装器 来包装getter和setter方法,使得对属性的获取更加方便。
class Student:
"""一个简单的学生类"""
def __init__(self, id, name):
"""初始化属性 id 和 name """
self._id = id
self._name = name
# getter 方法 - 访问器
@property
def id(self):
return self._id
# setter 方法 - 修改器
@id.setter
def id(self, id):
self._id = id
# getter 方法 - 访问器
@property
def name(self):
return self._name
# setter 方法 - 修改器
@name.setter
def name(self, name):
self._name = name
def study(self, course):
"""学生正在学习的课程"""
print(f'{self._name} 正在学习 {course}')
if __name__ == '__main__':
stu = Student('10010', 'Mary')
stu.name = 'John'
stu.id = '20020'
print(stu.id)
stu.study('Chinese')
输出的结果为
20020 John 正在学习 Chinese |
继承
在Python中,可以在已有类的基础上创建新的类,这种方式称之为继承。已有的基础类我们称之为父类或超类或基类,在父类基础上创建的新类称之为子类或派生类或衍生类。子类继承了父类的所有属性和方法,同时还可以自定义自己的属性和方法。
class Person(object):
"""人类"""
def __init__(self, name, age):
"""初始化属性 name 和 age"""
self._name = name
self._age = age
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
@property
def age(self):
return self._age
@age.setter
def age(self, age):
self._age = age
def play(self):
"""模拟人玩耍的方法"""
print(f'{self._name} 正在玩耍')
class Student(Person):
"""学生类"""
def __init__(self, name, age, id):
"""初始化属性"""
# 调用父类构造方法初始化属性值
super().__init__(name, age)
self._id = id
@property
def id(self):
return self._id
@id.setter
def id(self, id):
self._id = id
def study(self, course):
"""学生正在学习的课程"""
print(f'{self._name} 正在学习 {course}')
if __name__ == '__main__':
stu = Student('Mary', 16, '10010')
stu.study('Chinese')
stu.play()
结果输出为
Mary 正在学习 Chinese Mary 正在玩耍 |
多态
子类在继承了父类的方法后,可以对父类已有的方法进行重写(override)。通过方法重写可以让父类的同一个行为在子类中拥有不同的实现版本,即同一个父类的不同的子类对象调用同个父类的方法会表现出不同的行为,这称之为多态。
class Animals(object):
"""动物类"""
def __init__(self, name):
"""初始化属性 name """
self._name = name
def speak(self):
"""模拟动物发声的方法"""
pass
class Dog(Animals):
"""狗类"""
def __init__(self, name):
"""初始化属性"""
super().__init__(name)
def speak(self):
"""模拟狗发声的方法"""
print('汪汪汪')
class Cat(Animals):
"""猫类"""
def __init__(self, name):
"""初始化属性"""
super().__init__(name)
def speak(self):
"""模拟猫发声的方法"""
print('喵喵喵')
if __name__ == '__main__':
dog = Dog('dog')
dog.speak()
cat = Cat('cat')
cat.speak()
结果输出为
汪汪汪 喵喵喵 |