0%

面向对象初级

python的第八节课笔记(基础高级)

面向对象介绍

借鉴函数的封装思维,再次对函数和变量进行封装,来提高代码的复用性,通过这样的封装,把和人相关的变量、函数等放在了一起,只要找到这个部分代码,就能知道关于人已经定义了哪些变量和函数,为了便于区分,把用关键字 class 定义的代码块称为 类

注意:

  • 在类里面的变量称为类的属性,一般是名词性的东西
  • 在类里面的函数称为类的方法,一般是动词性的东西
  • 本质就是使用面向对象进行封装—封装成一个类
  • 类定义的关键字: class
1
2
3
4
5
类的组成:  
类名 类的名称
属性 一般我们会使用初始化函数来进行定义,用于描述事物的特征

方法 就是放到类里面的函数而已,用于描述事物的行为

语法:

1
2
class 类名:
pass
1
2
3
需求:
定义一个15期班级的晓军同学
定义一个15期班级的龙飞同学

类和对象

没学面向对象之前,我们只能使用变量和函数来表示,很不方便

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#晓军同学的特性
name = "晓军"
age = 28
sex = "男"

def study():
print("热爱学习")

def play():
print("喜欢打游戏")


name = "龙飞"
age = 29
sex = "男"


def study():
print("热爱学习")


def play():
print("喜欢打游戏")

print(type(name))
print(type(age))

学完后,可以将这些信息封装成一个类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class cls15:
name = "龙飞"
age = 29
sex = "男"

def study(name):
print(f"{name}热爱学习")

def play(name):
print(f"{name}喜欢打游戏")


# 调用类的属性 类名/类的对象.属性名
print(cls15.name)
print(cls15.age)
print(cls15.sex)
# 调用类的方法 类名/类的对象.方法
cls15.play(cls15.name)
cls15.study(cls15.name)

创建实例对象

1
2
3
4
面向对象的组成:
类: 只是一个概念,一个模板,比如汽车图纸
对象:由类生成(实例化)出来的具体的事物,比如汽车本身
类和对象是相对而言的
1
2
3
4
5
6
7
8
创造一个类
class 类名():
def __init__(self, 属性1, 属性2 )
self.变量名1 = 属性1
self.变量名2 = 属性2

def 方法名(self):
pass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class cls15:
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
print(self.age)
print(self)

def study(self):
print(f"{self.name}热爱学习")

def play(self):
print(f"{self.name}喜欢打游戏")

#实例化对象 变量 = 类名()
lf = cls15("龙飞", 22, "男")

#调用属性: 对象.属性
print(lf) # 打印发现self与lf一致,说明,self就是龙飞同学
print(lf.name)
xjy = cls15("小鲸鱼", 28, "男")
print(xjy) # 打印发现self与xjy一致,说明,self就是小鲸鱼同学
print(xjy.name)

#调用方法 对象.方法名()
lf.play()
xjy.study()

#举例
#对象名 = 类名() 实例化一个列表类
a_list = list("hello world")
# 对象名.方法() 调用类的方法
a_list.append("a")
print(a_list)
1
2
实例化对象: 类名()
变量名 = 类名(属性值1, 属性值2)

init 是构造函数

1
2
3
4
初始化(构造)方法  __init__()
不需要调用,在对象被实例化的时候自定执行
构造方法和析构方法都是初始化方法
初始化方法里面的属性,可以被一整个类所使用的

self.对象自身
当某个对象调用方法时,会自动把对象(对象名)传入self
对象通过.操作符来调用属性和方法

1
2
3
self
1、就是对象本身()
2、谁调用的,self就是谁

类的析构函数

1
2
3
4
5
6
7
对象的生命周期  被创建---->被释放
构造函数:__init__
当对象被创建的时候自动执行
析构函数:__del__
当对象从内存中被释放的时候自动执行
1、代码全部执行完毕
2、手动删除该对象(变量)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class cls15():
def __init__(self):
print("hello , 我诞生了")

def __del__(self):
print("bey,我要走了!")
print(1)
print(1)
print(1)
print(1)

def func(self):
print("这是一个函数")


lm = cls15()
# lm.func()
del lm
# lm.func()
print("ing……………………")

面向对象三大特性

1
2
3
封装: 把属性和方法都放在类里面
继承: 子类表现出和父类一致的地方
多态: 子类表现出和父类不一致的地方

继承

1
2
3
4
5
6
7
8
继承的语法
class 子类(父类):
pass

特点:子类可以拥有父类的一切属性和方法

在Python3里面,所有的类都默认继承object类。
object又称为基类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Ape(object):
def walk(self):
print("可以直立行走")

def work(self):
print("可以使用工具")

#继承
class Human(Ape):
pass


xx = Ape()
xx.walk()

gf = Human()
gf.walk() # Human没有这个walk方法,也能直立行走
gf.work()
#原因:Human继承了Ape
1
多继承与重写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class GrandFather(object):
def big_money(self):
print("GrandFather 有 1000万")

