python-对象
面向对象基础:
-
掌握在类与对象的概念;
-
掌握 class 关键字的使用语法;
-
掌握什么是方法,什么是属性;
-
掌握 init 方法的使用;
-
掌握 del 方法的使用;
第 1 章 面向对象基础------概念
一、面向函数的编程方式
-
把完成某⼀个需求的所有步骤从头到尾逐步实现;
-
根据开发需求,将某些功能独⽴的代码封装成⼀个⼜⼀个函数;
-
最后完成的代码,就是顺序地调⽤不同的函数。
二、⾯向对象的编程方式
相⽐较函数,⾯向对象是更⼤的封装,根据职责在⼀个对象中封装多个⽅法
-
在完成某⼀个需求前,首先确定职责 —— 要做的事情(⽅法) ;
-
根据职责确定不同的对象,在对象内部封装不同的⽅法;
-
最后完成的代码,就是顺序地让不同的对象调⽤不同的⽅法。
三、类和对象的概念
类和对象是⾯向对象编程的两个核⼼概念
1. 类
类是对⼀群具有相同特征或者⾏为的事物的⼀个统称,是抽象的,不能直接使⽤ 。
-
特征被称为属性
-
⾏为被称为⽅法
2. 对象
对象是由类创建出来的⼀个具体存在,可以直接使⽤。
由哪⼀个类创建出来的对象,就拥有在哪⼀个类中定义的:属性和方法
3. 类和对象的关系
-
类是模板,对象是根据类这个模板创建出来的,应该先有类,再有对象 ;
-
类只有⼀个,⽽对象可以有很多个 ;
-
不同的对象之间属性可能会各不相同 ;
-
类中定义了什么属性和⽅法,对象中就有什么属性和⽅法,不可能多,也不
四、类的设计
在程序开发中,要设计⼀个类,通常需要满⾜⼀下三个要素:
-
类名 :这类事物的名字 ;
-
属性 :这类事物具有什么样的特征 ; -----属性就是函数中的变量
-
⽅法 :这类事物具有什么样的⾏为。------方法就是“函数”
1. 属性和⽅法的确定
- 对于对象的特征描述,通常可以定义成属性 ,属性的具体实现可以是一个变量;
- 对象具有的⾏为(动词),通常可以定义成⽅法,方法的具体实现可以是一 个类里面的函数 ;
2.设计一个小猫类(三要素)
- 类名 cat
- 属性
- name(名字)
- color(颜色)
- height(身高)
- weight(体重)
- sex(性别)
- 方法
- eat(吃)
- drink(喝)
- sleep(睡)
第 2 章 面向对象基础------语法
一、class 关键字
- class 关键字用于创建一个类,语法如下:
class 类名:
def ⽅法 1(self, 参数列表):
pass
1.方法和函数的区别
- 方法括号里面即使没有参数,也要写上"self",别的和函数一样
- ⽅法的定义格式和之前学习过的函数⼏乎⼀样 ;
- 区别在于第⼀个参数必须是 self ,⼤家暂时先记住,稍后介绍 self 。
二、类的代码实现
class cat:
def eat(self):
print("汤姆爱吃鱼")
def drink(self):
print("汤姆爱喝水")
三、 创建一个对象
-
名词解释
- 实例------通过类创建出来的对象叫做类的实例
- 实例化------创建对象的动作叫做实例化
-
创建对象语法:
- 对象名 = 类名(参数列表)
类是静态的,只有创建为对象后,才能成为动态运行的程序。
class cat: #定义了一个类,这个类不能直接使用
def eat(self):
print("汤姆爱吃鱼")
def drink(self):
print("汤姆爱喝水")
c1=cat() #根据类cat 创建了一个对象c1,对象名类似于变量名
c1.eat() #调用的时候,不需要提供self对应的实参
c1.drink() #调用对象的方法
#c1就是类的实例
#c1=cat() 这个动作就叫实例化
四、⽅法中的self 参数
- 在类封装的⽅法内部, self 就表示调用方法的对象自己
- 调⽤⽅法时,不需要传递 self 参数、
- 在方法内部可以通过 self. 访问对象的属性
- 通过在方法内部使用 self.属性名 = 值,为类添加属性
- 在方法内部可以通过 self. 调⽤对象的⽅法
- 在类的外部,通过 对象名. 访问对象的属性和⽅法
cat 类添加 name 属性,同时创建两个对象
# 定义 cat 类
class cat:
def set_name(self):
# 给 cat 类添加一个属性 name 值是tom
self.name = "tom"
def eat(self):
print("{}爱吃鱼" .format(self.name))
def drink(self):
print("{}爱喝水" .format(self.name))
c=cat()
c.set_name()
c.drink()
c.eat()
c.name="张三"
c.drink()
c.eat()
tom爱喝水
tom爱吃鱼
张三爱喝水
张三爱吃鱼
Process finished with exit code 0
# 定义 cat 类
class cat:
def set_name(self,name1):
# 给 cat 类添加一个属性 name
self.name = name1
def eat(self):
print("{}爱吃鱼" .format(self.name))
def drink(self):
print("{}爱喝水" .format(self.name))
c=cat()
c.set_name("张三")
c.drink()
c.eat()
张三爱喝水
张三爱吃鱼
Process finished with exit code 0
1. 课堂练习---
定义一个小狗类 dog
-
创建小狗类的对象,设置对象的 name 为”旺财”;
-
调用 show_name 显示对象的 name。
# 定义 dog类
class dog:
def set_name(self, name1):
self.name=name1
def show_name(self):
print("属性的值:{}".format(self.name))
c=dog()
c.set_name("tom")
c.show_name()
属性的值:tom
Process finished with exit code 0
解析:
第 3 章 面向对象基础------ init 方法
一、init 初始化方法
__init__就是对象的初始化⽅法, __init__ 是对象的内置⽅法
当使⽤ 类名() 创建对象时,会自动执⾏以下操作:
- 为对象在内存中分配空间 —— 创建对象 ;
- 系统自动调用⽅法(__ init__ )
二、cat类增加__init__方法
-
在初始化方法内部为类添加属性
class cat: def __init__(self): self.name = "猫" print("%s 的初始化方法" % self.name) def eat(self): print("%s 爱吃鱼" % self.name) def drink(self): print("%s 爱喝水" % self.name) # 创建对象的同时,初始化方法被自动调用 lazy_cat = cat() 猫 的初始化方法 Process finished with exit code 0
-
带有参数的初始化方法
class cat: def __init__(self,name): self.name = name print("%s 的初始化方法" % self.name) def eat(self): print("%s 爱吃鱼" % self.name) def drink(self): print("%s 爱喝水" % self.name) # 创建对象的同时,初始化方法被自动调用 lazy_cat = cat("tom") tom 的初始化方法 Process finished with exit code 0
-
初始化方法的缺省参数
class cat: def __init__(self,name = "猫"): self.name = name print("%s 的初始化方法" % self.name) def eat(self): print("%s 爱吃鱼" % self.name) def drink(self): print("%s 爱喝水" % self.name) # 创建对象的同时,初始化方法被自动调用 lazy_cat = cat()
解析:
1.init方法的作用:
- 定义类中的属性
- 同时通过init方法的参数为属性赋值
- init方法一旦有形参,对象实例化的时候就必须提供参数
- 为了避免实例化的时候必须提个参数,init的形参总是有缺省值
2. 课堂练习---car类设计
#定义car类
#属性:
#luotai(轮胎)、yanse(颜色) 、chuanghu(窗户)、xinghao(型号)
#方法:
#guadang(挂挡) 、qianjin(前进)、houtui(后退)、wurenjiashi(无人驾驶)、shache(刹车)、jiayou(加油)
class car:
def __init__(self,luntai="轮胎",yanse="白色",chuanghu="窗户",xinghao="大众"):
self.luntai=luntai
self.yanse=yanse
self.chuanghu=chuanghu
self.xinghao=xinghao
def guadang(self,a="前进"):
self.jiayou()
if a == "前进":
self.qianjin()
elif a == "后退":
self.houtui()
else:
print("挡不对")
def qianjin(self):
print("{}在前进".format(self.xinghao))
def houtui(self):
print("{}的{}在后退".format(self.yanse,self.xinghao))
def wurenjiashi(self):
print("无人驾驶")
def shache(self):
print("刹车")
def jiayou(self):
print("加油")
c=car()
c.guadang("前进")
c.guadang("后退")
c.guadang("我")
加油
大众在前进
加油
白色的大众在后退
加油
挡不对
Process finished with exit code 0
第 4 章 面向对象基础------__del__方法
一、__del__方法说明
- __del__方式只能有一个参数 self;
- 当对象在内存中被销毁的时候,__del__方法被系统自动调用
- 当使⽤ 类名() 创建对象时,为对象分配完空间后,⾃动调⽤ init ⽅法
- 当⼀个对象被从内存中销毁前,会⾃动调⽤ del ⽅法
- ⼀个对象的 del ⽅法⼀旦被调⽤,对象的生命周期结束
class cat():
def __init__(self,name="tom"):
self.name=name
def show_name(self):
print(self.name)
def __del__(self):
print("{}销毁了".format(self.name))
c=cat()
c.show_name()
tom
tom销毁了
Process finished with exit code 0
- 在函数内定义的变量,函数执行完毕,变量就被销毁了;
- 在函数外部定义的变量,程序执行完毕,变量就被销毁了
- 可以通过 del 关键字,显式的销毁一个变量
第 5 章 面向对象基础------str 方法
- 在 Python 中,使⽤ print 输出 对象变量,默认情况下,会输出这个变量 引⽤的对象是由哪⼀个类创建的对象,以及在内存中的地址(⼗六进制表示)
如果在开发中,希望使⽤ print 输出对象变量时,能够打印⾃定义的内容, 就可以利⽤ str 这个内置⽅法了
- 直接把对象放到print里面显示
- 当把对象直接放到print里面,显示的是对象的内存的地址编号
class cat:
def __init__(self,name = "猫"):
self.name = name
print("%s 的带有参数的初始化方法" % self.name)
def eat(self):
print("%s 爱吃鱼" % self.name)
c=cat()
print(c)
猫 的带有参数的初始化方法
<__main__.cat object at 0x00000295A8507BE0>
Process finished with exit code 0
- 如果在开发中,希望使⽤ print 输出对象变量时,能够打印⾃定义的内容, 就可以利⽤ str 这个内置⽅法了
注意:str ⽅法必须返回⼀个字符串
class cat:
def __init__(self,name = "猫"):
self.name = name
#print("%s 的带有参数的初始化方法" % self.name)
def __str__(self):
return self.name
def eat(self):
print("%s 爱吃鱼" % self.name)
c=cat()
# 这个时候 print 将显示__str__函数返回的字符串
print(c)
猫
Process finished with exit code 0
第 6 章 面向对象基础------类设计练习
1. 课堂练习---
- 设计一个类 calc,实现计算器
功能属性与方法说明如下:
class calc:
def __init__(self,oper="+"):
self.oper=oper
def calc_test(self,a,b):
if self.oper == "+":
return a+b
if self.oper == "-":
return a-b
if self.oper == "*":
return a*b
if self.oper == "/":
if b != 0:
return a/b
else:
return None
else:
return None
a=calc()
print(a.calc_test(3,4))
b=calc("-")
print(b.calc_test(3,4))
c=calc("*")
print(c.calc_test(3,4))
d=calc("/")
print(d.calc_test(3,4))
7
-1
12
0.75
Process finished with exit code 0
拓展--对象调用(重点)
1、调用其他脚本中的全局变量
- 语法
脚本名.全局变量名 ----q.id
#被调用脚本q
id=10
#脚本q2调用脚本q中定义的变量ID
import q
a=q.id
print("调用其他脚本中的全局变量:id={}".format(a))
调用其他脚本中的全局变量:id=10
Process finished with exit code 0
2、调用其他脚本中的函数
- 语法
脚本名.函数名() -----q.test_id()
#被调用脚本q
def test_id():
id=11
print("调用其他脚本中的函数:id={}".format(id))
#脚本q2调用脚本q中定义的test_id函数
import q
b=q.test_id()
调用其他脚本中的函数:id=11
Process finished with exit code 0
3、调用其他脚本中的类方法
- 语法
实例化对象:对象=文件名.类名()
对象.方法名()
c=q.test_id_2()
c.test_id_2_1()
#被调用脚本q
class test_id_2():
name="mike111"
def test_id_2_1(self):
self.id=12
print("调用其他脚本中的类方法:id={}".format(self.id))
#脚本q2调用脚本q中定义的 test_id_2_1 方法
import q
c=q.test_id_2()
c.test_id_2_1()
调用其他脚本中的类方法:id=12
Process finished with exit code 0
4、给类中的局部变量重新赋值后在调用(这个叫类属性)
- 语法
#赋值语句
类名.局部变量名=新的变量------test_id_2.name=self.id
#调用
实例化对象:对象=文件名.类名()
对象.局部变量名
d=q.test_id_2()
d.name
#被调用脚本q
class test_id_2():
name=None
def test_id_2_1(self):
self.id=12
print("调用其他脚本中的类方法:id={}".format(self.id))
#赋值语句
test_id_2.name=self.id
#脚本q2调用脚本q中定义的 局部变量name
d=q.test_id_2()
e=d.name
print("给类中的局部变量重新赋值后在调用:name={}".format(e))
给类中的局部变量重新赋值后在调用:name=12
Process finished with exit code 0
脚本文件
id=10
def test_id():
id=11
print("调用其他脚本中的函数:id={}".format(id))
name="mike"
class test_id_2():
name=None
def test_id_2_1(self):
self.id=12
print("调用其他脚本中的类方法:id={}".format(self.id))
test_id_2.name=self.id
import q
a=q.id
print("调用其他脚本中的全局变量:id={}".format(a))
b=q.test_id()
c=q.test_id_2()
c.test_id_2_1()
d=q.test_id_2()
e=d.name
print("给类中的局部变量重新赋值后在调用:name={}".format(e))
面向对象三大特点:
-
了解面向对象三大特点的概念;
-
掌握继承语法;
-
掌握方法重写;
-
掌握类属性和类方法的使用;
第 1 章 面向对象进阶------三大特点
一、面向对象程序设计三大特性:
-
封装------根据职责将属性和⽅法封装到⼀个抽象的类中 ;
-
继承------实现代码的重⽤,相同的代码不需要重复的编写 ;
-
多态------不同的对象调⽤相同的⽅法,产⽣不同的执⾏结果,增加代码的灵活度 。
第 2 章 面向对象进阶------封装
一、类的私有属性和私有⽅法
- 对于私有属性和私有方法,只能在类的内部访问,类的外部无法访问
- 在定义属性或⽅法时,在属性名或者⽅法名前 增加两个下划线,定义的就是私有属性或方法
私有属性:
#定义私有类和私有方法----将体重weight设置私有属性
class woman:
def __init__(self):
self.name="玛丽"
self.__weight=200 #体重weight设置私有属性
w=woman()
print(w.name)
print(w.__weight) #调用报错,不能在类的外部访问类的私有属性
玛丽
Traceback (most recent call last):
File "D:\PycharmProjects\111\222\001.py", line 10, in <module>
print(w.__weight) #调用报错,不能在类的外部访问类的私有属性
AttributeError: 'woman' object has no attribute '__weight'
Process finished with exit code 1
私有方法:
#定义私有类和私有方法
class woman:
def __init__(self):
self.name="玛丽"
self.__weight=200 #体重weight设置私有属性
def __eat(self): #eat 方法为私有方法
print("吃的很多")
w=woman()
print(w.name)
w.__eat #调用报错,不能在类的外部访问私有方法
玛丽
Traceback (most recent call last):
File "D:\PycharmProjects\111\222\001.py", line 13, in <module>
w.__eat #调用报错,不能在类的外部访问私有方法
AttributeError: 'woman' object has no attribute '__eat'
Process finished with exit code 1
第 3 章 面向对象进阶------继承
一、继承的概念
- ⼦类拥有⽗类的所有⽅法和属性
二、继承的语法
- ⼦类继承⾃⽗类,可以直接享受⽗类中已经封装好的⽅法,不需要再次开发,⼦类再根据职责,封装⼦类特有的属性和⽅法。
class 类名(⽗类名):
pass
示例:
class animal:
def sleep(self):
print("睡")
def eat(self):
print("吃")
class dag(animal): #类dog继承自animal类
def run(self):
print("跑")
object=dag()
object.eat() #继承了父类中eat方法
object.sleep() #继承了父类中sleep方法
object.run() #子类自己的frun方法
三、专业术语
- dog 类是 animal 类的⼦类; animal 类是 dog 类的⽗类; dog 类从 animal 类 继承
另一种说法:
- dog 类是 animal 类的派⽣类; animal 类是 dog 类的基类 ; dog 类从 animal 类派生
四、继承的传递性(多级继承)
C 类从 B 类继承, B 类⼜从 A 类继承
- 那么 C 类就具有 B 类和 A 类的所有属性和⽅法
- ⼦类拥有⽗类以及⽗类的⽗类 中封装的所有属性和⽅法
多级继承:
class animal:
def sleep(self):
print("睡")
class dog(animal): #类dog继承自animal类
def run(self):
print("跑")
class erha(dog): #类erha继续自dog类
def kawayi(self):
print("萌萌嘀")
object=erha()
object.sleep()
object.run()
object.kawayi()
五、⽅法的重写
当⽗类的⽅法实现不能满⾜⼦类需求时,可以对⽅法进⾏ 重写(override)
-
重写⽗类⽅法有两种情况:
1、覆盖⽗类的⽅法
2、对⽗类⽅法进⾏扩展
1. 覆盖⽗类的⽅法(重载)
如果在开发中,⽗类的⽅法实现和⼦类的⽅法实现,完全不同 ,就可以使 ⽤覆盖的⽅式,在⼦类中重新编写⽗类的⽅法实现
- 具体的实现⽅式,就相当于在⼦类中定义了⼀个 和⽗类同名的⽅法并且实现
- 重写之后,在运⾏时,只会调⽤⼦类中重写的⽅法,⽽不再会调⽤父类封装的方法。
示例:
class animal:
def sleep(self):
print("睡")
def eat(self):
print("吃")
class dog(animal): #类dog继承自animal类
def run(self):
print("跑")
# 覆盖了父类的同名方法,在dog子类中,就没有父类eat方法了,覆盖了
def eat(self):
print("吃肉")
object=dog()
object.eat() #此时eat方法被覆盖重写了,打印的是"吃肉",不是"吃"
吃肉
Process finished with exit code 0
2. 对⽗类⽅法进⾏扩展
如果在开发中,既要使用父类的方法,又想增加功能, 就可以使⽤扩展的 ⽅式
- 在⼦类中重写⽗类的⽅法
- 在需要的位置使⽤ super().⽗类 ⽅法来调⽤⽗类⽅法的执⾏
- 代码其他的位置针对⼦类的需求,编写⼦类特有的代码实现
示例:
class animal:
def sleep(self):
print("睡")
def eat(self):
print("吃")
class dog(animal): #类dog继承自animal类
def run(self):
print("跑")
def eat(self):
print("吃肉")
# 对父类的 sleep 方法进行了扩展
def sleep(self):
super().sleep()
print("睡的更多")
object=dog()
object.sleep() #此时父类的sleep方法被扩展了,子类调用sleep方法,打印两个---"睡" "睡的更多"
六、⽗类的私有属性和私有⽅法
- ⼦类对象不能在⾃⼰的⽅法内部,直接访问⽗类的私有属性或私有⽅法
- ⼦类对象 可以通过⽗类的公有⽅法间接访问到私有属性或私有⽅法
私有属性、⽅法是对象的隐私,不对外公开,外界以及⼦类都不能直接访问 私有属性、⽅法通常⽤于做⼀些内部的事情
class animal:
def sleep(self):
print("睡")
def __eat(self): #父类eat方法设置私有方法
print("吃")
class dog(animal): #类dog继承自animal类
def run(self):
print("跑")
object=dog()
object.__eat() #在子类dog类里面,没有__eat方法 执行报错
1.课堂练习
-
实现父亲类 father
-
实现儿子类 son,继承自 father 类
class father:
def __init__(self):
self.__name = "张三" #姓名:私有属性,不能继承
self.house = "别墅"
def eat(self):
print("吃")
def sleep(self):
print("睡")
def __edu_back(self): #学历:私有方法 不可以继承的方法
print("本科")
class son(father):
def show_eat(self): #调用 father 类的 eat 方法
self.eat()
def show_sleep(self): #调用 father 类的 sleep 方法
self.sleep()
def show_house(self): #显示 father 类的 house 属性
print(self.house) #huuse是一个属性,不能self.house调用,要用print显示
object=son()
object.show_eat()
object.show_sleep()
object.show_house()
吃
睡
别墅
Process finished with exit code 0
第 4 章 面向对象进阶------多态
多态的前提:不同的子类是来自相同的一个父类,子类会覆盖父类的方法
- 多态:对于不同的类可以有同名的方法,同名的方法应用到不同的类可以有不同行为。
或者说:
- 不同的⼦类对象调⽤相同的⽗类⽅法,产⽣不同的执⾏结果
class animal:
def food(self):
pass
def eat(self):
self.food()
class dog(animal):
def food(self):
print("肉")
class cattle(animal):
def food(self):
print("草")
d = dog()
# 调用父类的 eat 方法
d.eat()
c = cattle()
# 调用父类的 eat 方法
c.eat()
肉
草
Process finished with exit code 0
面向对象进阶:
第 5 章 面向对象进阶------类属性和类⽅法
- 不需要创建类的对象,通过 类名. 的⽅式就可以访问类的属性或者调用类的方法 。
一、类属性
- 定义在类的里面,方法的外面,
- 可以赋值
- 定义的时候不需要关键字self,语法类似于普通变量
class dog:
name="二哈"
def __init__(self):
pass
print(dog.name)
dog.name="狼狗"
print(dog.name)
二哈
狼狗
Process finished with exit code 0
二、类方法
- 用@classmethod 修饰的方法为类方法;
- 类方法的参数为 cls (不是self),在类方法内部通过 cls.类属性 或者 cls.类方法 来访问同一个类中的其他类属性和类方法
- 类方法不需要实例化就可以调用,类方法只能访问同一个类中的类属性和类方法。
class dog:
name="二哈"
@classmethod
def set_name(cls,name):
cls.name=name #通过类方法的形参修改 类属性name的值
def __init__(self):
self.age=20 #在类方法里无法访问age
dog.set_name("老虎")
print(dog.name)
老虎
Process finished with exit code 0
三、普通方法访问类属性或类方法
普通方法可以访问类方法/类属性,类方法不能访问普通方法,因为访问普通方法需要对象
- 在普通方法中通过 类名.类属性 或者 类名.类方法 来访问类属性和类方法。
class dog:
# name 为类属性
name="二哈"
# get_name 为类方法
@classmethod
def get_name(cls):
return cls.name
# demo 为普通方法
def demo(self): #演示如何在普通方法中来使用类属性和类方法
dog.name="大狗"
print(dog.get_name())
d=dog()
d.demo()
大狗
Process finished with exit code 0
第 6 章 面向对象进阶------静态⽅法
和函数有点像,只是把这个函数放在一个类里面了
- 在类中用@staticmethod 修饰的方法为静态方法
- 静态方法不需要实例化对象,通过 类名。静态方法名 调用
- 静态方法不能访问类中的其他成员,静态方法就是一个独立于类存在的函数
#静态方法
class dog:
@staticmethod
def help():
print("这是一个静态方法")
dog.help()
这是一个静态方法
Process finished with exit code 0
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律