面向对象基础
面向对象是一种抽象化的编程思想,就是将编程当成是一个事物。对于外界来说,事物是直接使用的,不用管内部情况,而编程则是设置事物应该做什么事。
类和对象
用类创建对象。类是对一系列具有相同**特征(属性)和行为(方法)**的事物的统称,是一个抽象的概念,不是真实存在的。对象是由类创造出来真实存在的事物。
Python2中类分为:经典类和新式类
class 类名():
代码
# 类名要满足标识符命名规则,同时遵循大驼峰命名习
# 不由任何内置类型派生出来的类叫做经典类
对象名=类名()
#创建对象也叫实例化对象
self
self:调用该函数的对象
# 1.定义类
class Washer():
def wash(self):
print('我会洗⾐服')
# <__main__.Washer object at 0x0000024BA2B34240>
print(self)
# 2.创建对象
haier1 = Washer()
# <__main__.Washer object at 0x0000018B7B224240>
print(haier1)
# haier1 对象调⽤实例⽅法
haier1.wash()
haier2 = Washer()
# <__main__.Washer object at 0x0000022005857EF0>
print(haier2)
添加和获取对象属性
对象属性既可以在类外⾯添加和获取,也能在类⾥⾯添加和获取。
# 类外添加成员属性
对象名.属性名=值
#类外获取对象属性
对象名.属性名
#类内获取对象属性
self.属性名
class Washer():
def print_info(self):
#类⾥⾯获取实例属性
print(f'haier1 洗⾐机的宽度是{self.width}')
print(f'haier1洗⾐机的高度是{self.height}')
#创建对象
haier1 = Washer()
#添加实例属性
haier1.width = 500
haier1.height = 800
haier1.print_info()
魔方方法
在Python中,xx()的函数叫做魔方⽅法,指的是具有特殊功能的函数。
_init_():初始化对象
#该方法在创建对象时会被默认调用
#_init_(self)的self参数。不需要开发者传递,python解释器会把对当前对象的引用传递过去
class Washer():
#定义初始化功能的函数
def __init__(self):
#添加实例属性
self.width = 500
self.height = 800
def print_info(self):
#类⾥⾯调⽤实例属性
print(f'洗⾐机的宽度是{self.width},⾼度是{self.height}')
haier1 = Washer()
haier1.print_info()
带参数的_init_()方法:
#⼀个类可以创建多个对象,可以通过传参数对不同的对象设置不同的初始化属性
class Washer():
def __init__(self, width, height):
self.width = width
self.height = height
def print_info(self):
print(f'洗⾐机的宽度是{self.width}')
print(f'洗⾐机的⾼度是{self.height}')
haier1 = Washer(10, 20)
haier1.print_info()
haier2 = Washer(30, 40)
haier2.print_info()
_str_()
#当使⽤print输出对象的时候,默认打印对象的内存地址。
#如果类定义了__str__⽅法,那么就会打印从在这个⽅法中return的数据。
class Washer():
def __init__(self, width, height):
self.width = width
self.height = height
def __str__(self):
return'这是海尔洗⾐机的说明书'
haier1 = Washer(10, 20)
#这是海尔洗⾐机的说明书
print(haier1)
_del_()
#当删除对象的时候,python解释器也会默认调用_del_()方法
class Washer():
def __init__(self, width, height):
self.width = width
self.height = height
def __del__(self):
print(f'{self}对象已经被删除')
haier1 = Washer(10, 20)
# <__main__.Washer object at 0x0000026118223278>对象已经被删除
del haier1
封装
将属性和⽅法书写到类的⾥⾯的操作即为封装+封装可以为属性和⽅法添加私有权限
继承
在Python中,所有类默认继承object类,object类是顶级类或基类;其他⼦类叫做派⽣类。
class 类名(object):
代码
#⽗类A
class A(object):
def __init__(self):
self.num = 1
def info_print(self):
print(self.num)
#⼦类B
class B(A):
pass
result = B()
result.info_print()# 1
(1)当⼀个类有多个⽗类的时候,默认使⽤第⼀个⽗类的同名属性和⽅法。
(2)⼦类和⽗类具有同名属性和⽅法,默认使⽤⼦类的同名属性和⽅法。
class Master(object):
def __init__(self):
self.kongfu = '[古法煎饼果⼦配⽅]'
def make_cake(self):
print(f'运⽤{self.kongfu}制作煎饼果子')
class School(object):
def __init__(self):
self.kongfu = '[⿊⻢煎饼果⼦配⽅]'
def make_cake(self):
print(f'运⽤{self.kongfu}制作煎饼果子')
class Prentice(School, Master):
def __init__(self):
self.kongfu = '[独创煎饼果⼦配⽅]'
def make_cake(self):
#如果是先调⽤了⽗类的属性和⽅法,⽗类属性会覆盖⼦类属性,故在调⽤属性前,先调⽤⾃⼰⼦类的初始化
self.__init__()
print(f'运⽤{self.kongfu}制作煎饼果⼦')
#调⽤⽗类⽅法,但是为保证调⽤到的也是⽗类的属性,必须在调⽤⽅法前调⽤⽗类的初始化
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_school_cake(self):
School.__init__(self)
School.make_cake(self)
daqiu = Prentice()
daqiu.make_cake()
daqiu.make_master_cake()
daqiu.make_school_cake()
daqiu.make_cake()
super():调用父类方法
使⽤super()可以⾃动查找⽗类。调⽤顺序遵循__mro__类属性的顺序。⽐较适合单继承使⽤。
私有权限
在Python中,可以为实例属性和⽅法设置私有权限,即设置某个实例属性或实例⽅法不继承给⼦类。设置私有权限的⽅法:在属性名和⽅法名前⾯加上两个下划线__
self._money=200000
(1)使用get__xx获取私有属性,使用set__xx修改私有属性
#获取私有属性
def get_money(self):
return self.__money
#修改私有属性
def set_money(self):
self.__money = 500
多态
传⼊不同的对象,产⽣不同的结果
多态指的是⼀类事物有多种形态,(⼀个抽象类有多个⼦类,因⽽多态的概念依赖于继承)。
定义:
(1)多态是⼀种使⽤对象的⽅式,⼦类重写⽗类⽅法,调⽤不同⼦类对象的相同⽗类⽅法,可以产⽣不同的执⾏结果
(2)好处:调⽤灵活,有了多态,更容易编写出通⽤的代码,做出通⽤的编程,以适应需求的不断变化!
实现步骤:
(1)定义⽗类,并提供公共⽅法
(2)定义⼦类,并重写⽗类⽅法,传递⼦类对象给调⽤者,可以看到不同⼦类执⾏效果不同
class Dog(object):
def work(self):
#⽗类提供统⼀的⽅法,哪怕是空⽅法
print('指哪打哪...')
class ArmyDog(Dog):
#继承Dog类
def work(self):
#⼦类重写⽗类同名⽅法
print('追击敌人...')
class DrugDog(Dog):
def work(self):
print('追查毒品...')
class Person(object):
def work_with_dog(self, dog):
#传⼊不同的对象,执⾏不同的代码,即不同的work函数
dog.work()
ad = ArmyDog()
dd = DrugDog()
daqiu = Person()
daqiu.work_with_dog(ad)
daqiu.work_with_dog(dd)
类属性和类方法
类属性就是类对象所拥有的属性,它被该类的所有实例对象所共有。类属性可以使⽤类对象或实例对象访问。
类的实例记录的某项数据始终保持⼀致时,则定义类属性。实例属性要求每个对象为其单独开辟⼀份内存空间来记录数据,⽽类属性为全类所共有,仅占⽤⼀份内存,更加节省内存空间。
类属性只能通过类对象修改,不能通过实例对象修改,如果通过实例对象修改类属性,表示的是创建了⼀个实例属性。
类方法是第⼀个形参是类对象的⽅法,需要⽤装饰器@classmethod来标识其为类⽅法,对于类⽅法,第⼀个参数必须是类对象,⼀般以cls作为第⼀个参数。
静态方法需要通过装饰器@staticmethod来进⾏修饰,静态⽅法既不需要传递类对象也不需要传递实例对象(形参没有self/cls)。静态⽅法也能够通过实例对象和类对象去访问。
class Dog(object):
@staticmethod
def info_print():
print('这是⼀个狗类,⽤于创建狗实例...')
wangcai = Dog()
#静态⽅法既可以使⽤对象访问⼜可以使⽤类访问
wangcai.info_print()
Dog.info_print()
需求分析
烤地瓜
产品设计需求:
(1)被烤的时间和对应的状态
0-3min | 生的 |
---|---|
3-5min | 半生不熟 |
5-8min | 熟的 |
>=8 | 烤熟了 |
(2)调料:用户可以按照自己的意愿进行添加
步骤分析:
地⽠的属性
- 被烤的时间
- 地⽠的状态
- 添加的调料
地⽠的⽅法
- 被烤
⽤户根据意愿设定每次烤地⽠的时间
判断地⽠被烤的总时间是在哪个区间,修改地⽠状态 - 添加调料
⽤户根据意愿设定添加的调料,将⽤户添加的调料存储,显示对象信息
#定义类
class SweetPotato():
def __init__(self):
#被烤的时间
self.cook_time = 0
#地⽠的状态
self.cook_static = '⽣的'
#调料列表
self.condiments = []
def cook(self, time):
"""烤地⽠的⽅法"""
self.cook_time += time
if 0<= self.cook_time<3:
self.cook_static = '⽣的'
elif 3<= self.cook_time<5:
self.cook_static = '半⽣不熟'
elif 5<= self.cook_time<8:
self.cook_static = '熟了'
elif self.cook_time>= 8:
self.cook_static = '烤糊了'
def add_condiments(self, condiment):
"""添加调料"""
self.condiments.append(condiment)
def __str__(self):
return f'这个地⽠烤了{self.cook_time}分钟,状态是{self.cook_static},添加的调料有{self.condiments}'
digua1 = SweetPotato()
print(digua1)
digua1.cook(2)
digua1.add_condiments('酱油')
print(digua1)
digua1.cook(2)
digua1.add_condiments('辣椒⾯⼉')
print(digua1)
digua1.cook(2)
print(digua1)
digua1.cook(2)
print(digua1)
搬家具
需求:将小于房子剩余面积的家具摆放到房子中
class Furniture():
def __init__(self, name, area):
#家具名字
self.name = name
#家具占地⾯积
self.area = area
class Home():
def __init__(self, address, area):
#地理位置
self.address = address
#房屋⾯积
self.area = area
#剩余⾯积
self.free_area = area
#家具列表
self.furniture = []
def __str__(self):
return f'房⼦坐落于{self.address},占地⾯积{self.area},剩余⾯积{self.free_area},家具有{self.furniture}'
def add_furniture(self, item):
"""容纳家具"""
if self.free_area>= item.area:
self.furniture.append(item.name)
#家具搬⼊后,房屋剩余⾯积=之前剩余⾯积-该家具⾯积
self.free_area -= item.area
else:print('家具太⼤,剩余⾯积不⾜,⽆法容纳')
bed = Furniture('双⼈床',6)
jia1 = Home('北京',1200)
jia1.add_furniture(bed)
sofa = Furniture('沙发',10)
jia1.add_furniture(sofa)
ball = Furniture('篮球场',1500)
jia1.add_furniture(ball)