python—面向对象的封装、继承、多态

封装

1.封装是面向对象编程的一大特点
2.面向对象编程的第一步,将属性和方法封装到一个抽象的类中(为什么类是抽象的?)
3.外界使用类创建对象,然后让对象调用方法
4.对象方法的细节都被封装在类的内部

案例1
小明和小美爱跑步
1.小明体重75.0公斤
小美体重45.0公斤
2.小明每次跑步会减肥0.5公斤
3.小明每次吃东西体重会增加1公斤

class Person:
def init(self, name, weight):
# 在初始化方法中增加两个参数由外界传递
# self.属性 = 形参
self.name = name
self.weight = weight
def str(self):
return ‘我的名字叫 %s 体重是 %.2f’ % (self.name, self.weight)
def run(self):
# pass
print ‘%s 爱跑步’ % self.name
# 在对象方法的内部,是可以直接访问对象的属性
self.weight -= 0.5
def eat(self):
#pass
print ‘%s 吃东西’ % self.name
self.weight += 1
xiaoming = Person(‘小明’,75.5)
xiaoming.run()
xiaoming.eat()
print xiaoming

xiaomei = Person(‘小美’,45.0)
xiaomei.eat()
xiaomei.run()

# 同一个类创建的多个对象之间,属性互补干扰
print xiaomei
print xiaoming

案例2:摆放家具
需求:
1.房子有户型,总面积和家具名称列表
新房子没有任何的家具
2.家具有名字和占地面积,其中
床:占4平米
衣柜:占2平面
餐桌:占1.5平米
3.将以上三件家具添加到房子中
4.打印房子时,要求输出:户型,总面积,剩余面积,家具名称列表

剩余面积:
1.在创建房子对象的时候,定义一个剩余面积的属性,初始值和总面积相等
2.在调用添加家具的方法时,让 剩余面积 -= 家具的面积

class HouseItem:
# 初始化方法
def init(self,name,area):
self.name = name
self.area = area
# 描述方法,返回家具的描述
def str(self):
return ‘[%s] 占地 %.2f’ %(self.name,self.area)

# 1.创建家具
bed = HouseItem(‘bed’,4)
print bed
chest = HouseItem(‘chest’,2)
print chest
table = HouseItem(‘table’,1.5)
print table

案例3.演练重点:一个对象的属性可以是另外一个类创建的对象
示例:士兵射击
需求:
1.士兵瑞恩有一把AK47
2.士兵可以开火(士兵开火扣动的是扳机)
3.枪 能够 发射子弹(把子弹发射出去)
4.枪 能够 装填子弹 –增加子弹的数量
Soldier Gun
——— ————
name model
gun bullet_count
———- ————-
init(self) init(self)
fire(self) add_bullet(self,count)
shoot(self)

class Gun:
def init(self, model):
# 枪的型号
self.model = model
# 子弹的数量
self.bullet_count = 0
def add_bullet(self,count):
self.bullet_count += count
# 只要子弹的数量足够,就能发射,所有shoot方法不需要传递参数
def shoot(self):
# 1.判断子弹的数量
if self.bullet_count <= 0:
print ‘[%s] 没有子弹了…’ %self.model
return
# 2.发射子弹,子弹数量-1
self.bullet_count -= 1
# 3.提示发射信息
print ‘[%s] 突突突…[%d]’ %(self.model,self.bullet_count)

class Soldier:
def init(self,name):
self.name = name
# 定义属性的时候,如果不知道设置什么初始值,可以设置为None
# None关键字表示什么都没有,表示一个空对象,没有方法和属性
# 是一个特殊的常量,可以将None赋值给任何一个变量
self.gun = None

def fire(self):
    # 1.判断士兵是否有枪
    if self.gun == None:
        print '[%s] 还没有枪...' %self.name
        return
    print 'go!!! [%s]' %self.name
    self.gun.add_bullet(50)
    self.gun.shoot()

# 1.创建枪对象
ak = Gun(‘AK47’)
# 枪不能自己发射子弹,枪不能自己开火 需要士兵去完成
# ak.add_bullet(50)
# ak.shoot()

# 2.创建瑞恩
ryan = Soldier(‘Ryan’)
#ryan.gun = ak
ryan.fire()
print ryan.gun

继承

封装:根据职责将属性和方法封装到一个抽象的类中
继承:实现代码的重用,相同的代码不需要重复的写

单继承
class Animal:
def eat(self):
print ‘吃’
def drink(self):
print ‘喝’
def run(self):
print ‘跑’
def sleep(self):
print ‘睡’

