zoukankan      html  css  js  c++  java
  • 类的三大特性---继承,以及类的派生

    类的继承

    • 继承是为了拿到父类的所有东西

    继承的特性

    • 减少代码的冗余
    • Python中父类和子类的对应关系是多对多
    • 使用__bases__方法获取对象继承的类
    # 父类(超类,基类)
    class FatherFoo:
        def __init__(self, first_name, money, car, house):
            self.first_name = first_name
            self.money = money
            self.car = car
            self.house = house
            
        def lixiang(self):
            print('理想')
    
    # 子类(派生类)
    class SonFoo(FatherFoo):
        pass
    
    sf = SonFoo('叶', 3000, 'feng', '9')
    print(sf.first_name)
    print(sf.money)
    print(sf.car)
    print(sf.house)
    sf.lixiang()
    print(SonFoo.__bases__)
    
    叶
    3000
    feng
    9
    理想
    (<class '__main__.FatherFoo'>,)
    

    不推荐继承多个,因为继承多个的时候,代码太混乱,最好是只继承一个父类

    • 继承后查找顺序;从自身向上查找,对象-->类-->父类
    class Foo:
        def f1(self):
            print('from Foo.f1')
            
        def f2(self):
            print('from Foo.f2')
            self.f1()		# self是obj本身,也就是b,b中没有f1,所以去到Bar找
        
        
    class Bar(Foo):
        def f1(self):
            print('Bar Foo.f1')
            
    b = Bar()
    print(b.__dict__)
    b.f2()
    
    {}
    Foo.f2
    Bar.f1
    

    类的派生

    继承中当子类也有也有自己的init时,就会发生下面的情况

    class Animal:
        def __init__(self, height, weight):
            self.height = height
            self.weight = weight
            	
        def sleep(self):
            print('睡觉了')
            
    class Dog(Animal):
        def __init__(self, name, age):
            self.name = name
            self.age = age
            
    d1 = Dog('shinubi', 3)	# 只能传入name和age
    print(d1.__dict__)
    # print(d1.height)		# 会报错
    # print(d1.weight)
    print(d1.name)
    print(d1.age)
    
    {'name': 'shinubi', 'age': 3}
    shinubi
    3
    

    这样的话就失去了继承的意义,因为继承就是要获取父类的所有属性,但这样就无法获取init里面的属性

    解决方案一:

    class Cat(Animal):
        def __init__(self, name, age):
            self.name = name
            self.age = age
            
    c1 = Cat('Tom', 2)
    Animal.__init__(c1, 50, 10)		# 把实例对象c1当成参数传入Animal的init函数中
    print(c1.__dict__)
    
    
    {'name': 'Tom', 'age': 2, 'height': 50, 'weight': 10}
    

    但是这种方法和继承无关,即便Cat类不继承Animal也一样可以做到

    解决方案二:

    • 派生:继承父类属性的同时增加新的属性,然后使用super()._init_()
    • 继承才可以使用,相当于是对方案一的一层封装
    class Animal:
        def __init__(self, height, weight):
            self.height = height
            self.weight = weight
        
        def eat(self):
            print('吃')
            
    class Felidae:
        def __init__(self, gender):
            self.gender = gender
        
        def sleep(self):
            print('睡')
            
    class Dog(Animal, Felidae):
        def __init__(self, name, age, height, weight):
            # Python3可以不用填super()中的参数,默认是填了他自己
            super().__init__(weight, height)		
            # super(Dog, self).__init__(weight, height)
            self.name = name
            self.age = age
    
    d1 = Dog('shinubi', 3, 100, 80)
    print(d1.__dict__)
    
    {'height': 80, 'weight': 100, 'name': 'shinubi', 'age': 3}
    

    这里默认是会继承第一个父类的属性,如果要继承第二个或是两个都继承,可以把代码从两个父类一个子类,调整成父类-->父类-->子类的形式。

    或者用如下方法:

    # 继承Felidae
    class Cat(Animal, Felidae):
        def __init__(self, name, age, gender):
            # 添加第一个父类,就能找到第二个,我也不知道为什么,试出来的,现在没时间查
            super(Animal, self).__init__(gender)
            self.name = name
            self.age = age
            
    c1 = Cat('Tom', 2, 'male')
    print(c1.__dict__)
    print('-' * 20)
    
    # 两个都继承
    class Cat(Animal, Felidae):
        def __init__(self, name, age, height, weight, gender):
            # 两个一起写就可以了,有没有别的办法我也不清楚,这也是试出来的
            super(Cat, self).__init__(height, weight)
            super(Animal, self).__init__(gender)
            self.name = name
            self.age = age
            
    c1 = Cat('Tom', 2, 'male')
    print(c1.__dict__)
    
    {'gender': 'male', 'name': 'Tom', 'age': 2}
    --------------------
    {'height': 50, 'weight': 10, 'gender': 'male', 'name': 'Tom', 'age': 2}
    

    类的组合

    • 将类组合在一起,解决类与类之间的代码冗余度

    • 写一个简单的选课系统

    class People:
        def __init__(self, name, gender):
            self.name = name
            self.gender = gender
            
        def eat(self):
            print(f'{self.name}开始吃了')
    
    class Student(People):
        def __init__(self, num, name, gender):
            super(Student, self).__init__(name, gender)
            
        def choose_course(self, course):
            self.course = course
            print(f'{self.name}选课{course.name}成功')
                  
    class Teacher(People):
    	def __init__(self, level, name, gender):
    		super(Teacher, self).__init__(name, gender)
            self.level = level
                  
       	def scored(self, student, course, score):
            print(f'老师{self.name}给{student.name}课程{course.name}打分{score}')
                  
    class Course:
    	def __init__(self, name, price):
            self.name = name
            self.price = price	
                
    class Admin(People):
        def create_course(self, name, price):
            course = Course(name, price)
            print(f'管理员{self.name}创建了课程{name}')
            return course
    
    # 对象创建    
    # 创建学生对象
    zhangsan = Student(1, 'zhangsan', 'male')
    lisi = Student(2, 'lisi', 'male')
                  
    # 创建老师对象
    nick = Teacher(1, 'nick', 'male')
    tank = Teacher(2, 'tank', 'male')
    
    # 创建管理员
    baba = Admin('baba', 'male')
    
    # 业务逻辑
    # 1. 创建课程
    python = baba.create_course('Python', 8888)
    linux = baba.create_course('Linux', 6666)
    print(python.__dict__)
    print(linux.__dict__)
    print('-' * 20)
    
    # 2. 学生选择课程
    zhangsan.choose_course(python)
    lisi.choose_course(linux)
    print('-' * 20)
    
    # 3. 老师给学生打分
    nick.scored(zhangsan, python, '10')
    tank.scored(lisi, linux, '30')
    print('-' * 20)
               
    
    管理员baba创建了课程Python
    管理员baba创建了课程Linux
    {'name': 'Python', 'price': 8888}
    {'name': 'Linux', 'price': 6666}
    --------------------
    zhangsan选课Python成功
    lisi选课Linux成功
    --------------------
    老师nick给zhangsan课程Python打分10
    老师tank给lisi课程Linux打分30
    --------------------
    
  • 相关阅读:
    数据导入和导出
    用户登陆案例
    SQLHelper
    把连接数据库的字符串放在配置文件中
    访问数据库
    SQL语句
    Django Tornado Flask
    Python 的协程
    面试 Better Call Soul
    mklink 解决VScode 扩展...Google迁移到 windows D盘
  • 原文地址:https://www.cnblogs.com/lucky75/p/11055050.html
Copyright © 2011-2022 走看看