Python随记(七)Python类与类的继承之简析
本篇博文描述的是python3, python2与3在类的的一些细节上有点区别
类是用来描述具有相同属性和方法的对象的集合。对象是类的实例。
基本格式:
Class Classname( ):
def __init__(self, A, B, …):
self.a = A #这里其实并不要求是对应大小写的关系,只是举例对应的关系而已
self.b = B #因为A,B说白了只是形参名,他们的值是由外部传入
…… #一般命名时还是要有较好的易读性
def function(self):
……
用来定义类,类名一般采用驼峰命名法、
每个类定义中都应该有这一个方法,开头和末尾是两个下划线!。
必须包含两种类型的形参:self形参和 其他形参
相当于一个指向实例(对象)的引用,能够让实例访问类中的属性和方法。
当我们定义一个具体的对象时,这个对象会自动传递给self,我们不需要手动操作。
比如定义一个person的类, Class Person ( ): ……,当我们使用这个类创建对象时,
比如:teacher = Person(A,B, …)
只需要传入其他类型的参数即可,teacher相当于自动传递为self了,所以self就是teacher在类定义中的一个引用。
构造方法中的A、B之类的就都属于其他类型的参数,需要手动填写并传入
在构造方法中定义的变量都需要使用self前缀,表明是这个对象的属性,供其访问。
给我的感觉有点类似于C++中的成员函数的样子吧,定义的时候一定要加self形参,这样才能让对象调用。
要注意写注释信息,这样使得程序表达的意思更清楚。采用文档注释的形式:三引号。
同时也要注意缩进。
来运行一下:
可见,通过句点符号可以访问对象的属性和方法。
编写类的时候并非总要从空白开始,如果是已有类的修订版或增强版,就可以使用继承。
当一个类继承另一个类的时候,它将自动获得另一个类的所有属性和方法,原类称为父类,新类称为子类。
创建子类的时候,父类必须要包含在相同的作用域内
class Son(Father):
def __init__(self, A, B):
和父类中的构造函数一样,为什么呢?
其实这里可以理解为这个构造函数就是子类的构造函数,就和新定义一个类的时候要使用构造函数初始化一样,
因为说白了,子类也是一个类啊,所以建立新的类的时候,都要有这么一个初始化函数,
不管是子类还是父类,只要是类,都要有这个构造函数
至于为什么要包含进去父类的形参,是因为我们这是继承父类的子类,既然是继承,那肯定要有父类的遗传基因,不然没有意义,所以一般情况下会把父类所具有的属性(也就是括号中的形参)都初始化一次。#但你这里不写,其实也能够默认继承下来,
如果想要子类能添加新的形参,就必须需要在这个初始化函数中写明了,参考我下文的程序示例。
super( ).__init__(A,B,….)
这就是把刚刚子类构造函数的形参和父类的形参关联在一起,同时父类的方法也被关联在一起了。
换句话说,这里就是在调用父类的初始化构造函数,这个super就是superclass的代表,就是说超类,
而对于子类来讲,就是它的父类,所以这里也把父类的初始化函数调用一遍,
至于父类的形参,在这里还是应该写上的
这里就不用写self了,python3中 super 帮你继承了。。
注意:python2中的语法稍有不同:super(Son,self).__init__(A,B,…),
也就是说super当中一定要包含子类类名和self这两个形参,有点显式的意味,或者是: Father.__init__(self) 也是同样的
因为我们编程时也会碰到一些以前的python2的程序,所以还是要知道这两个的区别。
经过以上三个操作,子类就能继承父类的所有了,
举例:
注意我标注的地方
A、 因为就在这个对话框中前面定义过父类,所以这里直接包括进去就行,否则要import模块
B、 我在使用构造函数初始化属性的时候,新加了一个属性student_number,见图中红色方框
表明子类Student现在一共需要传入self,persont_name,person_age,person_male,student_number这五个形参了,其中self不用我们手动传入;
C、 我们使用super()进行关联的时候,却没有出现student_number这个形参,这是因为父类里面本来没有这个属性,如图中绿线部分所示。所以我们没必要进行关联,只有子类有这个属性。
D、 我们这里重写了show_info()这个方法,
其实就算不写,也能在实例中直接用句点符号调用这个方法,因为我们继承了父类的所有方法,但是就不会有num这个输出了。所以我们重新定义了这个方法,这叫做覆写。就是把父类的方法给覆盖了。但是覆盖只是说使用子类来实例化的对象调用这个方法的时候用的是新的语句,比如下文的 H; 如果是父类实例化的对象,比如上文的teacher,调用这个方法,还是执行的父类的代码块。
H成功接受了2018这个参数,而父类里是没有这个属性项的,
并且调用子类的新的show_info( )方法,成功打印出来了
基本使用情况就是这样