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

    一、什么是继承

    继承是一种关系,描述两个对象之间,什么是什么的关系。就是两个类之间有什么关联,可以用到相同的属性或者方法。

    例如a继承了b,a就能直接使用b已经存在的方法和属性。

    a称之为子类,b称之为父类,也称之为基类。

    二、为什么要使用继承

    继承的一方可以直接使用被继承一方已经有的东西,其目的是为了重用已经写好的代码,提高重用性。

    三、如何使用继承

    语法:

    class   类名称(父类的名称):
               类的内容
    
    #在python中  一个子类可以继承多个父类    后面的菱形继承有总结

    四、抽象的概念

    这个抽象不是指我们平常描述中说的模糊不清的,不具体的概念。

    这里是将多个子类中相同的部分,进行抽取,形成一个新的类,这个过程也称之为抽象的过程。

    正确的使用继承方法:

    1.先抽象再继承

    2.继承一个已经存在的类,扩展或是修改原始的功能

    五、属性的查找顺序

    对象自己的  >>> 所在类中  >>>  找父类  >>>  父类的父类   >>>object

    六、派生  (这个只是一个要记住的知识点,平常我们都会这样写,只是不知道叫什么名字)

    当一个子类中出现了与父类中不同的内容时,这个子类就称之为派生类。

    通常子类都会写一些新的代码,不可能和父类完全一样,即通常都是派生类。

    所以派生类指的就是子类

    七、覆盖(这个也是只当一个知识点了解)

    也可以称为重写  overrides  当子类出现了与父类名称完全一致的属性或是方法

    下面这个例题是继承list,重写append方法,判断只能添加int类型的数据,不能就添加失败

    强调!!!(最好这么做)

    当你在继承一个类的时候,并且你覆盖了父类的__init__方法时,必须在初始化方法的第一行调用父类的初始化方法,并传入父类所需要的参数。

    class Mylist(list):
        def __init__(self,type):
            super().__init__()    #继承父类的__init__方法
            self.type = type    #实例化传一个参数
    
        def append(self,num):
            if type(num) == self.type:
                super().append(num)
                print('添加成功')
            else:
                print('添加失败,你传入的参数数据类型不对')
    
    
    p = Mylist(int)  #设置传值的类型
    p.append(2)   #传一个值2

    八、组合(这个也很重要,和继承的用处差不多)

    也是一种关系,描述两个对象之间  什么是什么的关系     例如,学生有手机,游戏中角色拥有某些装备

    将一个对象作为另一个对象的属性  (就是把一个实例化对象当做参数传到另一个对象中)

    组合的目的: 也是为了重用现有代码

    什么时候使用继承:分析两个类的关系,如果是属于一类的话,就可以用继承

    举个例子:动物类有吃喝拉撒,人类也有吃喝拉撒,但是我们通常不会用人类去继承动物的吃喝拉撒,逻辑上说不过去,但是如果你想这样用的话,还是可以用的,只是觉得人类继承动物的有点奇怪。可以再写一个父类有吃喝拉撒,人类和动物类都从那边继承。

    什么时候使用组合:如果两个类之间  没有太大的关系,完全不属于同类

    另外组合相比继承,耦合度更低了

    举个例子两个类:一个是电话,一个是学生。现在需求是学生也想用到电话类里面的call_phone方法,这里如果使用继承逻辑说不通,只能用组合

    class Phone:
        def __init__(self,kind,price):
            self.kind = kind
            self.price = price
        def call_phone(self):
            print('打电话')
    
    class Student:
        def __init__(self,name,age,phone):  #这里记得加一个参数
            self.name = name
            self.age = age
            self.phone = phone    #这里也要加
    
        def show_info(self):
            print("name:%s age:%s" % (self.name,self.age))
    
    phone = Phone('apple',10000)
    s1 = Student('rose',20,phone)  #把phone对象当做参数传入s1对象中
    s1.phone.call_phone()    

    九、使用super在子类中访问父类的内容

    方式1:
    super(当前类名称,self).你要调的父类的属性或方法
    方式2:
    super().你要调的父类的属性或方法    #这种方式是最常使用的
    方式3:
    类名称.你要调的父类的属性或方法(self)  
    #方式3与继承无关 

    强调!!!(最好这么做)

    当你在继承一个类的时候,并且你覆盖了父类的__init__方法时,必须在初始化方法的第一行调用父类的初始化方法,并传入父类所需要的参数

    #程序员类
    class Programmer:
        def __init__(self,name,gender,age,money):
              self.name = name
              self.gender = gender
              self.age = age
              self.money = money
        def programming(self):
            print('会写代码')
    
    #项目经理类
    class Manager(Programmer):
        def __init__(self, name, gender, age, money,p):
            super().__init__(name,gender,age,money)   #父类
            self.p = p
        #奖金能力
        def bonus(self):
            print('会发奖金')
        #管理技能
        def management(self):
            print('有管理技能')
    
    p = Programmer('小明','male',20,10000)
    m1 = Manager('老王','male',30,30000,p)  #这里用组合方式传参
    m1.programming()
    m1.bonus()
    m1.management()
    class Parent:
        text = "abc"
        def say_something(self):
            print("anything")
    
    class Sub(Parent):
        def show_info(self):
            print(super().text)    #这个要注意写在一个函数中,我们只能调用函数然后执行super().text
            super().say_something()
    
    sub = Sub()
    sub.show_info()

    十、菱形继承

    python3中任何类都是直接或间接继承了Object 
    新式类:任何显式或隐式地继承自object的类就称之为新式类, python3中全都是新式类
    经典类:既不是Object的子类 ,仅在python2中出现 当出现了菱形继承时:python3如果是新式类,先深度优先,当遇到了共同父类时就找广度 python2经典类,就是一直深度优先
  • 相关阅读:
    linux杀死僵尸进程
    通过dd命令显示硬盘的读写性能
    linux 压缩与解压缩
    linux云主机cpu一直很高降不下来,系统日志报nf_conntrack: table full, dropping packet.
    vsftp配置文件详解
    linux中ping带时间及打印内容到文件
    atop工具检测linux硬件异常
    windows连接服务端的域名正常,linux却不通,(针对于负载均衡后端节点设置)
    有你的地方就是天堂
    Java 异常 —— java.io.InvalidClassException: javax.xml.namespace.QName; local class incompatible
  • 原文地址:https://www.cnblogs.com/wangcuican/p/11247183.html
Copyright © 2011-2022 走看看