美文网首页
(十二)类<3>继承

(十二)类<3>继承

作者: 费云帆 | 来源:发表于2019-01-17 08:43 被阅读0次

1.基本实例

>>> class P:
    pass

>>> class C(P):
    pass

>>> C.__base__
<class '__main__.P'>
  • 让父类做点事情
class P:
    def __init__(self):
        print("I'm a rich man!!!")

class C(P):
    pass

#建立实例的时候,首先初始化函数,这里是继承了父类的
c=C()
print(c)
>>>
I'm a rich man!!!
<__main__.C object at 0x00000000030D8B38>
  • 进一步的实例
class Person:
    
    def __init__(self,name):
        self.name=name

    def height(self,m):
        # 不要奇怪dict()的这种写法
        h=dict((["height",m],))
        return h

    def breast(self,n):
        b=dict((["breast",n],))
        return b

class Girl(Person):
    def get_name(self):
        return self.name

# 父类有初始化的参数,故子类也必须传入它
cang=Girl('Teacher Cang')
print(cang.get_name()) # Teacher Cang
print(cang.height(175)) # {'height': 175}
print(cang.breast(90)) # {'breast': 90}
  • 重写---上述实例再修改一下
class Person:
    
    def __init__(self,name):
        self.name=name

    def height(self,m):
        h=dict((["height",m],))
        return h

    def breast(self,n):
        b=dict((["breast",n],))
        return b

class Girl(Person):
    # 相同的方法,父类的会被覆盖
    # 初始化的时候,不需要再传入父类要求的值
    def __init__(self):
        # 增加属性
        self.name="Kate Green"
    def get_name(self):
        return self.name

#这么写会报错
#cang=Girl('Teacher Cang')
cang=Girl() #初始化,不再显示的传入参数,程序正常运行
print(cang.get_name()) # Kate Green
print(cang.height(175)) # {'height': 175}
print(cang.breast(90)) # {'breast': 90}

从结果中不难看出,如果子类中的方法或属性覆盖了父类(即与父类同名),那么就不在继承父类的该方法或者属性。
像这样,子类 Girl 里面有与父类 Person 同样名称的方法和属性,也称之为对父类相应部分的重写。重写之后,父类的相应部分不再被继承到子类,没有重写的部分,在子类中依然被
继承,从上面程序可以看出来此结果。

重写后,如果依然加持要使用父类的方法,可以这么写(初始化参数一样,类方法的方式调用):

class Person:
    
    def __init__(self,name):
        self.name=name

    def height(self,m):
        h=dict((["height",m],))
        return h

    def breast(self,n):
        b=dict((["breast",n],))
        return b

class Girl(Person):
    def __init__(self,name): # 这里的name是用来对接父类的name,一定不能省略
        # 这么写也可以
        # self.name=name
        # 类方法的方式调用
        Person.__init__(self,name)
        # 新增属性
        self.real_name="Kate Green"
    def get_name(self):
        return self.name


cang=Girl('Teacher Cang')
# 输出属性
print(cang.real_name) # Kate Green
print(cang.get_name()) # Teacher Cang
print(cang.height(175)) # {'height': 175}
print(cang.breast(90)) # {'breast': 90}
  • review插入升级版实例:
class Person():
    
    def __init__(self,name):
        self.name=name
    
    def get_height(self,height):
        h=dict((('Height',height),))
        return h

    def get_breast(self,breast):
        b=dict([('Breast',breast)])
        return b

class Girl(Person):
    # 区别于 def __init__(self.name):
    # 下面这么写,相当于不仅拥有父类的name属性,还额外增加了自己的属性
    def __init__(self,name,age):
        Person.__init__(self,name)
        self.age=age

    def get_age(self):
        return self.age
# 初始化传参要注意多传入一个age
g=Girl(name='Kate Green',age=20)
print(g) # <__main__.Girl object at 0x00000000030D7C18>
print(g.name) # Kate Green
print(g.age) # 20
print(g.get_height(175)) # {'Height': 175}
print(g.get_breast(39)) # {'Breast': 39}

  • 神奇的super,接上面实例
    super()实际就是代表父类,只不过调用的方法不再需要传入self,使代码看上去更加简洁.
class Person:
    
    def __init__(self,name):
        self.name=name

    def height(self,m):
        h=dict((["height",m],))
        return h

    def breast(self,n):
        b=dict((["breast",n],))
        return b

class Girl(Person):
    def __init__(self,name):
        # Person.__init__(self,name)
        # super().__init__(name)
        super(Girl,self).__init__(name) #这行的效果相当于上面任意一行
        self.real_name="Kate Green"
    def get_name(self):
        return self.name


cang=Girl('Teacher Cang')
print(cang.real_name) # Kate Green
print(cang.get_name()) # Teacher Cang
print(cang.height(175)) # {'height': 175}
print(cang.breast(90)) # {'breast': 90}
  • review,对super的应用再来一个自己的实例:
