1. 面向对象的访问限制
1.1 定义
在Class内部,可以有属性和方法,
外部的代码可以通过直接调用实例变量的方法来操作数据。
- 这种操作方法有很大的弊端:外部的代码可以自由修改实例中的属性
这种情况不安全
我们要让内部属性不被外部访问,可以在属性的名称前加上两个下划线__
-
在python中,实例的变量名以__开头就变成一个私有变量(private),只有内部可以访问,外部不可以访问。
这样就可以保证外部代码不能随意修改对象内部的状态,进行访问控制限制保护,提高了安全性。 -
让外部获取或者修改私有变量 —— 添加set和get方法
1.2 练习
2. 面向对象的特征
2.1 封装
封装是对具体对象的一种抽象,即将某些部分隐藏起来,在程序外部看不到,其含义是其他程序无法调用。
将对象和属性封装起来,使不同的对象具有不同的属性。
2.2 继承
- 继承是一种创建新的类的方式,新创建的叫子类,继承的叫父类、超类、基类。
- 继承的特点:
子类可以使用父类的属性(特征、技能) 继承是类与类之间的关系- 继承的作用:
减少代码冗余、提高重用性
class Father(object):
def __init__(self,name,age):
self.name = name
self.age = age
def age(self):
print('%s is eating...' %self.name)
def set_goal(self):
print('%s set a goal' %self.name)
#Son继承于Father类
class Son(Father):
def eat(self):
print('%s daoli eating...' %self.name)
father = Father('lao wang','24') # 调用父类创建对象
son = Son('wang','34') # 通过字类间接调用父类创建对象
print(son.name) # 继承父类属性
son.set_goal() # 继承父类方法
son.eat() # 子类重写父类方法
3.3 新式类和经典类
- 新式类是深度优先
是指从起始页开始,一个链接一个链接跟踪下去,处理完这条线路之后再转入下一个起始页,继续追踪链接。
# python2中深度优化
class D():
def test(self):
print('test in D...')
class C(D):
def test(self):
print('test in C...')
class B(D):
pass
# def test(self):
# print('test in B...')
class A(B,C):
pass
# def test(self):
# print('test in A...')
a = A()
print(a.test())
打印结果 A-B-D结束
test in D..
- 经典类是广度优先
是指先抓取起始页中的所有网页,然后在选择其中的一个连接网页,继续抓取在此网页中链接的所有网页。
# python3中广度优先
class D(object):
def test(self):
print('test in D...')
class C(D):
def test(self):
print('test in C...')
class B(D):
pass
# def test(self):
# print('test in B...')
class A(B,C):
pass
# def test(self):
# print('test in A...')
a = A()
print(a.test())
打印结果 A-B--C-D 结束
test in C..
3.4 多态
多态是以封装和继承为前提的, 一个操作的意义取决于被操作对象的类型,相同的消息给予不同的对象会引发不同的动作
多态意味着变量并不知道引用的对象是什么,根据引用对象的不同表现不同的行为方式在处理多态对象时,只需要关注他的接口即可
同一个操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
3. 面向对象和类的实例
案例一:
1.小明和小美都爱跑步
2.小美体重45.0公斤
3.小明体重75.0公斤
4.每次跑步都会减少0.5公斤
5.每次吃东西都会增加1公斤
class People():
def __init__(self,name,weight): #定义初始化方法,把对象和属性打包封装在一起赋值变量
self.name = name
self.weight = weight
def __str__(self): #定义str方法
return '我的名字是%s,体重是%.2f斤' %(self.name,self.weight)3
def run(self): #定义跑的方法
print('%s 爱跑步' %self.name)
self.weight -= 0.5
def eat(self): 定义吃的方法
print('%s吃东西' %self.name)
self.weight += 1
xiaoming = People('xiaoming',75.0) #创建对象
xiaoming.run() #调用run()方法
print(xiaoming) #直接使用str方法
xiaomei = People('xiaomei',45.0)
xiaomei.eat()
print(xiaomei)
案例二:
使用类和对象实现对栈的基本操作
class Stack(object):
def __init__(self):
#定义一个空列表,相当于一个空栈,用来存储和读取
self.stack = []
#用来检测长度
def __len__(self):
return len(self.stack)
def top(self):
#判断栈是否为空
if not self.is_empty():
return self.stack[-1]
#抛出异常
raise Exception('stack is empty!')
def push(self,element):
self.stack.append(element)
def pop(self):
#判断栈是否为空
if self.is_empty():
raise Exception('stack is empty!')
else:
item = self.stack.pop()
return item
def length(self):
return len(self.stack)
def is_empty(self):
return len(self.stack) == 0
#实例化
stack = Stack()
stack.push(1)
stack.push(2)
print(stack.length())
item = stack.pop()
print('The pop item is: %s' %item)
print(stack.top())
print(stack.is_empty())
print(stack.pop())
print(stack.length())
print(stack.is_empty())
案例三:
房子有户型,总面积和家具名称列表
新房子没有任何的家具家具有名字和占地面积,其中
床:占4平米
衣柜:占2平米
餐桌:占1.5平米将以上三件家具添加到房子中
打印房子时,要求输出:户型,总面积,剩余面积,家具名称列表
class House():
def __init__(self,house_type,area): #把对象和属性封装起来
#定义类属性也就是变量
self.house = house_type
self.area = area
self.free_area = area
self.item_list = [] #空房子列表为空
#定义方法其实就是写函数
def __str__(self): #定义str方法,返回值
return ('户型:%s\n总面积:%.2f\n剩余面积:%.2f\n家具:%s'
%(self.house,self.area,self.free_area,self.item_list))
def add_item(self,item): #添加家具及判断家具和房子面积
if item.area > self.free_area: #判定家具面积大于房子剩余面积
print('%s的面积太大,无法添加' %(item.name))
return False
self.item_list.append(item.name) #添加家具
self.free_area -= item.area #计算剩余面积
bed = Furniture('bed',4) #家具类实列化
wardrobe = Furniture('wardrobe',2)
table = Furniture('table',1.5)
my_house = House('别墅',500) #房子类实列化 #调用add_item()添加家具
my_house.add_item(bed)
my_house.add_item(wardrobe)
my_house.add_item(table)
print(my_house)
案例四:
士兵瑞恩有一把ak47
士兵可以开火(开火扣动的是班级)
抢能够发射子弹(把子弹打出去)
抢能够装子弹–增加子弹数量
class Gun(object):
def __init__(self,model): #名字model
self.model = model
self.bullet_count = 0 #子弹数为0
def add_bullet(self,count): #给抢添加子弹
self.bullet_count += count
def shoot(self): #设计
if self.bullet_count <= 0 : #挡枪里面的子弹数小于等于0
print('%s没有子弹' %(self.model)) #打印没有子弹
else:
self.bullet_count -= 1 #否则每射击一次子弹数量减1,求子弹余数
print('%s的子弹数量为%s' %(self.model,self.bullet_count)) #打印子弹余数
class Soldier(object): #定义士兵类
def __init__(self,name): #士兵名字
self.name =name
self.gun = None #士兵没有抢
def fire(self): #士兵开枪
if self.gun == None: #判断=None
print('%s没有枪' %(self.name)) #打印没有抢
else:
self.gun.add_bullet(5) #否则给抢添加5颗子弹
self.gun.shoot() #射击
ak47 = Gun('AK47') #实列化抢
ak47.add_bullet(10) #给抢添加子弹
ak47.shoot() #射击
ruien = Soldier('RE') #实列化士兵
ruien.gun = ak47 #给士兵枪
ruien.fire() #士兵开枪