面向对象(二)——继承、派生、组合以及接口

一、继承与派生

1.1 什么是继承

继承是一种创建新类的方式,在Python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类

Python中类的继承分为:单继承和多继承

class People:    # 定义父类
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def walk(self):
            print(‘%s is walking‘ %self)
class Teacher(People):    # 单继承,基类是People,派生类是Teacher
    pass
class Student(People):    #  单继承,基类是People,派生类是Student
    pass
t=Teacher(‘egon‘,18)
print(t.name,t.age)
print(t.__dict__)
t.walk()

需要注意圆括号中基类的顺序,若是基类中有相同的方法名,而在子类使用时为指定,Python从左至右搜索即方法在子类中未找到时,从左到右查找基类中是否包含方法。

如果没有指定基类,Python的类会默认继承object类,object是所有Python类的基类,它提供了一些常见方法如(__str__)的实现

BaseClassName(示例中的基类名)必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用:

class DerivedClassName(modname.BaseClassName):

单继承实例:

#类定义
class people:
    #定义基本属性
    name = ‘‘
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))
#单继承示例
class student(people):
    grade = ‘‘
    def __init__(self,n,a,w,g):
        #调用父类的

二、多继承

class People:    # 定义父类
    pass
class Animal:    # 定义父类
    pass
class Student(People,Animal):    # 定义子类
    pass

print(Student.__bases__)
print(People.__bases__)
print(Animal.__bases__)

在Python3中,所有类默认继承object

但凡是继承了object类的子类,以及该子类的子类,都称为新式类(在Python3中所有的类都是新式类)

没有继承object类的子类成为经典类(在Python2中,没有继承object的类,以及它的子类,都是经典类)

继承的好处:

解决代码重用的问题,减少代码冗余

继承是一种什么‘是’什么的关系    # 比如:人是动物

继承与派生

class People:    # 定义父类
    # 定义构造方法
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    def walk(self):
        print(‘%s is walking‘ %self.name)
    def foo(self):
        print(‘from father %s‘ %self.name)

class Teacher(People):    # 定义派生(子类)
    school=‘oldboy‘    # 定义基本属性
    def __init__(self,name,age,sex,level,salary):    # 定义构造方法
        People.__init__(self,name,age,sex)
        self.level=level
        self.salary=salary
    def teach(self):
        print(‘% is teaching‘ %self.name)
    def foo(self):
        People.foo(self)
        print(‘from teacher‘)

class Student(People):    # 定义派生(子类)
    def __init__(self,name,age,sex,group):    # 定义构造方法
        People.__init__(self,name,age,sex)    # 调用父类的构函
        self.group=group
    def study(self):
        print(‘% is studying %self.name‘)

t=Teacher(‘egon‘,18,‘male‘,10,10000)    # 实例化对象
s=Student(‘wocao‘,22,‘male‘,12)    # 实例化对象
print(t.__dict__)
print(s.__dict__)
t.foo()

三、组合

软件重用的重要方式除了继承之外还有另外一种方式,即:组合

组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合

class Date:
    def __init__(self,year,mon,day):
        self.year=year
        self.mon=mon
        self.day=day
    def tell_brith(self):
        print(‘出生于<%s>年 <%s>月 <%s>日‘ %(self.year,self.mon,self.day))

class Teacher:
    def __init__(self,name,age,year,mon,day):
        self.name=name
        self.age=age
        self.brith=Date(year,mon,day)
    def teach(self):
        print(‘%s is teaching‘ %self.name)

class Stdent:
    def __init__(self,name,age,year,mon,day):
        self.name=name
        self.age=age
        self.brith=Date(year,mon,day)
    def study(self):
        print(‘%s is studying‘ %self.name)

t=Teacher(‘egon‘,18,1999,1,8)
print(t.name,t.age)
print(t.brith)
print(t.brith.year)
print(t.brith.mon)
print(t.brith.day)
t.brith.tell_brith()

组合与继承都是有效地利用已有类的资源的重要方式。但是二者的概念和使用场景皆不同,

1.继承的方式

通过继承建立了派生类与基类之间的关系,它是一种是的关系,比如白马是马,人是动物。

当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如教授是老师

>>> class Teacher:
...     def __init__(self,name,gender):
...         self.name=name
...         self.gender=gender
...     def teach(self):
...         print(‘teaching‘)
...
>>>
>>> class Professor(Teacher):
...     pass
...
>>> p1=Professor(‘egon‘,‘male‘)
>>> p1.teach()
teaching

  

2.组合的方式

用组合的方式建立了类与组合的类之间的关系,它是一种有的关系,比如教授有生日,教授教Python课程

