python-面向对象之继承
一、继承介绍
继承是一种新建类的方式,新建的类称之为子类或者派生类,被继承的类称为父类/基类/超类
python中继承的特点:
1.子类可以遗传/重用父类的属性
2.子类可以有多个父类
3.Python中的继承类分为新式类和经典类
新式类:继承了object的类,以及他的子类都是新式类
经典类:没有继承object的类,以及他的子类都是经典类
在Python3中,没有显示的声明,默认继承object类,所有的类都是新式类
在Python2中才区分新式类和经典类,没有显示继承任何类,也不会继承object类。
使用继承的好处:减少类与类之间的代码冗余
二、继承的定义
在子类中加括号,括号里加上父类
class parent1: x=111 class sub1(parent1): pass
调用属性,查看父类:
class parent1: x=111 class parent2: x=222 class sub1(parent1): pass class sub2(parent1,parent2): pass print(parent1.__bases__)#查看父类 (<class 'object'>,) print(sub1.__bases__)#(<class '__main__.parent1'>,) print(sub2.__bases__)#(<class '__main__.parent1'>, <class '__main__.parent2'>) obj = sub1() print(obj.x)#111
三、利用继承解决类与类之间的代码冗余问题
可以将类与类之间的重复代码定义在一个父类中,思考的时候从下往上思考统计
class OldboyPeople: school = 'Oldboy' def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex class OldboyStudent(OldboyPeople): def choose_course(self): print('%s choosing course' % self.name) class OldboyTeacher(OldboyPeople): def score(self,stu,num): stu.score=num stu1=OldboyStudent('刘二蛋',38,'male') print(stu1.__dict__) tea1=OldboyTeacher('egon',18,'male') print(tea1.__dict__)
不过这个时候,不同的类要是想用自己独有的属性应该怎么办呢?
在子类派生的新方法中重用父类的功能 方式一:
指名道姓地引用一个类中的函数
class OldboyPeople: school = 'Oldboy' def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex class OldboyStudent(OldboyPeople): def __init__(self, name, age, sex, score=0): OldboyPeople.__init__(self,name,age,sex) self.score = score def choose_course(self): print('%s choosing course' % self.name) class OldboyTeacher(OldboyPeople): def __init__(self,name,age,sex,level): OldboyPeople.__init__(self,name,age,sex) self.level=level def score(self,stu,num): stu.score=num stu1=OldboyStudent('刘二蛋',38,'male') print(stu1.__dict__) tea1=OldboyTeacher('egon',18,'male',10) print(tea1.__dict__)
总结:
1.与继承无关
2.访问的是类的函数,没有自动传值的效果
在学习子类派生方法中重用父类的功能第二个方式之前先来说一下在继承背景下的属性查找
1.单继承状态下的属性查找:
class Foo: xxx=444 pass class Bar1(Foo): # xxx=333 pass class Bar2(Bar1): # xxx=222 pass obj=Bar2() # obj.xxx=111 print(obj.xxx)#444
单继承查找的优先级别:对象->对象的类->父类->object
2.多继承状态下的属性查找:
如果继承关系为非菱形结构,则会按照先找B这一条分支,然后再找C这一条分支,最后找D这一条分支的顺序直到找到我们想要的属性
class G: x = 'G' pass # 第三层 class E(G): # x = 'E' pass class F: # x = 'F' pass # 第二层 class B(E): # x = 'B' pass class C(F): # x = 'C' pass class D: # x = 'D' pass # 第一层 class A(B, C, D): # x = 'A' pass obj = A() # obj.x = 111 print(obj.x)
此时属性的查找顺序优先级是:对象->对象的类->按照从左到右的顺序一个分支一个分支的找下去
菱形继承:属性的查找方式有两种,深度优先和广度优先
新式类:广度优先查找,从左往右一个分支一个分支的查找,在找到最后一个分支采才去查找顶级类
经典类:深度优先查找,从左往右一个分支一个分支的查找,在第一个分支就查找到顶级类
继承原理:
对于定义的每一个类,Python会计算出一个方法解析顺序(MRO)列表,这个列表就是一个简单的所有基类的线性顺序表
# 第四层: class G(object): # x = 'G' pass # 第三层 class E(G): # x = 'E' pass class F(G): # x = 'F' pass # 第二层 class B(E): # x = 'B' pass class C(F): # x = 'C' pass class D(G): # x = 'D' pass # 第一层 class A(B, C, D): # x = 'A' pass obj=A()
[<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>]
注:今天威老师讲了一个很好记的方式,就是先深度查找,然后去除前面重复的,留下的就是查找属性的顺序。
在子类派生的新方法中重用父类的功能 方式二:
super()必须在类中使用
在Python2中:super(自己的类名,自己的对象)
在Python3中:super()
调用该函数会得到一个特殊的对象,该对象专门用来访问父类中的属性,(完全参照mro列表)
总结:
1.严格依赖继承的mro列表
2.访问的是绑定方法,有自动传值的效果
class OldboyPeople: school = 'Oldboy' def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex class OldboyStudent(OldboyPeople): def __init__(self, name, age, sex, score=0): super(OldboyStudent,self).__init__(name,age,sex) self.score = score def choose_course(self): print('%s choosing course' % self.name) class OldboyTeacher(OldboyPeople): def __init__(self,name,age,sex,level): super().__init__(name,age,sex) self.level=level def score(self,stu,num): stu.score=num stu1=OldboyStudent('刘二蛋',38,'male') print(stu1.__dict__) tea1=OldboyTeacher('egon',18,'male',10) print(tea1.__dict__)
还是需要加油学习!
焚膏油以继晷,恒兀兀以穷年。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Confluence 6 企业环境或者网站托管的 Java 配置策略
Confluence 需要依赖一些 Java 的库才能够允运行。一些依赖的 Java 库应用了 Java 的语言特性,但是又是被 Java 的安全策略所限制的。 这个通常来说是不会造成任何问题的。默认的安全配置策略通常对运行 Confluence 没有任何影响。但是在一些共享服务器或者企业部署环境下,安全设定可能会导致 Confluence 不能正常的工作。 当你尝试运行 Confluence 的时候,你可能会遇到下面的错误: java.security.AccessControlException:access denied (java.lang.RuntimePermissionaccessDeclaredMembers) atjava.security.AccessControlContext.checkPermission(AccessControlContext.java(CompiledCode)) atjava.security.AccessController.checkPermission(AccessController.java(CompiledCode)) at...
- 下一篇
在 Linux 中自动启动 Confluence 6
在 Linux/Solaris 环境下,最好的办法是对每一个服务进行安装和配置(包括 Confluence),同时配置这些服务权限为他们所在用户需要的服务权限即可, 为实例创建一个 Confluence,使用下面的命令: sudo useradd --create-home -c "Confluence role account" confluence 来为 Confluence 的安装创建一个目录。在这个例子中,我们使用/usr/local/confluence。 sudo mkdir /usr/local/confluence sudo chown confluence: /usr/local/confluence 以 Confluence 用户进行登录后安装 Confluence: sudo su - confluence cd /usr/local/confluence/ tar zxvf /tmp/confluence-5.6.4.tar.gz ln -s confluence-5.6.4/ current 编辑 <<CONFLUENCE_INSTALL_DIRE...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS关闭SELinux安全模块
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果