zoukankan      html  css  js  c++  java
  • 面向对象,特性之继承

     

    继承父类中对象和方法的语法

    class Parent:
      year = 2018
      def coding(self):
          print('coding')
       
    class Sub(Parent):
      pass
    print(Sub.year)
    s1 = Sub()
    s1.coding()
    4,继承对编程的作用
    假设有个学生管理需求:
    
    class Student:
      def __init__(self,name,age,sex):
          self.name = name
          self.age = age
          self.sex = sex
      def study(self):
          print('正在学习中')
      def eat(self):
          print('正在吃饭中')
     
    
    后续又要求添加老师管理需求:
    
    学生的属性和技能也适用于老师,此时可以引用继承,减少代码的冗余
    
    class Teacher(Student):
      pass
    t1 = Teacher('alex',30,'man')
    t1.eat()
    t1.study()

    从逻辑上来说,如果学生有打游戏的技能,而老师并没有这个需求,因此继承到了老师并不需要的技能

     

    正确姿势: 抽取公共的父类 (抽象)

    抽象 : 抽取多个类中相同得部分,形成另一个类

    把学生和老师共有的内容抽到另一个类中,学生和老师分别继承这个类,这样就避免了一个类继承到不需要的内容 因此应该先抽象,再继承

     

     

    小结:
    • 通过继承,避免了重复代码的编写。

    • 继承的作用是可以直接使用父类已有的代码

    • 通过抽象,避免了一个类继承到不需要的内容

    • 抽象的作用是存储多个子类相同的属性和技能

    • 正确地顺序应该先抽象,再继承

     

     

    派生和覆盖

    1,派生

    class Person:
    •  def __init__(self,name,age,sex):
    •      self.name = name
    •      self.age = age
    •      self.sex = sex
    ​
    •  def sayhi(self):
    •      print('hello,')
    ​
    class Student(Person):                     # 学生属于人类,可以直接继承def __init__(self,number):             # 加上一些学生特有的属性
    •      self.number = number
    ​
    •  def study(self):
    •      print('%s正在学习'%self.name)
    • 派生指某个子类继承父类,并且拥有自己独特的属性或技能

    • 该子类称之为派生类

    • 只要子类中出现任何新内容,这就是一个派生类

     

    2,覆盖

    class A:
      age = 18#age相同
      def f1(self):#f1相同
          print(" A f1" )
      passclass B(A):
      age1 = 19
      def f1(self):#f1
          self.f1()
          print(" B f1")
    ​
    b1 = B()
    print(b1.age)
    ​
    b1.f1()
    小结:
    • 子类出现了与父类重复的名字 称之为覆盖

    • 子类出现了与父类不同的名字 称之为派生

     

     

    子类访问父类的方法

    (1) 深度优先,沿着一条线找到底

    继承的父类,存在父类,则先把父类找完 ​ 这种查找方式仅仅在非菱形继承(没有共同父类)的情况下

    (2 广度优先,并非绝对的广度优先,而是基于深度的广度优先。

    先是深度优先,如果发现有共同父类,则返回。最后再查找共同父类 ​

     

     
    多重继承的菱形访问

     

    class A:
        def ping(self):
            print('ping A:', self)
    
    
    class B(A):
        def pong(self):
            print('pong B:', self)
    
    
    class C(A):
        def pong(self):
            print('PONG C:', self)
    
    
    class D(B, C):
        def ping(self):
            super().ping()
            print('post-ping D:', self)
    
        def pingpong(self):
            self.ping()
            super().ping()
            self.pong()
            super().pong()
            C.pong(self)
    D().ping()
    D().pingpong()

    mro

    method resolution order

    MRO步骤:

    1. 按照深度优先,从左到右的顺序

    2. 移除列表中的重复类型,仅保留最后一个

    3. 确保子类总在基类前面,并保留多继承定义顺序

    对 bases 的调整会直接影响 mro 的顺序

    查看访问路径

    "super访问父类内容时 按照mro列表属性查找"

    class S:
        def f1(self):
            print("s f1")
    
    class A(S):
        pass
    
    class B(S):
        def f1(self):
            print("b f1")
        pass
    
    class C(A,B):
        def f2(self):
            print("c f2")
            super().f1()
    
    
    print(C.mro())
    c1 = C()
    c1.f2()

    Tkinter GUI 类层次结构的 UML 简图

     

    
    

    组合

    • 多个对象放在一起就是组合

    • 一个对象将另一个对象作为自己的属性,就是组合 

     
    class Phone:#组合的代码
      def __init__(self,phonenumber,operator,address):
          self.phonenumber = phonenumber
          self.operator = operator
          self.address = address
    ​
      def call(self,t):
          print("%s 正在拨号 %s" % (t.name,self.phonenumber))
    ​
    
    class Person:#父类
      def __init__(self,name,sex,age):
          self.name = name
          self.sex = sex
          self.age = age
           
    class Student(Person):#子类
      def __init__(self,name,sex,age,number):
          super().__init__(name, sex, age)
          self.number = number
      def show_info(self):
          print(self.__dict__)
      def select_cursor(self):
          print("%s 正在选课...." % self.name)
           
    class Teacher(Person):#子类
      def __init__(self,name,sex,age,salary,level):
          super().__init__(name,sex,age)
          self.salary = salary
          self.level = level
      def set_score(self):
          print("%s 正在为学生打分..." % self.name)
    ​
    stu = Student("乔峰","",38,"007")
    ​
    p1 = Phone("1999999999","中国小米移动","上海浦东")
    ​
    stu.q = p1             #这里的q是变量名,相当于把p1赋值给q,通过stu来调用
    ​
    stu.q.call(stu) #不能直接stu.p1.call()
     

     

     

     

     

  • 相关阅读:
    汉语-词语:架构(计算机术语)
    汉语-词语:架构
    全世界云计算宕机和中断[2013年-2014年集锦]
    java异常处理Exception
    CodeForces 390E Inna and Large Sweet Matrix(树状数组改段求段)
    操作系统CPU调度知识点
    hp-ux 集群,内存 小记
    增强for循环、Map接口遍历、可变參数方法
    spring下载和安装
    Android设计模式(八)--模板方法模式
  • 原文地址:https://www.cnblogs.com/wang-kai-1994/p/10167198.html
Copyright © 2011-2022 走看看