class BirthDate:
    def __init__(self,year,month,day):
        self.year=year
        self.month=month
        self.day=day

class Couse:
    def __init__(self,name,price,period):
        self.name=name
        self.price=price
        self.period=period

class Teacher:
    def __init__(self,name,gender):
        self.name=name
        self.gender=gender
    def teach(self):
        print(‘teaching‘)

class Professor(Teacher):
    def __init__(self,name,gender,birth,course):
        Teacher.__init__(self,name,gender)
        self.birth=birth
        self.course=course

p1=Professor(‘egon‘,‘male‘,
             BirthDate(‘1995‘,‘1‘,‘27‘),
             Couse(‘python‘,‘28000‘,‘4 months‘))
print(p1.birth.year,p1.birth.month,p1.birth.day)
print(p1.course.name,p1.course.price,p1.course.period)
‘‘‘
运行结果:
1 27
python 28000 4 months
‘‘‘

当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好

四、接口与归一化设计

1.什么是接口

继承有两种用途:

一:继承基类的方法,并且做出自己的改变或者扩展(代码重用)

二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能

class Interface:#定义接口Interface类来模仿接口的概念,python中压根就没有interface关键字来定义一个接口。
    def read(self): #定接口函数read
        pass
    def write(self): #定义接口函数write
        pass
class Txt(Interface): #文本,具体实现read和write
    def read(self):
        print(‘文本数据的读取方法‘)
    def write(self):
        print(‘文本数据的读取方法‘)
class Sata(Interface): #磁盘,具体实现read和write
    def read(self):
        print(‘硬盘数据的读取方法‘)
    def write(self):
        print(‘硬盘数据的读取方法‘)
class Process(Interface):
    def read(self):
        print(‘进程数据的读取方法‘)
    def write(self):
        print(‘进程数据的读取方法‘)

继承的第二种含义非常重要,它又叫“接口继承”。

接口继承实质上要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。

五、抽象类

1、什么是抽象类?

抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

2、为什么要有抽象类?

如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性。

3、在Python中实现抽象类

# 父类要限制
# 1 子类必须要有父类的方法
# 2 子类实现的方法必须跟父类的方法的名字一样
import abc    # 利用abc模块实现抽象类

class File(metaclass=abc.ABCMeta):
    @abc.abstractmethod    # 定义抽象类方法,无需实现功能
    def read(self):
        ‘子类必须定义读功能’
        pass
    @abc.abstractmethod

    def writh(self):
        ‘子类必须定义写功能’
        pass

class Txt(File):    # 子类继承抽象类,但是必须定义read和write方法
    def read(self):    # read方法,如果子类没有定义抽象方法,则报错
        pass
    def writh(self):    # write方法,和上面一样
        pass
t=Txt()

4、抽象类本质还是类,指的是一组类的相似性,包括数据属性和函数属性,而接口只强调函数属性的相似性。

抽象类是一个介于类和接口直接的一个概念,同时具备类和接口的部分特性,可以用来现实归一化设计

六、继承实现的原理(继承顺序)

1 继承顺序

class A(object):
    def test(self):
        print(‘from A‘)

class B(A):
    def test(self):
        print(‘from B‘)

class C(A):
    def test(self):
        print(‘from C‘)

class D(B):
    def test(self):
        print(‘from D‘)

class E(C):
    def test(self):
        print(‘from E‘)

class F(D,E):
    # def test(self):
    #     print(‘from F‘)
    pass
f1=F()
f1.test()
print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性
#新式类继承顺序:F->D->B->E->C->A
#经典类继承顺序:F->D->B->A->E->C
#python3中统一都是新式类
#pyhon2中才分新式类与经典类
继承顺序

  

2、继承原理

python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如

>>> F.mro() #等同于F.__mro__
[<class ‘__main__.F‘>, <class ‘__main__.D‘>, <class ‘__main__.B‘>, <class ‘__main__.E‘>, <class ‘__main__.C‘>, <class ‘__main__.A‘>, <class ‘object‘>]

mro只在新式类中有

子类调用父类的方法

super()函数,调用父类的绑定方法

class People:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    def foo(self):
        print(‘from parent‘)

class Teacher(People):
    def __init__(self,name,age,sex,salary,level):
        # People.__init__(self,name,age,sex)    # 指名道姓地调用People类的__init__函数

        # 在Python3中
        super().__init__(name,age,sex)  # 调用父类的__init__的功能,实际上用的是绑定方法,只能调用一次父类

        # 在Python2中
        # super(Teacher,self).__init__(name,age,sex)
        self.salary=salary
        self.level=level
    def foo(self):
        super().foo()
        print(‘from child‘)
t=Teacher(‘egon‘,18,‘male‘,3000,10)
t.foo()

