类的继承、派生、组合、菱形的继承、多态

类的继承

继承是一种新建的类的方式,新建的类成为子类,被继承的类称为父亲

继承的特性是:子类会遗传父亲的属性

继承是类与类之间的关系

使用继承目的,可以减少代码的咒余

在python中,父类和子类只有在继承的时候才会产生

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

class Parent_Foo:
    def __init__(self,first_name,money,car,house)
    self.first_name = first_name
    self.car = car
    self.house =house
    self.money = money*0.5
    print('继承的财产扣掉一办')
    
    def find_wife(self):
		print(f'{self.first_name}先生找到妻子白富美‘)

              
class Son_Foo(Parent_Foo)
      pass
              
sf= Son_FOO('二','1000','tesla','上海汤臣一品')
print(sf.first_name)
print(sf.money)
print(sf.car)
sf.find_wife()
#二
#500.0
#tesla
#上海汤臣一品1栋
#二先生找到妻子白富美              
class Animal():
	def __init__(self,height,weight)
    	self.height = height
        self.weight =weight
    def jiao(self):
        print(self.__class__.__name__,'叫')
        
        
class Xingxing():
    def sleep(self):
        print('睡觉')
        
class People(Animal,Xingxing):
	def read(self):
		print('read')
    
    def jiao(self)
    	print('jiao')
        
        
aobama = People(170,140)
aobama = jiao()
#jiao
aobama = sleep()
#睡觉
meixi = People(168,140)
meixi.jiao()
#jiao


class Dog(Animal):
    def eat_shi(self):
        print('eat_shi')
        
shinubi = Dog(40,50)
shinubi.jiao()
# Dog 叫
==# 不推荐使用继承,当你继承多个的时候,功能与功能之间会混乱,顶多继承一
个
# 继承后查找顺序:先自己,在类,在父类,在父类,在父类的父类==
class Foo:
    def f1(self)
    	print('Foo.f1')
        
    def f2(self)			# self =b
    	print('Foo.f2')
        self.f1()			#b.f1()
        
        
class Bar(Foo):
    def f1(self)
    	print('Bar.f1')
        
        
        
b = Bar()
#{}
print(b.__dict__)
# Foo.f2
b.f2()
# Bar.f1


类的派生

  • 派生:子类中新定义的属性的这个过程叫做派生,并且需要记住子类在使用派生的属性始终是以自己的为准
  • 指明道姓访问某一个类的函数:该方式与继承无关
#派生方法一:
class OldboyPeople:
    '''由于学生和老师都是人,因此人都有姓名,年龄,性别'''
    school ='oldboy'
    
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age 
        self.gender =gender
        
class OldboyStudent(OldboyPeople):
    """由于学生类没有独立的__init__()方法,因此不需要声明继承父类的__init__方法,会自动生成"""
    def chooser_course(self):
        print('%s is choosing course' %self.name)
        
class OldboyTeacher(OldboyPeople):
    """由于老师类有独自的__init__()方法,因此需要声明继承父类的__init__()"""
    def __init__(self,name,age,gender,level):
		OldboyPeople.__init__(self,name,age,gender)
        self.level=level
        
    def score(self,stu_obj,num)
    	print('% is scoring'% self.name)
        stu_obj.score = num
        

stu1 = OldboyStudent('tank',18,'male')
tea1 = OldboyTeacher('nick','18','male',10)

print(stu1.__dict__)
#{'name': 'tank', 'age': 18, 'gender': 'male'}


print(tea1.__dict__)
{'name': 'nick', 'age': 18, 'gender': 'male', 'level': 10
  • 严格以来继承属性查找关系
  • super()会得到一个特殊的对象,该对象就是专门用来访问父类中的属性的(按照继承关系来的)
  • super().init(不用为self传值)
  • super 的完整用法就是super(自己的类名,self),在python2中需要写完整,在python3中口蹄疫简写为super()
#派生方法二:
class OldboyPeolpe:
    school ='oldboy'
    
    def __init__(self,name,age,aex)
    	self.name =name
        self.age = age
        self.sex = sex
        
class OldboyStudent(OldBboyPeople):
    def __init__(self,name,age,sex,stu_id):
        super().__init__(name,age,sex)
        self.stu_id = stu_id
        
    def choose_course(self):
        print('%s is choosing course'% self.name)
        
stu1 = OldboyStudent('tank',19,'male',1)

print(stu1.__dict__)

#{'name': 'tank', 'age': 19, 'sex': 'male', 'stu_id': 1}

类的组合

  • 组合就是一个类的对象具备爱某一个属性,该属性的值是指向另一个类的对象
  • 组合是用来解决类与类之间代码咒余的问题
  • 组合可以理解成多个人去造一个机器人,有的人造头,有的人造身体,手,大家完工后,最后机器人造出来了
#简单的选课系统
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,student_id,name,gender):
        self.student_id = student_id
        super(Student,self).__init__(name,gender)
        
    def choose_course(self,course):
        self.course = course
        print(f'{self.name}选课{course.name}成功)
              
              
def Teacher(People):
    def __init__(self,level,name,gender):
         self.level = level
         super(Teacher,self).__init__(name,gender)
         
    def scored(self,student,course,score):
        print(f'老师{self.name}给{student.name}课程{course.name}打分{score})
              
              
def Course:
     def __init__(self,name,price):
          delf.name =name
          delf.price =price
              
              
def Admin(People):
      def create_course(self,name,price):
          course = Course(name,price)
          print(f'管理员{self.name}创建了课程{name}')
          return course
              
#课程
#python = Course('Python','888')
#linux = Course('Linux','666')
              
#学生
zhubajie  =Student('01','zhubajie','male')
sunwukong = Student('02','sunwukong','male')
              
# 老师
nick = Teacher('1','nick','male')
tank =Teacher('2','tank','male')

              
#管理员
egon  =Admin('egon','male')
              
              
              
# 业务逻辑
*1创建课程
python = egon.create_course('python','8888')
print(python.__dict__)              
==管理员egon创建了课程python
{'name': 'python', 'price': '8888'}
              
              
linux = egon.create_course('linux','6666')
print(linux.__dict__)              
==管理员egon创建了课程linux
{'name': 'linux', 'price': '6666'}            
              
*2学生选择课程
zhubajie.choose_corse(python)
              
==zhubajie选课python成功              
              
*3老师给学生打分
nick.scored(zhubajie,python,'0')              
              
==老师nick给zhubajie课程python打分0             

菱形的继承

经典类 和新式类

在python3 当中 会默认继承object类

在python2 当中 不会默认继承object类,必须得自己手动添加

新式类:只要继承了object类的就是新式类,在python3当中所有的类都是新式类

经典类:没有继承object类的就是经典类,只要python2当中有经典类

当继承为菱形继承的时候,经典类和新式类的搜索某一个属性的循序会不一样的

  • 经典类下:深度优先
  • 新式类下:广度优先
  • 经典类:一条路走到黑,深度优先

类的多态与多态性

多态指的是一类事物有多种形态

  • 序列数据类型有多种形态:字符串,列表,元祖
  • 动物有多种形态:人,狗,猪
#动物有多种形态:人类,猪,狗
def Animal:
    def run(self):          #子类约定俗成的必须实现这个方法
        raise AttributeError	('子类必须实现这个方法')
        
        
class People(Animal):
    def run(self):
        print('人在走')
        
class Pig(Animal):
    def run(self):
        print('Pig is walking')

class Dog(Animal):
    def run(self):
        print('dog is running')
        
peo1 =People()
pig1 =Pig()
d1 = Dog()


peo1.run()
#人在走
pig1.run()
#pig is walking
d1.run()
#dog is runing
import abc

class Animal(metaclass=abc.ABCMeta):  # 同一类事物:动物
    @abc.abstractmethod  # 上述代码子类是约定俗称的实现这个方法,加上@abc.abstractmethod装饰器后严格控制子类必须实现这个方法
    def talk(self):
        raise AttributeError('子类必须实现这个方法')


class People(Animal):  # 动物的形态之一:人
    def talk(self):
        print('say hello')


class Dog(Animal):  # 动物的形态之二:狗
    def talk(self):
        print('say wangwang')


class Pig(Animal):  # 动物的形态之三:猪
    def talk(self):
        print('say aoao')


peo2 = People()
pig2 = Pig()
d2 = Dog()

peo2.talk()
#say hello
pig2.talk()
#say aoao
d2.talk()
# wangwang

多态性

注意:多态与多态性非等同

多态性是指具有不停功能得函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容的函数。在面向对象的方法中一般是这样表述多态性:向不同的对象发送同一条信息,不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去相应共同的消息,所谓消息,就是调用函数,不同的行为就是指不同的时间,即执行不同的函数

多态性的好处

  • 1,增加了程序的灵活性:以不变应万变,不论对象千遍万遍,使用者都是同一种形式调用,如 func
  • 2,增加了程序额的可扩展性:通过集成Animal类创建了一个新的类,使用者无法更新自己的代码,还是用func(animal)去调用
原文地址:https://www.cnblogs.com/zhuyuanying123--/p/11056477.html