zoukankan      html  css  js  c++  java
  • Python 继承

    继承

    • 实现继承, 可以通过"继承"(Inheritance) 和 "组合"(Composition) 来实现. 
    • 在某些语言中, 一个子类可以继承多个基类, 但是一般情况下, 一个子类只能有一个基类, 要实现多重继承,可以通过多级继承来实现.

    继承概念的实现方式主要有两类:

    • 实现继承
      • 实现继承是指使用基类的属性和方法而无需额外编码的能力
    • 接口继承
      • 接口继承是指仅使用属性和方法的名称, 但是子类必须提供实现的能力(子类重构父类方法)
    • 注意:
      • 在考虑使用继承时, 有一点需要注意, 两个类之间的关系应该是"属于"关系. 例如, employee是一个人, manager也是一个人. 因此这两个类都可以继承person类, 但是leg却不能继承person类.
      • 抽象类仅定义将由子类创建的一般属性和方法

    OO开发范式大致为:

    • 划分对象 -> 抽象类 -> 将类组织成为层次化结构(继承和合成) -> 用类与实例进行设计和实现几个阶段
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    
    # 直接继承父类方法
    class Person(object):
        def talk(self):
            print("person is talking")
    
    
    class BlackPerson(Person):
        pass
    
    
    b = BlackPerson()
    b.talk()
    
    
    # 子类自己有独有方法
    class Person(object):
        def talk(self):
            print("person is talking")
    
    
    class BlackPerson(Person):
        def walk(self):
            print("BlackPerson is walking")
    
    
    b = BlackPerson()
    b.talk()
    b.walk()
    
    
    # 子类重写父类方法
    class Person(object):
        def talk(self):
            print("person is talking")
    
    
    class BlackPerson(Person):
        def talk(self):
            print("BlackPerson is talking")
    
        def walk(self):
            print("BlackPerson is walking")
    
    
    b = BlackPerson()
    b.talk()
    b.walk()
    
    
    # 传参
    class Person(object):
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def talk(self):
            print("person is talking")
    
    
    class BlackPerson(Person):
        def talk(self):
            print("BlackPerson is talking")
    
        def walk(self):
            print("BlackPerson is walking")
    
    
    class WhitePerson(Person):
        pass
    
    
    b = BlackPerson("will smith", 30)
    b.talk()
    b.walk()
    
    
    # 先继承,再重构
    class Person(object):
        def __init__(self, name, age):
            self.name = name
            self.age = age
            self.sex = "normal"
    
        def talk(self):
            print("person is talking")
    
    
    class BlackPerson(Person):
        def __init__(self, name, age, strength):   # 先继承,再重构
            Person.__init__(self, name, age)  # 把子类实例传到父类(父类引用指向子类对象)
            print(self.name, self.age, self.sex)
            print(strength)
    
        def talk(self):
            print("BlackPerson is talking")
    
        def walk(self):
            print("BlackPerson is walking")
    
    
    class WhitePerson(Person):
        pass
    
    
    b = BlackPerson("will smith", 30, "strong")
    b.talk()
    b.walk()
    继承

    多继承

    • 一个子类有多个父类
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    
    """
    命名规范:
    1. 类名每个单词都要首字母大写
    2. 类名下面要写注释
    """
    
    
    class SchoolMember(object):
        """
        学校成员基类
        """
        member = 0
    
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
            self.enroll()
    
        def enroll(self):
            """
            注册
            :return:
            """
            print("just enrolled a new school memeber [%s]" % self.name)
            # self.member += 1  # 每新注册一个, 成员数加1. 这样写只是当前子类成员数加1;要想父类SchoolMember总成员数加1, 需得加到全局变量里.
            SchoolMember.member += 1
    
        def tell(self):
            print('------------%s info ----------' % self.name)
            for k, v in self.__dict__.items():  # __dict__方法可以打印出类的所有变量
                print("	", k, v)
            print("end".center(33, "-"))
    
        def __del__(self):
            print("开除了[%s]" % self.name)
            SchoolMember.member -= 1
    
    
    class School(object):
        """
        假装是另一个社团团员类(以便Teacher和Student能继承;否则School是个组织, Teacher/Student是不能继承的)
        """
        def open_branch(self, addr):
            print("opening new branch in ", addr)
    
    
    class Teacher(SchoolMember, School):  # 多继承
        """
        讲师类
        """
        def __init__(self, name, age, sex, salary, course):
            # SchoolMember.__init__(self, name, age, sex)  # 继承父类变量写法1. 又称经典类写法.
            super(Teacher, self).__init__(name, age, sex)  # 继承父类变量写法2. 又称新式类写法.
            self.salary = salary
            self.course = course
            # self.enroll()  # enroll()方法在每个子类里都需要, 可以直接写在父类里
    
        def teaching(self):
            print("Teacher [%s] is teaching [%s]" %(self.name, self.course))
    
    
    class Student(SchoolMember):
        def __init__(self,name, age, sex, course, tuition):
            SchoolMember.__init__(self, name, age, sex)
            self.course = course
            self.tuition = tuition  # fee
            # self.enroll()  # enroll()方法在每个子类里都需要, 可以直接写在父类里
            self.amount = 0
    
        def pay_tuition(self, amount):
            print("student [%s] has just paid [%s]" %(self.name, amount))
            self.amount += amount
    
    
    t1 = Teacher("WuSir", 28, "FM", 3000, "Python")
    s1 = Student("HaiTao", 38, "M", "Py15", 300000)
    s2 = Student("LiChuang", 12, "M", "Py15", 11000)
    
    print(SchoolMember.member)
    t1.tell()
    s1.tell()
    t1.open_branch("SH")
    继承进阶

    经典类 VS 新式类

    • 写法的不同
      • 经典类继承父类变量用ParentClass.__init__;   新式类继承父类变量用super()
    • 多继承时继承顺序的不同
      • python3 没有不同, 经典类和新式类都是广度查找
      • python2 : 经典类深度查找; 新式类广度查找
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    
    """
    写法不同:
    1. 新式类: super
    2. 经典类: ParentClass.__init__
    现在都主要写新式类
    """
    
    
    class Person(object):  # new style 新式类. 注: 括号里的object是一个基类.
        super(Person, self).__init__()  # init括号里写父类的全部变量名
    
    
    class Person:  # classical style 经典类
        ParentClass.__init__()  # init括号里写父类的全部变量名
    
    
    
    """
    多继承时继承顺序的区别 : 
    1. python3中无区别, 都是广度查找; 
    2. python2中有区别(经典类: 深度查找. 若B注掉, 不会去找C,而是直接找A.A没有才再找回C; 新式类: 广度查找.)
    """
    
    
    class A(object):
        def __init__(self):
            self.n = "A"
    
    
    class B(A):
        def __init__(self):
            self.n = "B"
    
    
    class C(A):
        def __init__(self):
            self.n = "C"
    
    
    class D(B, C):  # 广度查找: 先把B,C找完, 找不到再找A; 深度查找: 找不到B, 直接去找A而不是C, A没有才找C.
        # def __init__(self):
            # self.n = "D"  # 若打印print(d.n), 返回D. 就近原则
            pass  # 若打印print(d.n), 返回B
    
    
    d = D()
    print(d.n)
    经典类VS新式类
  • 相关阅读:
    XHTML基础问答-给初学者
    动态改变表格的行数列数(添加表格)
    记录的添加,修改,删除等操作,??
    数据绑定
    优秀ASP.NET程序员修炼之路
    关于Command的ExecuteNonQuery(),ExecuteScalar(),ExecuteReader方法的区别
    MyEclipse7.5注册
    实用JavaScript代码库
    解决数据库录入中文数据乱码问题
    Oracle占用8080端口问题的解决
  • 原文地址:https://www.cnblogs.com/cheese320/p/9171751.html
Copyright © 2011-2022 走看看