全民一起玩Python提高篇第十二课:面向对象基本原理与语法(三)

继承

class A:
    def __init__(self):
        self.money=50000000
        self.house=100

    def my_small_goal(self):
        print('先挣他一个亿')

class B(A):
#通过在定义类后面加上括号和类名,就可以实现继承
#pass语句必须要
    pass
if  __name__=='__main__':
    
    x=B()
    print(x.money)
    x.my_small_goal()
50000000
先挣他一个亿

继承是一种复制,而不是传递
继承的方法也可以扩展和覆盖

class A:
    def __init__(self):
        self.money=50000000
        self.house=100

    def my_big_goal(self):
        print('挣他100个亿')

    def my_small_goal(self):
        print('先挣他一个亿')

class B(A):
    def hobby(self):
        print('唱跳rap篮球')

    def my_small_goal(self):
        print('先挣他10个亿')
    #扩展和方法的覆盖

class C(A):
    pass

if  __name__=='__main__':
    x=[B(),C()]
    b=B()
    b.hobby()
    for i in x:
        print(i.money)
        i.my_big_goal()
        i.my_small_goal()
        #B.hobby()

如果B是A的子类,那么B既属于类型B,也属于类型A。type(B类对象)的结果是B类,但是isinstance(B类对象, A类名)将返回True。isinstance比type方法更加灵活合理。
如果子类中重写了__init__初始化,那么也会造成对父类的覆盖

题目:计算机类

日常生活使用电脑可以上网冲浪、编程和玩游戏,请定义Computer类,实现这三个方法,每个方法里只要用print输出一句提示即可。
接下来定义Pc和Laptop类,并且都继承自Computer类,然后在主程序中创建这两个类的对象,并调用它们继承来的冲浪等方法。

class Computer():
    def Surfing(self):
        print('我在网上冲浪')

    def Programming(self):
        print('我在编程')

    def Playing(self):
        print('我在打游戏')

class PC(Computer):
    pass

class Laptop(Computer):
    pass

if __name__=='__main__':
    computers=[Computer(),PC(),Laptop()]
    for i in computers:
        i.Surfing()
        i.Programming()
        i.Playing()

美国高校某班级中的学员来自中国,日本和美国三个不同国家,学生类拥有speak方法可以进行发言,默认采用英文发言。
但是来自中日两国的学生发言时,分别使用汉语和日语。
请编写学生类、中国学生类、日本学生类和美国学生类四个类,其中学生类的speak执行“默认语言”,即用print输出“英语发言”。然后其他各国学生都继承了学生类,其中日本和中国学生的speak执行各自语言。
现在班级中有两个中国学员,一个日本学员和三个美国学员,请生成不同对象代表它们,然后放入列表中,按顺序依次发言。

class Student:
    def Speak(self):
        print('英语发言')

class American(Student):
    pass

class Japanese(Student):
    def Speak(self):
        print('日语发言')

class Chinese(Student):
    def Speak(self):
        print('中文发言')

if __name__=='__main__':
    students=[Chinese(),Chinese(),American(),American(),American(),Japanese()]
    for s in students:
        s.Speak()

假设编写一个游戏,其中有玩家类和敌人类,二者又都继承自人类。
人类拥有普通攻击和防御的方法(方法内容直接写成print语句即可);
玩家类的对象除了普通攻击和防御以外,还可以进行魔法攻击;
敌人类的对象除了普通攻击和防御以外,还具备复活方法。
请编写程序实现这三个类,然后创建一个玩家对象、一个敌人对象,再调用它们的不同方法进行测试。

class Person:
    def attack(self):
        print('这是普通攻击')

    def defend(self):
        print('这是防御')

class Player(Person):
    def Magic(self):
        print('这是魔法攻击')

class Enemy(Person):
    def Revive(self):
        print('这是复活')

if __name__=='__main__':
    player=Player()
    enemy=Enemy()
    person=[player,enemy]
    for i in person:
        i.attack()
        i.defend()
    enemy.Revive()
    player.Magic()

