Python 类和对象
Python 从一开始就被设计成一门面向对象的语言。不过,与 JavaScript 基于原型(prototype)的面向对象编程范式(normal form)不同,Python 的面向对象编程范式是中规中矩的基于类(class)的继承,并天然的支持多态(polymophine)。
类的定义
Python 使用 class
关键字定义类,例如:
class People:
name = ""
def __init__(self, name):
self.name = name
def getName(self):
return self.name
person = People("Rudy")
print(person.getName())
在这里,我们使用关键字 class 定义了一个名为 Stu 的类。类是一些属性和方法的集合,通常用来描述具有相同的属性和方法的对象。
- Stu 类里面有 name 变量,它定义在类中且在函数体之外,称为类变量或类属性,它在整个实例化的对象中是公用的。
- 类中的函数通常称为方法,Stu 类有一个
__init__()
方法,它是一个魔术方法,在实例化的时候会自动调用,称为构造方法。 - Stu 类中还有一个
get_name()
方法,我们可以通过对象调用这个方法。__init__()
方法和get_name()
方法的第一个参数都是 self,这个参数是必须的,它指向对象本身。 - 但 self 的名字不是固定的(只是约定俗成而已),我们也可以修改成 this。
- 接着,使用
stu = Stu("Rudy")
创建一个 stu 对象并传入一个学生名字,学生名字会作为参数传递给构造方法,这个过程称为实例化。 - 最后调用 stu 对象的
get_name()
方法,并将名字打印出来,实现了对象方法的调用。实际上,在这个例子中,我们也可以直接通过 stu.name 对象属性获取学生的名字。
实例化对象
Python 实例化对象特别简单,不需要像其他语言那样使用 new 关键字。
面向对象的三大特性是封装、继承和多态,上面的例子就是对“学生信息”这个类的简单封装。Python 同样支持类的继承,如果一种语言不支持继承,那么类就没有意义了。下面来看看继承和多态:
class Student(People):
grade = ""
def __init__(self, name, grade):
People.__init__(self, name)
self.grade = grade
def getName(self):
return ("Name:" + self.name)
def getGrade(self):
return self.grade
stu = Student("Tina", "A+")
print(stu.getName())
print(stu.getGrade())
类的继承只需要在类名称后面的圆括号中添加基类(又称父类)的名称即可。比如这里的 Student 类继承自 People 类,我们称 Student 为派生类(又称子类),显然 Student 继承了 People 的 name 属性和 getName() 方法。
对于构造方法,子类需要将相应的参数传递给父类的构造函数,已完成数据的初始化。Student 类中重新实现了 getName() 方法,它会覆盖父类中同名的方法,我们 称之为方法重写,通过方法重写就可以实现多态。
此外,Student 类还增加了 grade 属性和 getGrade() 方法,这些属性和方法只属于 Student 类,这称为类的扩展。
注意:Python 中的方法重写和方法重载是一样的。它的意义在于,如果父类方法提供的功能不满足子类的需求,那么就可以在子类中重写父类的方法。
Python 有限的支持多继承形式,多继承方式如下:
class DerivedClassName(Base1, Base2, Base3):
<statement-1>
...
<statement-N>
值得一提的是,如果父类中有相同的方法名,而子类使用时并未指定,这时就需要特别关注圆括号中父类的顺序。也就是说,当方法在子类中未找到时,就会在继承序列中以从左往右的顺序,查找父类中是否包含该方法,调用最先找到的方法。