class Foo:
    def test_func(self,x):
        return x

class Bar(Foo):
    # 保留父类的参数,并且额外添加自己的参数
    def test_func(self,x,y):
        super().test_func(x)
        return (x,y)
#print(Foo().test_func(1))
print(Foo.test_func(Foo(),1)) # 1
print(Bar().test_func(1,2)) # (1,2)

  • 下面的实例,是对上面例子的综合运用
class FooParent:
    def __init__(self):
        self.parent = 'I\'m the parent.'
        print ('Parent')
    
    def bar(self,message):
        print ("{} from Parent".format(message))
 
class FooChild(FooParent):
    def __init__(self):
        # super(FooChild,self) 首先找到 FooChild 的父类(就是类 FooParent),然后把类B的对象 FooChild 转换为类 FooParent 的对象
        #FooParent.__init__(self)
        super(FooChild,self).__init__()# 调用父类的初始化方法
        print ('Child')
        
    def bar(self,message):
        # FooParent.__init__(self).bar(message)
        super(FooChild, self).bar(message)
        print ('Child bar fuction')
        print (self.parent)
 
if __name__ == '__main__':
    fooChild = FooChild()
    fooChild.bar('HelloWorld')
>>>
Parent
Child
HelloWorld from Parent
Child bar fuction
I'm the parent.

2.多态,基础实例

class Person:
    
    def eye(self):
        print("Two eyes.")

    def breast(self,n):
        print("The breast is {}".format(n))

class Girl:

    age=28
    
    def color(self):
        print("The girl is white.")
        
# 多态继承两个类
class HotGirl(Person,Girl):
    pass #虽然什么都没有,调用父类的方法木问题

if __name__=='__main__':

    cang=HotGirl() 
    cang.eye() # Two eyes.
    cang.breast(90) # The breast is 90
    cang.color() # The girl is white.
    # 属性也被继承
    print(cang.age) # 28

3.多重继承,广度优先:

class K1:
    def foo(self):
        print("I'm in K1-foo()")
class K2:
    def foo(self):
        print("I'm in K2-foo()")
    def bar(self):
        print("I'm in K2-bar()")
class J1(K1,K2):
    pass
class J2(K1,K2):
    def bar(self):
        print("I'm in J2-bar()")
class C(J1,J2):
    pass

if __name__=='__main__':
    # (<class '__main__.C'>, <class '__main__.J1'>, <class '__main__.J2'>, <class '__main__.K1'>, <class '__main__.K2'>, <class 'object'>)
    # 打印继承的顺序
    # 可以看出,继承的顺序是这样的:
    # C==>J1==>J2==>K1==>K2
    print(C.__mro__)
    m=C()
    # C==>J1==>J2==>K1,C,J1,J2都没有foo(),到了K1,有了,于是调用K1.foo()
    m.foo() # I'm in K1-foo()
    # C==>J1==>J2,同理,调用J2.bar()
    m.bar() # I'm in J2-bar()

相关文章

  • (十二)类<3>继承

    1.基本实例 让父类做点事情 进一步的实例 重写---上述实例再修改一下 重写后,如果依然加持要使用父类的方法,可...

  • 面向对象特性------继承

    1,为什么要设计继承? 2,通过 " class A extends B " 类实现类的继承。 3,子类继承父类以...

  • js的继承方式

    1 类式继承 子类的原型对象 2 构造函数继承 创建即继承 3 组合继承 (类式继承和构造函数...

  • 继承、重写、面向对象、类、私有属性、多态的基本知识

    单继承 1. 类默认要继承 (object) 2. 子类继承通过(父类)完成 3. 子类继承父类的非私有 属性 和...

  • C#面向对象继承学习笔记(1)

    1.当类没有继承于其它类时,都继承于object类;object类是所有类的基类。2.继承方法: 例: 3.new...

  • 继承与派生

    1,父类与子类,单继承与多继承 2、为何要用继承:用来解决类与类之间代码冗余问题 3,如何实现继承 4,属性查找 ...

  • Object-C继承与初始化方法

    一、继承 1. 继承的上层:父类(或超类) 继承的下层:子类 2. 继承是单向的,两个类之间不能互相继承 3. 继...

  • 继承

    一. 单继承 继承的概念一般子女继承父辈 2.多继承 3.重写、调用父类方法 二. 静态方法和类方法 1、类方法 ...

  • Swift学习笔记九之继承

    1、继承:一个类可以继承另一个类的方法,属性及其它特征 2、子类还可以被其他类继承 3、重写:子类可以对继承自父类...

  • Java中的继承

    继承 继承的概念: 继承是类与类的一种关系,是一种“is a”的关系 注:Java中的继承是单继承 3. 继承的好...

网友评论

      本文标题:(十二)类<3>继承

      本文链接:https://www.haomeiwen.com/subject/mwsbdqtx.html