【翻译】Java 面向对象编程基本概念
原文地址:Java OOPs Concepts
面向对象的理念包含了四个主要原则:抽象(abstraction)、封装(encapsulation)、继承(inheritance)和多态(polymorphism),这也是众所周知的面向对象理念的四个支柱。抽象是暴露实体本质,而忽略一些无关细节的过程,以此来降低使用的复杂程度。封装是在一个实体中绑定数据和操作的过程。继承是从已有的类型衍生出一个新的类型,进而建立父类-子类关系。多态让一个实体在不同的上下文环境上呈现不同的状态。
下面详细介绍上述四个面向对象的四个主要原则。
一、 抽象(Abstraction)
我们用现实世界中的场景来举例说明,抽象就变得很容易理解。例如:当我们去驾驶我们的汽车,我们不用关心汽车内部是如何工作的。我们需要关系的仅仅是汽车与我们交互的部分,如:方向盘、刹车踏板、油门踏板等。这些就是我们对汽车的抽象。
在计算机科学中,抽象就是用语义的形式描述数据和程序,隐藏其实现细节。简单地说,抽象就是通过在真实世界中类似的东西间进行比较,来隐藏不相关的信息。
抽象仅包含当前视角下类型的相关信息
常见的抽象有如下两种形式
1.数据抽象
数据抽象是将多个细分的数据类型整合成一个复杂的数据类型。通常情况下,这个复合数据类型与现实世界的实体更为接近。如:一个Employee
类型可以是一个拥有多个细分信息的复合数据类型。
public class Employee {private Department department;private Address address;private Education education;//so on...}
因此,如果我们想获取一个Employee
的信息,我们只需要从Employee
获取,正如我们在现实生活中一样。
2.操作抽象
操作抽象是通过内部的方法访问为一个复杂任务隐藏其内部的一系列动作。因此,任务的具体逻辑对使用者来说是隐藏的,并且可以在不影响使用者代码的情况对内部逻辑进行调整。
public class EmployeeManager{public Address getPrefferedAddress(Employee e){//Get all address from database//Apply logic to determine which address is preferred//Return address.}}
在上述的例子,如果后续我们需要调整方法逻辑让方法一直返回国内的地址,我们可以调整getPrefferedAddress()
方法的实现逻辑,且使用者的代码不受影响。
更多信息,参见:Understanding abstraction in Java
二、封装(Encapsulation)
将数据和方法包装至一个类型中,并通过访问控制隐藏相关的实现逻辑通常叫做封装。封装的结果是一个类型既包含了属性与包含了行为。封装的本质是实现了信息和实现的隐藏。
"Whatever changes,encapsulate it" -- A famous design principle
信息隐藏常通过使用访问控制关键字来实现(如:public,private,protected
),实现隐藏常通过创建类型的接口实现。通过信息隐藏可以让设计人员在需求发生变更时自由地修改提供信息的实现逻辑。
信息隐藏,示例:
class InformationHiding{//Restrict direct access to inward dataprivate List items = new ArrayList();//provide a way to access data - internal logic can safely be changed in futurepublic List getItems(){//do something needed here...return items;}}
实现隐藏,示例:
interface ImplemenatationHiding{Integer sumAllItems(List items);}class InformationHiding implements ImplemenatationHiding{//Restrict direct access to inward dataprivate List items = new ArrayList();//provide a way to access data - internal logic can safely be changed in futurepublic List getItems(){//do something needed here...return items;}public Integer sumAllItems(List items){//Here you may do N number of things in any sequence//Which you do not want your clients to know//You can change the sequence or even whole logic//without affecting the client}}
更多信息,参见:Encapsulation in Java
三、继承(Inheritance)
在Java中,继承是一个对象获取其父类对象属性和行为的一种机制,其本质是在类型之间建立父-子关系。在Java中,我们经常使用继承来实现代码的复用以及提升其可维护性。
Java使用关键字extends
来实现对类的继承。extends
关键字表明我们从一个已有的类衍生出一个新的类型。Java使用超类(super class)术语来表示被继承的类,新的类称为子类(subclass)。
子类继承父类所有的非私有成员(属性、方法以及嵌套类)。构造函数不是类的成员,因此,构造函数不会被子类继承,但子类的构造函数可以触发父类的构造函数。
示例
public class Employee {private Department department;private Address address;private Education education;//so on...}class Manager extends Employee{private List<Employee> reportees;}
四、多态(Polymorphism)
多态指的是我们创建的函数或引用的对象在不同的运行上下文中表现出不同的行为状态。
在Java中,从本质上来看,多态存在两个不同的类型:
+ 编译时多态(静态的绑定或方法重载)
+ 运行时多态(动态的绑定或方法重写)
更多信息,参见:Java面向对象编程基本概念——多态