带你从入门到精通——Python(十. 面向对象二)
继承是指子类能够继承(复用)父类的共有属性和共有方法,并且可以添加新的属性和方法,或者重写(覆盖)父类的共有属性和共有方法以实现不同的功能。继承具有传递性,例如A类继承了B类,B类又继承了C类,则根据继承的传递性,则A类也会自动继承C类中的公共属性和公共方法,这种继承也被称为多层继承。父类:也叫作基类或超类,即被继承的类子类:也叫作派生类或扩展类,即继承父类的类。顶级类:通常值object类,Py
建议先阅读我之前的博客,掌握一定的Python前置知识后再阅读本文,链接如下:
带你从入门到精通——Python(一. 基础知识)-CSDN博客
带你从入门到精通——Python(二. 判断语句和循环语句)-CSDN博客
带你从入门到精通——Python(三. 函数基础)-CSDN博客
带你从入门到精通——Python(四. 五大容器一)-CSDN博客
带你从入门到精通——Python(五. 五大容器二)-CSDN博客
带你从入门到精通——Python(六. 函数进阶)-CSDN博客
带你从入门到精通——Python(七. 文件操作)-CSDN博客
带你从入门到精通——Python(八. 异常、模块和包)-CSDN博客
带你从入门到精通——Python(九. 面向对象一)-CSDN博客
目录
十. 面向对象二
面向对象的三大特性即为封装、继承、多态。
10.1 封装
封装即是指将属性和方法书写到类的里面的操作,此外,封装还可以通过在属性或方法名前面加上 '__' 的前缀为属性和方法添加私有权限,即设置某个属性或方法不继承给子类。
私有属性和私有方法只能在类的内部使用,不能在类的外部使用,如果想在类的外部使用需要设置用于操作私有属性和私有方法的公共方法(对于私有属性来说,通常设置名为get_私有属性名()和set_私有属性名()的公共方法来访问和修改私有属性)。
私有属性的封装示例如下:
class Girl():
def __init__(self, name):
self.name = name # 公共属性
self.__age = 18 # 私有属性
# 公共方法:提供给外部的访问接口
def get_age(self):
return self.__age
# 公共方法:提供给外部的设置接口
def set_age(self, age):
self.__age = age
girl = Girl('小美')
girl.set_age(19)
print(girl.get_age()) # 19
私有属性的封装可以明确地区分类内类外,控制在类外对私有属性的操作行为。
私有方法的封装示例如下:
class ATM():
def __card(self):
print('插卡')
def __auth(self):
print('用户认证')
def __input(self):
print('输入取款金额')
def __print_bill(self):
print('打印账单')
def __take_money(self):
print('取款')
# 定义一个对外提供服务的公共方法
def withdraw(self):
self.__card()
self.__auth()
self.__input()
self.__print_bill()
self.__take_money()
atm = ATM()
atm.withdraw()
'''
插卡
用户认证
输入取款金额
打印账单
取款
'''
私有方法的封装可以简化调用代码,降低程序复杂度。
10.2 继承
10.2.1 继承概述
继承是指子类能够继承(复用)父类的共有属性和共有方法,并且可以添加新的属性和方法,或者重写(覆盖)父类的共有属性和共有方法以实现不同的功能。
继承具有传递性,例如A类继承了B类,B类又继承了C类,则根据继承的传递性,则A类也会自动继承C类中的公共属性和公共方法,这种继承也被称为多层继承。
继承中的一些基本概念如下:
父类:也叫作基类或超类,即被继承的类
子类:也叫作派生类或扩展类,即继承父类的类。
顶级类:通常值object类,Python中所有的类都默认继承object类。
单继承:一个类只继承一个父类。
单继承的基本语法如下:
class Father(object):
pass
class Son(Father):
pass
多继承:一个类同时继承多个父类,Python中支持多继承, 格式为:class Son(Father,Mother)。
10.2.2 重写
重写也叫作覆盖指在子类中重新定义父类中的共有属性和共有方法,示例如下:
class Animal(object):
def eat(self):
print('I can eat')
def call(self):
print('I can call')
class Dog(Animal):
# 重写父类的call方法
def call(self):
print('wang wang wang')
class Cat(Animal):
# 重写父类的call方法
def call(self):
print('miao miao miao')
dog = Dog()
dog.eat() # I can eat
dog.call() # wang wang wang
cat = Cat()
cat.eat() # I can eat
cat.call() # miao miao miao
注意:在子类重写了父类的call方法,不代表父类的call方法不在了,只是在调用子类示例的call方法时,子类实例先会在自己的类中查找call方法,当在自己的类中找不到call方法时才会去父类中查找对应的call方法。
10.2.3 super方法
在子类中可以使用super方法(或者直接使用父类名()的格式)来调用父类公共属性或公共方法,语法格式如下:
语法一
super().公共属性名
super().公共方法名()
# 语法一完整格式
super(当前子类名, self).公共属性名
super(当前子类名, self).公共方法名()
# 语法二
父类名().公共属性名
父类名().公共方法名()
10.2.4 方法解析顺序
方法解析顺序(Method Resolution Order,MRO)是指在多继承或者多层继承的情况下,Python解释器查找方法的顺序,即当一个方法被调用时,Python解释器会按照怎样的顺序在当前类及其父类中查找该方法,通常是沿着继承链向上查找。
方法解析顺序可以使用类名.__mro__属性或类名.mro()方法来查看,示例如下:
class Grandparent:
pass
class Father(Grandparent):
pass
class Mother(Grandparent):
pass
class Son(Father, Mother):
pass
print(Son.__mro__)
print(Son.mro())
'''
(<class '__main__.Son'>, <class '__main__.Mother'>, <class '__main__.Father'>, <class '__main__.Grandparent'>, <class 'object'>)
[<class '__main__.Son'>, <class '__main__.Mother'>, <class '__main__.Father'>, <class '__main__.Grandparent'>, <class 'object'>]
'''
注意:在多继承的情况下,越靠左的父类的方法解析顺序越靠前。
10.3 多态
多态的本意是指一类事物有多种形态,在Python中,多态指对于同一个函数,随着传入的子类对象的不同,可以产生不同的执行结果。
多态的三要素:有继承、 有重写、父类对象的引用指向子类对象(子类对象赋值给父类对象的引用)。
多态在不改变框架代码的情况下,轻松地实现模块和模块之间的解耦合,加强了软件系统的可拓展性。
多态的示例如下:
class Fruit(object):
def makejuice(self):
print('I can make juice')
class Apple(Fruit): # 继承父类Fruit
# 重写父类makejuice方法
def makejuice(self):
print('I can make apple juice')
class Orange(Fruit): # 继承父类Fruit
# 重写父类makejuice方法
def makejuice(self):
print('I can make orange juice')
def service(fruit):
fruit.makejuice()
service(Orange()) # I can make orange juice
# 此时service函数中的参数fruit = Orange()
# Orange()作为一个匿名对象赋值给fruit,满足父类对象的引用指向子类对象
10.4 对象属性和类属性
此前我们定义在__init__()方法中的属性都是对象属性(实例属性),不同的对象通常拥有不同的对象属性,对象属性通过对象名.对象属性名来使用。
而类属性指类所拥有的属性,它也被该类的所有实例对象所共有,不同的对象通常拥有相同的类属性,类属性可以通过对象名.类属性名来使用,也可以直接通过类名.类属性名来使用(这种使用方法不需要创建类的实例对象),具体示例如下:
class Fruit(object):
count = 10
def get_cnt(self):
return self.count
print(Fruit.count) # 10
fruit = Fruit()
print(fruit.count) # 10
print(fruit.get_cnt()) # 10
在Python中,一切皆对象,类也是一个特殊的对象,因此我们可以单独为类定义属性和方法。
10.5 对象方法和类方法
此前直接在类中定义的方法都是对象方法(实例方法),对象方法可以通过对象名.对象方法名来调用。
而类方法就是针对类对象定义的方法,在面向对象编程中,强调数据封装性,所以不建议直接在类的外部对类属性进行直接获取,所以我们如果想操作类属性,建议使用类方法。
类方法的基本语法为:在类内部使用"@classmethod "修饰器来标识的对象方法即为类方法,且类方法的第一个参数应为cls而不是self,类方法可以通过对象名.类方法名来调用,也可以直接通过类名.类方法名来调用(这种调用方法不需要创建类的实例对象),具体示例如下:
class Fruit(object):
count = 10
@classmethod
def get_cnt(cls):
return cls.count
print(Fruit.get_cnt()) # 10
fruit = Fruit()
print(fruit.get_cnt()) # 10
10.6 静态方法
静态方法与类方法类似只是静态方法使用“@staticmethod”装饰器来标识,此外静态方法不需要固定第一个参数(如对象方法的self或类方法的cls),静态方法可以使用对象名.静态方法或者类名.静态方法名(此方法不需要创建类的实例对象)来调用。
通常在静态方法中既不需要访问实例属性或者调用实例方法,也不需要访问类属性或者调用类方法,具体示例如下:
class Fruit(object):
count = 10
@staticmethod
def info():
print('There is a fruit.')
Fruit.info() # There is a fruit.
fruit = Fruit()
fruit.info() # There is a fruit.

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)