class Cat(Animal):
# 子类拥有父类的所有属性和方法
def call(self):
print ‘喵喵~’
fentiao = Cat()
fentiao.eat()
fentiao.drink()
fentiao.run()
fentiao.sleep()
fentiao.call()
# 子类继承自父类,可以直接享受父类中已经封装好的方法
“””
单继承
1.继承的概念:子类拥有父类的所有属性和方法(子类只需要封装自己特有的方法)
2.语法
class 类名(父类):
def 子类特有的方法
“”“

继承的传递性(爷爷 爸爸 儿子)
1.C 类从B类继承 ,B类又从A类继承
2.那么C类就具有B类和A类的所有属性和方法

class Animal:
def eat(self):
print ‘吃’
def drink(self):
print ‘喝’
def run(self):
print ‘跑’
def sleep(self):
print ‘睡’

class Cat(Animal):
# 子类拥有父类的所有属性和方法
def call(self):
print ‘喵喵~’

class Hellokitty(Cat):
def speak(self):
print ‘我可以说日语’

# 创建一个Hellokitty对象
kt = Hellokitty()
kt.speak()
kt.call()

# 继承的传递性 子类拥有父类的父类的属性和方法
kt.eat()
kt.drink()
kt.sleep()
kt.run()

方法的重写
1.覆盖父类的方法(重写父类方法)
2.对父类方法进行扩展

class Animal:
def eat(self):
print ‘吃’
def drink(self):
print ‘喝’
def run(self):
print ‘跑’
def sleep(self):
print ‘睡’

class Cat(Animal):
# 子类拥有父类的所有属性和方法
def call(self):
print ‘喵喵~’

class Hellokitty(Cat):
def speak(self):
print ‘我可以说日语’
def call(self):
# 1.针对子类特有的需求,编写代码
print ‘欧哈呦~空你起哇’
# 2.调用原本子阿父类中封装的方法
Cat.call(self)
#3.增加其他子类代码
print ‘@ @ ! #@!$!#’
kt =Hellokitty()
# 如果子类中,重写了父类的方法
# 在运行中,只会调用在子类中重写的方法而不会调用父类的方法
kt.call()

单继承易错点
class Bird:
def init(self):
self.hungry=True
def eat(self):
if self.hungry:
print ‘Aaaaa’
self.hungry=False
else:
print ‘No Thank~’

class SongBird(Bird):
def init(self): #易错
self.sound=’Squawk’ #易错
Bird.init(self) #易错
如果子类中重写了父类的方法,运行中将不会调用父类的方法,需重新调用
def sing(self):
print self.sound

bird=Bird()
bird.eat()

littlebird=SongBird()
littlebird.eat()
littlebird.sing()

多继承
子类拥有一个父类叫作单继承
子类可以拥有多个父类,并且具有所有父类的属性和方法
例如:孩子会继承自己父亲和母亲的特征
class A:
def test(self):
print ‘A———test 方法’
def demo(self):
print ‘A——–demo方法’
class B:
def test(self):
print ‘B ——-test方法’
def demo(self):
print ‘B ———demo 方法’

class C(B,A):
“”“多继承可以让子类对象,同时具有多个父类的属性和方法
多个父辈的方法和属性避免重复
“””
pass

# 创建子类对象
c = C()
c.test()
c.demo()

新式类和旧式类
新式类和旧式(经典)类:
object是Python为所有对象提供的基类,提供有一些内置的属性和方法,可以使用dir函数查看
新式类:以object为基类的类,推荐使用
经典类:不以object为基类的类,不推荐使用
在python3.X中定义的类时,如果没有指定父类,会默认使用object作为基类–python3.x中定义的类都是新式类
在python2.x中定义类时,如果没有指定父类,则不会以object作为基类

推荐使用新式类

新式类和旧式类在多继承时—会影响到方法的搜索顺序

为保证编写的代码能够同时在python2.x和python3.x运行
今后在定义类时,如果没有父类,建议统一继承自object

class A(object):
… pass

a = A()
dir(a) #查看内置的属性和方法


class B:
… pass

b=B()
dir(b)

==========================================================================
Python 早期,它对于class的定义在很多方面都是严重有问题的。当他们承认这一点的时候已经太迟了,
所以逼不得已,他们需要支持这种有问题的class 。
为了解决已有的问题,他们需要引入一种“新类”,这样的话“旧类”还能继续使用,而你也有一个新的正确的类可以使用了。
这就用到了“类即是对象”的概念。他们决定用小写的“object”这个词作为一个类,让你在创建新类时从它继承下来。

猜你喜欢

转载自blog.csdn.net/weixin_42915309/article/details/82463287