9.python面向对象
⾯向对象基础
- 类和对象
- 添加和获取对象属性
- 魔法⽅法
类和对象
在⾯向对象编程过程中,有两个重要组成部分:类 和 对象。
- 类和对象的关系:⽤类去创建⼀个对象。
理解类和对象
类
类是对⼀系列具有相同特征和⾏为的事物的统称,是⼀个抽象的概念,不是真实存在的事物
- 特征即是属性
- ⾏为即是⽅法
类好比是制造手机时要⽤到的图纸,也就是说类是⽤来创建对象的
对象
对象是类创建出来的真实存在的事物,例如:手机。
注意:开发中,先有类,再有对象。
⾯向对象实现⽅法
语法
class 类名():
代码
pass
注意:类名要满⾜标识符命名规则,同时遵循驼峰命名习惯(下划线可有可无)
快速体验
class My_Project():
print("我是第一个类")
My_Project()
创建对象
语法
# 变量名 = 类名()
快速体验
class My_Phone():
def call_tel(self):
print("正在打电话")
def play_game(self):
print("正在打游戏")
# 创建对象
apple = My_Phone()
print(apple)
# 调用对象的实例方法
apple.play_game()
创建对象的过程也叫实例化对象
self
self代表类的实例
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
添加和获取对象属性
属性即是特征,⽐如:手机的颜色,大小,重量...
对象属性既可以在类外⾯添加和获取,也能在类⾥⾯添加和获取。
类外⾯添加对象属性
语法
对象名.属性名 = 值
快速体验
# -*- coding:utf-8 -*-
class My_Phone():
def main(self):
pass
apple = My_Phone()
apple.width = 10
apple.heigth = 15
print(apple.width)
print(apple.heigth)
类里面获取对象属性
语法
self.属性名
快速体验
class My_Phone():
def main(self):
print(self.width)
print(self.heigth)
apple = My_Phone()
apple.width = 10
apple.heigth = 15
apple.main()
魔术方法
在Python中,__ xx__() 的函数叫做魔法⽅法,指的是具有特殊功能的函数。
init()
init() :初始化对象
class My_Phone():
def __init__(self):
self.width = 10
self.heigth = 15
def main(self):
print(self.width)
print(self.heigth)
apple = My_Phone()
init() ⽅法,在创建⼀个对象时默认被调⽤,不需要⼿动调⽤
init(self) 中的self参数,不需要开发者传递,python解释器会⾃动把当前的对象引⽤传递过去。
- 带参数的init
class My_Phone():
def __init__(self,width,heigth):
self.width = width
self.heigth = heigth
def apple_phone(self):
print("苹果手机的宽为:",self.width)
print("苹果手机的高为:",self.heigth)
def huawei_phone(self):
print("华为手机的宽为:",self.width)
print("华为手机的高为:",self.heigth)
apple = My_Phone(10,20)
apple.apple_phone()
str()
当使⽤print输出对象的时候,默认打印对象的内存地址。如果类定义了 str ⽅法,那么就会打印从在这个⽅法中 return 的数据。
解释类的属性或作用
# -*- coding:utf-8 -*-
class Demo():
def __init__(self, width, heigth):
self.width = width
self.heigth = heigth
def __str__(self):
return f"手机的宽是{self.width},高度是{self.heigth}"
a = Demo(10,20)
print(a)
del()
当删除对象时,python解释器也会默认调⽤ del() ⽅法。在对象销毁的时候被调用,当对象不再被使用时,del()方法运行:
# -*- coding:utf-8 -*-
class Demo():
def __init__(self, width, heigth):
self.width = width
self.heigth = heigth
def __del__(self):
print("对象已经删除")
a = Demo(10,20)
类属性与方法
类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问
class Demo():
__num = 0 # 私有属性
result = 0 # 公开属性
def count(self):
self.__num += 1
self.result += 1
print(self.__num)
run = Demo()
run.count()
run.count()
print(run.result)
print(run.__num) # 报错,实例不能访问私有变量
面向对象的特性
- 继承的概念
- 单继承
- 多继承
- ⼦类重写⽗类的同名属性和⽅法
- ⼦类调⽤⽗类的同名属性和⽅法
- 多层继承
- super()
- 私有属性和私有⽅法
继承
Python⾯向对象的继承指的是多个类之间的所属关系,即⼦类默认继承⽗类的所有属性和⽅法,具体如下
class A(object):
def __init__(self):
self.num = 1
def demo(self):
print(self.num)
class B(A):
pass
result = B()
result.demo()
在Python中,所有类默认继承object类,object类是顶级类或基类;其他⼦类叫做派⽣类。
单继承
枯荣大师只有一个弟子叫张三,他马上要与世长辞,现在,他想把自己的功夫传授给自己唯一的关门弟子
代码实现
# -*- coding:utf-8 -*-
class Master(object):
def __init__(self):
self.kunfu = "一阳指,狮吼功,六脉神剑"
def demo(self):
print(f"枯荣大师的功夫:{self.kunfu}")
class Apprentice(Master):
pass
func = Apprentice()
print(func.kunfu)
func.demo()
多继承
张三不满足枯荣大师的功夫,现在他又拜在了张三丰的门下,想学太极
# -*- coding:utf-8 -*-
class Kurong_Master(object):
def __init__(self):
self.kunfu_kurong = "一阳指,狮吼功,六脉神剑"
def demo_kurong(self):
print(f"枯荣大师的功夫:{self.kunfu}")
class Sanfeng_Master(object):
def __init__(self):
self.kunfu_sanfeng = "太极"
def demo_sanfeng(self):
print(f"张三丰的功夫:{self.kunfu}")
class Apprentice(Kurong_Master,Sanfeng_Master):
def __init__(self):
Kurong_Master.__init__(self)
Sanfeng_Master.__init__(self)
func = Apprentice()
print(func.kunfu_kurong)
print(func.kunfu_sanfeng)
所谓多继承意思就是⼀个类同时继承了多个⽗类。
⼦类重写⽗类⽅法和属性
张三觉得师傅的功夫都有一定的不足,决定改善师傅的功夫
# -*- coding:utf-8 -*-
class Kurong_Master(object):
def __init__(self):
self.kunfu_kurong = "六脉神剑"
def demo_kurong(self):
print(f"枯荣大师的功夫:{self.kunfu}")
class Sanfeng_Master(object):
def __init__(self):
self.kunfu_sanfeng = "太极"
def demo_sanfeng(self):
print(f"张三丰的功夫:{self.kunfu}")
class Apprentice(Kurong_Master,Sanfeng_Master):
def __init__(self):
Kurong_Master.__init__(self)
Sanfeng_Master.__init__(self)
self.kunfu_kurong = "万剑归宗"
self.kunfu_sanfeng = "醉拳"
def demo_zhangsan(self):
print(f"张三自己研制的功夫{self.kunfu_kurong}---{self.kunfu_sanfeng}")
func = Apprentice()
func.demo_zhangsan()
⼦类调⽤⽗类的⽅法和属性
张三在两位师傅功夫的基础上创建了新的功夫,但是他想在使用自己功夫的时候也可以用到师傅的功夫
同名的情况下,只能使用子类里面的方法
# -*- coding:utf-8 -*-
class Kurong_Master(object):
def __init__(self):
self.kunfu_kurong = "六脉神剑"
def demo_kurong(self):
print(f"枯荣大师的功夫:{self.kunfu_kurong}")
class Sanfeng_Master(object):
def __init__(self):
self.kunfu_sanfeng = "太极"
def demo_sanfeng(self):
print(f"张三丰的功夫:{self.kunfu_sanfeng}")
class Apprentice(Kurong_Master,Sanfeng_Master):
def __init__(self):
self.kunfu_kurong = "万剑归宗"
self.kunfu_sanfeng = "醉拳"
def demo_zhangsan(self):
print(f"张三自己研制的功夫{self.kunfu_kurong}---{self.kunfu_sanfeng}")
def demo_zhangsan_kurong(self):
Kurong_Master.__init__(self)
Kurong_Master.demo_kurong(self)
def demo_zhangsan_sanfeng(self):
Sanfeng_Master.__init__(self)
Sanfeng_Master.demo_sanfeng(self)
func = Apprentice()
func.demo_zhangsan()
func.demo_zhangsan_kurong()
func.demo_zhangsan_sanfeng()
多层继承
多年之后,张三老了,想把自己的毕生所学,传给李四
# -*- coding:utf-8 -*-
class Kurong_Master(object):
def __init__(self):
self.kunfu_kurong = "六脉神剑"
def demo_kurong(self):
print(f"枯荣大师的功夫:{self.kunfu_kurong}")
class Sanfeng_Master(object):
def __init__(self):
self.kunfu_sanfeng = "太极"
def demo_sanfeng(self):
print(f"张三丰的功夫:{self.kunfu_sanfeng}")
class Apprentice(Kurong_Master,Sanfeng_Master):
def __init__(self):
self.kunfu_kurong = "万剑归宗"
self.kunfu_sanfeng = "醉拳"
def demo_zhangsan(self):
print(f"张三自己研制的功夫{self.kunfu_kurong}---{self.kunfu_sanfeng}")
def demo_zhangsan_kurong(self):
Kurong_Master.__init__(self)
Kurong_Master.demo_kurong(self)
def demo_zhangsan_sanfeng(self):
Sanfeng_Master.__init__(self)
Sanfeng_Master.demo_sanfeng(self)
class Disciple(Apprentice):
pass
func = Disciple()
func.demo_zhangsan_sanfeng()
func.demo_zhangsan_kurong()
func.demo_zhangsan()
super()
调用父类方法
# -*- coding:utf-8 -*-
class Kurong_Master(object):
def __init__(self):
self.kunfu_kurong = "六脉神剑"
def demo_kurong(self):
print(f"枯荣大师的功夫:{self.kunfu_kurong}")
class Sanfeng_Master(object):
def __init__(self):
self.kunfu_sanfeng = "太极"
def demo_sanfeng(self):
print(f"张三丰的功夫:{self.kunfu_sanfeng}")
class Apprentice(Kurong_Master,Sanfeng_Master):
def __init__(self):
self.kunfu_kurong = "万剑归宗"
self.kunfu_sanfeng = "醉拳"
def demo_zhangsan(self):
print(f"张三自己研制的功夫{self.kunfu_kurong}---{self.kunfu_sanfeng}")
def demo_sanfeng_kurong(self):
# 写法一
# Kurong_Master.__init__(self)
# Kurong_Master.demo_kurong(self)
# Sanfeng_Master.__init__(self)
# Sanfeng_Master.demo_sanfeng(self)
# ⽅法2 super().函数()
# super().__init__()
# super().demo_kurong()
super().demo_sanfeng()
func = Apprentice()
func.demo_sanfeng_kurong()
私有权限
定义私有属性和方法
在Python中,可以为实例属性和⽅法设置私有权限,即设置某个实例属性或实例⽅法不继承给⼦类。
枯荣大师还有一招狮吼功,不想传授给他的徒弟,这个时候,可以吧狮吼功这个属性设置为私有
设置私有权限的⽅法:在属性名和⽅法名 前⾯ 加上两个下划线 __。
# -*- coding:utf-8 -*-
class Kurong_Master(object):
def __init__(self):
self.kunfu_kurong = "六脉神剑"
self.__kurong = "狮吼功"
def demo_kurong(self):
print(f"枯荣大师的功夫:{self.kunfu_kurong}")
def __demo_kurong(self):
print(f"枯荣大师的功夫:{self.__kurong}")
class Sanfeng_Master(object):
def __init__(self):
self.kunfu_sanfeng = "太极"
def demo_sanfeng(self):
print(f"张三丰的功夫:{self.kunfu_sanfeng}")
class Apprentice(Kurong_Master,Sanfeng_Master):
def __init__(self):
self.kunfu_kurong = "万剑归宗"
self.kunfu_sanfeng = "醉拳"
def demo_zhangsan(self):
print(f"张三自己研制的功夫{self.kunfu_kurong}---{self.kunfu_sanfeng}")
# def demo_sanfeng_kurong(self):
# Kurong_Master.__init__(self)
# Kurong_Master.demo_kurong(self)
# Sanfeng_Master.__init__(self)
# Sanfeng_Master.demo_sanfeng(self)
func = Apprentice()
func.__demo_kurong() # 报错
私有属性和私有⽅法只能在类⾥⾯访问和修改。
获取和修改私有属性值
在Python中,⼀般定义函数名 get_xx ⽤来获取私有属性,定义 set_xx ⽤来修改私有属性值。
# -*- coding:utf-8 -*-
class Kurong_Master(object):
def __init__(self):
self.kunfu_kurong = "六脉神剑"
self.__kurong = "狮吼功"
def demo_kurong(self):
print(f"枯荣大师的功夫:{self.kunfu_kurong}")
def get_demo(self):
return self.__kurong
def set_demo(self):
self.__kurong = "一阳指"
class Sanfeng_Master(object):
def __init__(self):
self.kunfu_sanfeng = "太极"
def demo_sanfeng(self):
print(f"张三丰的功夫:{self.kunfu_sanfeng}")
class Apprentice(Kurong_Master, Sanfeng_Master):
def __init__(self):
self.kunfu_kurong = "万剑归宗"
self.kunfu_sanfeng = "醉拳"
def demo_zhangsan(self):
print(f"张三自己研制的功夫{self.kunfu_kurong}---{self.kunfu_sanfeng}")
func = Kurong_Master()
print(func.get_demo())
func.set_demo()
print(func.get_demo())
面向对象的三大特征
-
封装
将属性和⽅法书写到类的⾥⾯的操作即为封装
封装可以为属性和⽅法添加私有权限 -
继承
⼦类默认继承⽗类的所有属性和⽅法
⼦类可以重写⽗类属性和⽅法 -
多态
传⼊不同的对象,产⽣不同的结果
多态
多态指的是⼀类事物有多种形态
定义:多态是⼀种使⽤对象的⽅式,⼦类重写⽗类⽅法,调⽤不同⼦类对象的相同⽗类⽅法,可以产⽣不同的执⾏结果
-
好处:调⽤灵活,有了多态,更容易编写出通⽤的代码,做出通⽤的编程,以适应需求的不断变化!
-
实现步骤:
定义⽗类,并提供公共⽅法
定义⼦类,并重写⽗类⽅法
传递⼦类对象给调⽤者,可以看到不同⼦类执⾏效果不同
代码实现
# -*- coding:utf-8 -*-
class Father(object):
def func(self):
print("下达命令:出兵剿匪")
class Son1(Father):
def func(self):
print("正面迎击")
class Son2(Father):
def func(self):
print("背后突袭")
class Main(object):
def func_demo(self,demo):
demo.func()
demo1 = Son1()
demo2 = Son2()
func = Main()
func.func_demo(demo1)
func.func_demo(demo2)
类属性和实例属性
类属性就是 类 所拥有的属性,它被 该类的所有实例对象 所共有。
类属性可以使⽤ 类对象 或 实例对象 访问
# -*- coding:utf-8 -*-
class Demo(object):
num = 10
def __init__(self):
self.number = 10
func = Demo()
print(Demo.num)
print(func.num)
修改类属性
类属性只能通过类对象修改,不能通过实例对象修改,如果通过实例对象修改类属性,表示的是创建了⼀个实例属性。
# -*- coding:utf-8 -*-
class Demo(object):
num = 10
func = Demo()
func1 = Demo()
Demo.num = 20
print(Demo.num)
print(func.num)
# 不能通过对象修改属性,如果这样操作,实则是创建了⼀个实例属性
func.num = 30
print(Demo.num)
print(func.num)
print(func1.num)
类方法和静态方法
了解即可
需要⽤装饰器 @classmethod 来标识其为类⽅法,对于类⽅法,第⼀个参数必须是类对象,⼀般以cls 作为第⼀个参数。
# -*- coding:utf-8 -*-
class Demo(object):
__num = 10
@classmethod
def get_num(cls):
return cls.__num
func = Demo()
print(func.get_num())
静态方法
当⽅法中 既不需要使⽤实例对象(如实例对象,实例属性),也不需要使⽤类对象 (如类属性、类⽅法、创建实例等)时,定义静态⽅法
取消不需要的参数传递,有利于 减少不必要的内存占⽤和性能消耗
class Demo(object):
@staticmethod
def get_info():
print("我是一个静态方法")
func = Demo()
func.get_info()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~