定义一个几何形状类Shape,Shape类中拥有求周长和面积的方法。但因为不知道是哪一种具体的形状,所以Shape里这两个方法的内容为空(pass)。
接下来为形状类添加几个子类:正方形,长方形和立方体。
其中正方形和长方形覆盖了父类的周长和面积两种方法,实现了针对自己这种形状的具体计算方法;
而立方体类不需要求周长,但是需要求面积和体积。
请编程实现上述功能。

class Shape:

    def Circumference(self):
        pass
    def Area(self):
        pass

class Square(Shape):
    def  __init__(self,length):
        self.__l=length
    def Circumference(self):
        print('正方形的周长是',self.__l*4)
    def Area(self):
        print('正方形的面积是',self.__l*self.__l)

class   Rectangle(Shape):
    def __init__(self,length,width):
        self.__l=length
        self.__w=width
    def Circumference(self):
        print('长方形的周长是',(self.__l+self.__w)*2)
    def Area(self):
        print('长方形的面积是',self.__l*self.__w)

class   Cube(Shape):
    def __init__(self,length,width,height):
        self.__l=length
        self.__w=width
        self.__h=height
    def Area(self):
        print('立方体的面积是',(self.__l*self.__w+self.__l*self.__h+self.__w*self.__h)*2)

    def Volume(self):
        print('立方体的体积是',self.__l*self.__w*self.__h)

if __name__=='__main__':
    cube=Cube(5,4,3)
    square=Square(4)
    rectangle=Rectangle(5,4)
    geometries=[cube,square,rectangle]
    for g in geometries:
        g.Area()
    rectangle.Circumference()
    square.Circumference()
    cube.Volume()

多继承

不指定B的属性,会直接继承A的

class A:
    def __init__(self):
        self.p='hello'

class B(A):
    pass
x=A()
print(x.p)
y=B()
print(y.p)

如果给B写了一个方法,那么调用时就不会调用来自A的,就不存在y.p的

class B(A):
    def __init__(self):
        self.q='bye'
class RichMan:
    def __init__(self,n,m):`在这里插入代码片`
        self.money=m
        self.name=n

    def MakeFriends(self):
        print(f'{self.name}说,这些钱拿去花:{self.money/200}')

class 富二代(RichMan):
    def 炫富(self):
        print(f'我叫{self.name},这些钱都是我的:',self.money*10)

if __name__=='__main__':
    a=RichMan('锦到黑',100000000)
    a.MakeFriends()
    
    b=富二代('锦锦黑',10000000000)
    b.炫富()
    b.MakeFriends()
    #交给朋友是调用的父类

把父类属性设为私有

class RichMan:
    def __init__(self,n,m):
        self.__money=m
        self.name=n

    def MakeFriends(self):
        print(f'{self.name}说,这些钱拿去花:{self.__money/200}')

class 富二代(RichMan):
    def 炫富(self):
        print(f'我叫{self.name},这些钱都是我的:', self._RichMan__money*10)
        #直接写self.__money*10肯定是不对的,但是这种封装
        #不是强封装,只是改了名字

子类调用父类的__init__

class RichMan:
    def __init__(self,n,m):
        self.__money=m
        self.name=n

    def MakeFriends(self):
        print(f'{self.name}说,这些钱拿去花:{self.__money/200}')

class 富二代(RichMan):
    def __init__(self,n,m,w):
        self.weibo=w
        RichMan.__init__(self,n,m)
       	#或者写成 super().__init__(n,m)
        #父类的__init__(self,n,m),减少代码量
    def 炫富(self):
        print(f'我叫{self.name},微博账号为{self.weibo},这些钱都是我的:', self._RichMan__money*10)
        #直接写self.__money*10肯定是不对的,但是这种封装
        #不是强封装,只是改了名字

if __name__=='__main__':
    a=RichMan('锦到黑',100000000)
    a.MakeFriends()

    b=富二代('锦锦黑',10000000000,'朴实无华')
    b.炫富()
    b.MakeFriends()
    #交给朋友是调用的父类

部分覆盖原方法

class RichMan:
    def __init__(self,n,m):
        self.__money=m
        self.name=n

    def MakeFriends(self):
        print(f'{self.name}说,这些钱拿去花:{self.__money/200}')