def company(self):
print("鞋厂")


class Father(GrandFather):
def little_money(self):
print("Father 有 10万")


class Son(Father):
def no_money(self):
print("有1000块")


# 实例化应该son的对象
lm = Son()
lm.no_money() # 自己有用自己的
lm.little_money() # 自己没有用父类的
lm.big_money() # 父类没有,用祖父类
lm.big_big_money() # 大家都没有,报错


#查看类的继承关系 __mro__
print(Son.__mro__) # 这里面都找不着就报错
1
2
3
多继承:
优先使用离自己近的
在同一级里面,左边优先原则
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Father1(object):
def money(self):
print("GrandFather 有 1000万")

def company(self):
print("鞋厂")


class Father2(Father1):
def money(self):
print("Father 有 10万")

#注意语法,这个括号里的顺序是精华所在
class Son(Father2, Father1):
pass


#实例化应该son的对象
lm = Son()
lm.money()

多态

1
2
3
4
5
多态:名字一样但功能不一样
子类和父类方法或者属性名一致的时候,会优先使用自己的
重写:
重新继承父类的方法(即都要,都表现出来):
super().方法名()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class GrandFather(object):
def big_money(self):
print("GrandFather 有 1000万")

def company(self):
print("鞋厂")


class Father(GrandFather):
def little_money(self):
print("Father 有 10万")


class Son(Father):
def no_money(self):
print("有1000块")

def company(self):
print("电竞公司")
# 重新调用父类的功能
super().company()


# 实例化应该son的对象
lm = Son()
lm.company() # 优先使用自己的
# 贪心: 鞋厂和电竞公司都想要
# 解决: super().方法名
1
2
3
4
5
6
7
8
9
10
#多态:名字一样但功能不一样
#如何理解这个概念,以下例子
#在面向对象里只是子类给父类覆盖掉了
lm = "流木" # 变量名
print(lm)

def lm(): # 函数名
print(1234)

lm()

多态练习题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
多态
已知内存的二进制的转换如下:
1byte(B) = 8 bits(b) 字节;1KB = 2^10B = 1024 千字节
1MB = 2^10KB 兆字节; 1GB = 2^10MB 千兆字节
1TB = 2^10GB
1)、现在有一个上课回放视频,大概200000KB, 假设某个网盘的下载速度为2MB/s,
请定义一个函数,计算大概下载所需时间。
2)、现在网盘对于VIP用户的下载速度为5.5MB/s,
请使用面向对象分别计算普通用户与VIP用户的下载速度,使用多态完成
分析:创建网盘类,有下载的方法,拥有两个子类:
普通用户(可以下载,速度为2M/s)与VIP用户(可以下载,速度为5.5M/s)

总结:
共同点使用父类封装
个性点,使用多态自定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 第一题
def kb_mb(ks): # 定义一个转换单位的方法
mb_size = ks / 1024
return mb_size # 返回转换后的单位


def speed(ms): # 定义计算下载速度的方法
# 总时长 = 大小/速度
sp = ms / 2
return f"下载所需时长为{sp}秒"


size = int(input("请输入你要下载的大小(kB):"))
print(speed(kb_mb(size)))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 第二题
class WangPan():

def kb_mb(self, xz): # 定义一个转换单位的方法
"""
:param xz: 原有单位
:return: 转换后的单位
"""
mb_size = xz / 1024
return mb_size # 返回转换后的单位

def down_load(self): # 定义计算下载速度的方法
pass


class PuTong(WangPan):
def __init__(self, name, xz):
self.name = name
self.xz = xz
print(f"{self.name}普通用户正在下载,大小为{self.xz}")

def down_load(self):
ms = self.kb_mb(self.xz) # 直接调用父类的转换单位
sp = ms / 2
print(f"下载所需时长为{sp}秒")


class VIP(WangPan):
def __init__(self, name, xz):
self.name = name
self.xz = xz
print(f"尊贵的{self.name}用户正在下载,大小为{self.xz}")

def down_load(self):
ms = self.kb_mb(self.xz) # 直接调用父类的转换单位
sp = ms / 5.5
print(f"下载所需时长为{sp}秒,请稍等片刻")


pt = PuTong("普通",200000)
pt.down_load()
vip = VIP("vip",200000)
vip.down_load()

私有属性和私有方法

1
2
3
4
5
私有属性和私有方法也可以继承吗?
__属性名
__方法名

Python当中没有绝对的私有,可以通过中间方法进行调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Father(object):

def __init__(self):
self.name = "孙涛"
self.__age = 18 # 私有属性

def test1(self):
print("test1")

def __test2(self): # 私有方法
print("test2")
#内鬼,即中间方法
def neigui(self):
print(self.__age) # 在自己类里面可以调用私有属性
self.__test2() # 在自己类里面可以调用私有属性


class Son(Father):
pass


lm = Son()
print(lm.name) # 属性可以继承
# print(lm.__age) # 私有属性不可以继承
lm.test1()
# lm.__test2() # 私有方法不可以继承
lm.neigui()