Skip to content

面向对象编程

面向对象编程(OOP)是如今多种编程语言所实现的一种编程范式,包括 Java、C++。 对象编程 的基本概念,其中包括:类与实例、继承、封装

类与实例

当我们使用面向对象编程的术语对一个问题进行建模时,我们会创建一系列抽象的定义,这些定义代表了系统中存在的各类对象。例如,如果我们要对一个学校进行建模,我们可能会建立许多用于代表教授的对象,所有教授通常都存在以下属性:教授们都有一个名字;都有一门他们各自所教的课程。此外,所有教授都可以做一些特定的事情,包括:他们可以为学生的论文打分;他们可以在学年的开始向学生介绍自己。

就类本身而言,并不做任何事情,类只是一种用于创建具体对象的模板。Professor 类可以创建一个具体的教授,我们称这样创建出来的具体教授为 Professor 类的实例。由类创建实例的过程是由一个特别的函数——构造函数所完成的。开发人员将类所需要的值传入构造函数,构造函数即可根据传入的值初始化实例的内部状态。

继承

如果我们可以用某种特别的方式共享教授和学生中相同属性的声明,那么这会节省我们不少的精力。更准确的说,在某种层级上,二者实际上是同种事物,他们能够具有相同的属性也是合理的。继承(Inheritance)可以帮助我们完成这一操作。

很容易注意到教授和学生都是人,而人是具有姓名,并且可以介绍自己的。我们可以将人定义为一个新类,即 Person 类,在 Person 类中,我们可以定义所有作为人的通用属性。接下来,我们可以定义 Professor 类和 Student 类由 Person 类派生(derive)而来

在这种情况下,我们称 Person 类是 Professor 类和 Student 类的超类(superclass)或父类(parent class)。反之,我们称 Professor 类和 Student 类是 Person 类的子类(subclass 或 child class)。

当一个方法拥有相同的函数名,但是在不同的类中可以具有不同的实现时,我们称这一特性为多态(polymorphism)。当一个方法在子类中替换了父类中的实现时,我们称之为子类重写(override)了父类中的实现。

封装

当其他部分的代码想要执行对象的某些操作时,可以借助对象向外部提供的接口完成操作,借此,对象保持了自身的内部状态不会被外部代码随意修改。也就是说,对象的内部状态保持了私有性,而外部代码只能通过对象所提供的接口访问和修改对象的内部状态,不能直接访问和修改对象的内部状态。保持对象内部状态的私有性、明确划分对象的公共接口和内部状态,这些特性称之为封装(encapsulation)。

封装的好处在于,当程序员需要修改一个对象的某个操作时,程序员只需要修改对象对应方法的内部实现即可,而不需要在所有代码中找出该方法的所有实现,并逐一修改。某种意义上来说,封装在对象内部和对象外部设立了一种特别的“防火墙”。

面向对象编程与 JavaScript

我们探讨了 JavaScript 中的一对核心特性:构造函数和原型

  • 构造函数:在 JavaScript 中,构造函数可以实现类的定义,帮助我们在一个地方描述类的“形状”,包括定义类的方法。不过,原型也可以用于实现类的定义。例如,如果一个方法定义于构造函数的 prototype 属性中,那么所有由该构造函数创造出来的对象都可以通过原型使用该方法,而我们也不再需要将它定义在构造函数中。

  • 原型链:原型链很自然地实现了继承特性。例如,如果我们由 Person 原型构造了一个 Student 类,那么我们可以继承 Person 类的 name 属性,重写 introduceSelf() 方法。