方法一:父类名.父类方法()

方法二:super()

时间: 2024-07-29 15:32:56

面向对象(二)——继承、派生、组合以及接口的相关文章

面向对象二 — — 继承、抽象类、接口

一.继承 extends 继承的特点:Java的继承通过extends关键字来实现,实现继承的类被称为子类,被继承的类称为父类 1.参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载. 2.返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载. 3.访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private) 4.重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常. 用supe

面向对象--多继承&amp;派生类对象内存布局分析&amp;各基类指针所指向的位置分析

背景 原文链接:ordeder  http://blog.csdn.net/ordeder/article/details/25477363 关于非虚函数的成员函数的调用机制,可以参考: http://blog.csdn.net/yuanyirui/article/details/4594805 成员函数的调用涉及到面向对象语言的反射机制. 虚函数表机制可以查看下面这个blog: http://blog.csdn.net/haoel/article/details/1948051 总结为: 其一

面向对象的继承与组合

面向对象的优势在于类的复用.继承与多态都是对类进行复用,它们是一个类级别的复用,一个是方法级别的复用.提到继承必提组合,二者有何异同?PHP到底有没有多态?若没有,则为什么没有?有的话,和其他语言中的多态又有什么区别? 继承和组合都是提高代码可重用性的手段.在设计模型时,可以按照语言识别类之间的组合关系和继承关系. 从方法复用的角度考虑,如果两个类中有很多相同的代码和方法,可以从这两个类中抽象出一个父亲,提供公共方法,然后两个类作为子类,提供个性方法. 这时继承语义更好. 而组合就没有这么多限制

Golang OOP、继承、组合、接口

http://www.cnblogs.com/jasonxuli/p/6836399.html 传统 OOP 概念 OOP(面向对象编程)是对真实世界的一种抽象思维方式,可以在更高的层次上对所涉及到的实体和实体之间的关系进行更好的管理. 流传很广的OOP的三要素是:封装.继承.多态. 对象:可以看做是一些特征的集合,这些特征主要由 属性 和 方法 来体现. 封装:划定了对象的边界,也就是定义了对象. 继承:表明了子对象和父对象之间的关系,子对象是对父对象的扩展,实际上,子对象"是"父对

继承,派生,组合

1 .继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类 1 class People: 2 pass 3 class Animal: 4 pass 5 class Student(People,Animal):#people ,Animal 是父类(基类),Student是子类(派生类) 6 pass 7 print(Student.__bases__)#(<class '__main__.People'>, &

JS 面向对象之继承--多种组合继承

转自 http://www.cnblogs.com/yangjinjin/archive/2013/02/01/2889563.html 这一次要讲 组合.原型式.寄生式.寄生组合式继承方式. 1. 组合继承:又叫伪经典继承,是指将原型链和借用构造函数技术组合在一块的一种继承方式. 下面来看一个例子: function SuperType(name) { this.name = name; this.colors = ["red", "blue", "gr

Python基础(16)_面向对象程序设计(类、继承、派生、组合、接口)

一.面向过程程序设计与面向对象程序设计 面向过程的程序设计:核心是过程,过程就解决问题的步骤,基于该思想设计程序就像是在设计一条流水线,是一种机械式的思维方式 优点:复杂的问题的简单化,流程化 缺点:扩展性差 面向对象的程序设计:核心是对象,对象是特征(变量)与技能(函数)的结合体,是一种上帝式的思维方式 优点:解决了程序的扩展性 缺点:可控性差 二.类和对象 以游戏举例,基于面向对象设计一个款游戏:英雄联盟,每个玩家选一个英雄,每个英雄都有自己的特征和和技能,特征即数据属性,技能即方法属性,特

Python开发基础-Day18继承派生、组合、接口和抽象类

类的继承与派生 经典类和新式类 在python3中,所有类默认继承object,但凡是继承了object类的子类,以及该子类的子类,都称为新式类(在python3中所有的类都是新式类) 没有继承object类的子类成为经典类(在python2中,没有继承object的类,以及它的子类,都是经典类) 1 class People: 2 pass 3 class Animal: 4 pass 5 class Student(People,Animal): #People.Animal称为基类或父类,

python基础之继承派生、组合、接口和抽象类

类的继承与派生 经典类和新式类 在python3中,所有类默认继承object,但凡是继承了object类的子类,以及该子类的子类,都称为新式类(在python3中所有的类都是新式类) 没有继承object类的子类成为经典类(在python2中,没有继承object的类,以及它的子类,都是经典类) 1 class People: 2 pass 3 class Animal: 4 pass 5 class Student(People,Animal): #People.Animal称为基类或父类,