class 富二代(RichMan):
    def __init__(self,n,m,w):
        self.weibo=w
        RichMan.__init__(self,n,m)
        # 或者写成 super().__init__(n,m)
        #父类的__init__(self,n,m)
    def 炫富(self):
        print(f'我叫{self.name},微博账号为{self.weibo},这些钱都是我的:', self._RichMan__money*10)
        #直接写self.__money*10肯定是不对的,但是这种封装
        #不是强封装,只是改了名字
    def MakeFriends(self):
        super().MakeFriends()
        #先执行进行的,再补充自己的,部分覆盖
        print(f'我是富二代,这些钱拿去花:{self._RichMan__money}')
if __name__=='__main__':
    a=RichMan('锦到黑',100000000)
    a.MakeFriends()

    b=富二代('锦锦黑',10000000000,'朴实无华')
    b.炫富()`在这里插入代码片`
    b.MakeFriends()
    #交给朋友是调用的父类

多继承主程序

from Creature import *
#导入所有对象
from Jobs import *
class 人类教师(,教师):
    #继承于两个类,如果两个类的方法同名
    #看传参顺序,这里的人就优先级高于教师
    def 写板书(self):
        print('先擦黑板!')

class 魔鬼教师(魔鬼鱼,教师):
    def 参观海底(self):
        print('去海底兜风')

if __name__=='__main__':
    a=人类教师()
    b=魔鬼教师()
    a.eat();a.讲课();a.说话();a.写板书()
    b.eat();b.游泳();b.参观海底();b.讲课()
#来自不同的继承

两个类的定义
Creature类:

class 生物:
    def eat(self):
        print('新陈代谢')

class 魔鬼鱼(生物):
    def 游泳(self):
        print('游泳ing')

class(生物):
    def 说话(self):
        print('我是人,当然可以说话')
    def 讲课(self):
        print('我开始上课了')
        #和jobs里面的讲课同名

Jobs类:

class 职业:
    def Work(self):
        print('打工仔是不能不打工的')

class 教师(职业):
    def 讲课(self):
        print('上课啦')

class 掠食者(职业):
    def 捕猎(self):
        print('肉不能少')

题目:属性继承

某公司将顾客分为内部顾客和外部顾客,但它们拥有相同的属性:姓名、年龄、职业。
请编写顾客类(Customer)、内部顾客类(InCustomer)和外部顾客类(ExCustomer)三个类。其中顾客类具有上述三个方法,而内外两种顾客都从顾客类中继承到这些数学。
然后创建几个内外部顾客对象,并调用它们的属性作为测试。

class Customer:
    def __init__(self,name,age,job):
        self.n=name
        self.a=age
        self.j=job

class  InCustomer(Customer):
    pass

class ExCustomer(Customer):
    pass

if __name__=='__main__':
    Incustomer=InCustomer('锦到黑',21,'Student')
    Excustomer=ExCustomer('锦到不黑',25,'Engineer')
    print(Incustomer.n,Incustomer.a,Incustomer.j)
    print(Excustomer.n,Excustomer.a,Excustomer.j)

题目:调用父类私有方法

很多数据分析教材中都会用到“鸢尾花数据集”,其中包含了三种花朵样本:山鸢尾(setosa)、变色鸢尾(versicolor)和维吉尼亚鸢尾(virginica)。
现在请编写一个处理该数据集的程序,首先编写一个鸢尾花类,该类有四个私有属性:萼片长度、萼片宽度、花瓣长度和花瓣宽度。要求在创建该类对象时,必须提供四个参数作为这四个私有属性的值。
然后编写一个山鸢尾(Setosa)类,要求该类继承自鸢尾花类,并且提供一个show方法,可以打印出它从父类“继承”到的四个私有属性值。
最后在主程序中创建两个山鸢尾对象,然后调用它们的show方法,观察结果。

class 鸢尾花:
    def __init__(self,Length,Width,length,width):
        self.__Length=Length
        self.__Width=Width
        self.__length=Length
        self.__width=width
    def showall(self):
        print(self.__Length,self.__Width,self.__length,self.__width)
class 山鸢尾(鸢尾花):
    def __init__(self,L,W,l,w):
        鸢尾花.__init__(self,L,W,l,w)
    def Show(self):
        super().showall()

if __name__=='__main__':
    s1=山鸢尾(200,100,80,60)
    s2=山鸢尾(100,50,30,20)
    s1.Show()
    s2.Show()

题目:继承属性并扩展

假设开发某个游戏,需要编写以下几个类:
基本角色(Charater类)具有血量和魔法值等基础属性;
人类(Human),继承自基本角色,并拥有特殊天赋属性外交;
血精灵(BloodElf),继承自基本角色,并拥有魔法抗性;
牛头人(Tauren),拥有耐久性属性。
请编写程序让三种种族继承人物基础属性并添加自己的特殊属性。打印各个种族的特殊天赋属性

class Character:
    def __init__(self,Red,Blue):
        self.Red=Red
        self.Blue=Blue

class   Human(Character):
    def __init__(self,Red,Blue,Talk):
        super().__init__(Red,Blue)
        self.Talk=Talk

class BloodElf(Character):
    def __init__(self,Red,Blue,Defend):
        super().__init__(Red,Blue)
        self.Defend=Defend

class Tauren(Character):
    def __init__(self,Red,Blue,Hold):
        super().__init__(Red,Blue)
        self.Hold=Hold

if __name__=='__main__':
    h=Human(1000,1000,'话痨')
    b=BloodElf(500,2000,1000)
    t=Tauren(2000,500,10000)
    c=[h,b,t]
    for i in c:
        print(i.Red,i.Blue)
    print(h.Talk,b.Defend,t.Hold)

题目:调用父类方法

在某些比较耗时的程序执行过程中,软件分析师需要统计程序执行的时间。《提高篇》前面讲过:time模块的time方法可以返回当前的时间戳,通过获取代码执行前和执行后两次的时间戳之差可以计算执行的时间。
请编写一个计算类Calc,其中有一个方法calc_func,方法体是进行一个非常耗时的操作,比如用for循环计算 1 到 59999999 之间所有整数之和。
然后编写一个名为TimeTools的类,并且继承于Calc类。要求该子类重新编写calc_func方法,即覆盖了父类的该方法。
在子类的calc_func方法中调用父类的同名方法,利用time模块计算父类方法的运行时间并返回它。

import time
class Calc:
    def calc_func(self):
        res = 0
        for i in range(10000000):
            res += i
        print(res)

class TimeTools(Calc):
    def calc_func(self):
        Start=time.time()
        super().calc_func()
        End=time.time()
        print('用时',End-Start,'秒')

if __name__=='__main__':
    TT=TimeTools()
    TT.calc_func()

题目:多继承

装修公司将所有的装修服务分为几种类型:时尚类、温馨类、品味类和务实类:
时尚类具备的服务有:经济实惠型和时尚美观型。具体写成代码,就是拥有 economy 和 fashion 两个方法,分别用print打印出“经济型服务”和“时尚型服务”两个字符串。
类似的,温馨类具备学习教育服务方法(用print输出“学习教育型服务”)、品味类具备审美品味方法(用print输出“审美品味型服务”)、务实类具备家庭方法(输出“家庭聚会型服务”)。
接下来请编写三种顾客服务类型:
青年人服务类,兼具时尚类和温馨类两种服务方法;
中年人服务类,兼具温馨类和品味类方法;
老年人服务类,具备务实类服务方法。
请利用多继承编写上述各种服务类,然后实例化并试验。

class Fashion:
    def economy(self):
        return '经济实惠型服务'

    def fashion(self):
        return '时尚美观型服务'

class Warm:
    def education(self):
        return '学习教育型服务'

class Taste:
    def aesthetic(self):
        return '审美品味型服务'

class Pragmatic:
    def family(self):
        return '家庭聚会型服务'

class Young(Fashion, Warm):
    pass

class Middle(Warm, Taste):
    pass

class Old(Pragmatic):
    pass

p1 = Young();p2 = Middle();p3 = Old()
print('青年人:', p1.economy(), p1.education(), p1.fashion())
print('中年人:', p2.education(), p2.aesthetic())
print('老年人:', p3.family())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值