面向对象其实是现实世界模型的自然延伸。现实世界中任何实体都可以看做是对象。对象之间通过消息相互作用。另外,现实世界中任何实体都可归属于某类事物,任何对象都是某一类事物的实例。如果说传统的过程式编程语言是以过程为中心、以算法为驱动的话,面向对象的编程语言则是以对象为中心,以消息为驱动。用公式表示,过程式编程语言为:程序=算法+数据;面向对象编程语言为:程序=对象+消息。
所有面向对象编程语言都支持3个概念,即封装、多态性和继承,Java也不例外。现实世界中的对象均有属性和行为,映射到计算机程序上,属性则表示对象的数据,行为表示对象的方法(其作用是处理数据或同外界交互)。所谓封装,就是用一个自主式框架把对象的数据和方法连在一起形成一个整体。可以说,对象是支持封装的手段,是封装的基本单位。Java语言的封装性较强,因为Java无全程变量,无主函数,在Java中绝大部分成员是对象,只有简单的数字类型、字符类型和布尔类型除外。而对于这些类型,Java也提供了相应的对象类型以便与其他对象交互操作。
“这个世界是由什么组成的?”这个问题如果让不同的人来回答会得到不同的答案。如果是一个化学家,他也许会告诉你:“还用问吗?这个世界是由分子、原子、离子等化学物质组成的”。如果是一个画家,他也许会告诉你:“这个世界是由不同的颜色所组成的”。但如果让一个分类学家来考虑问题就有趣多了,他会告诉你:“这个世界是由不同类型的物与事所构成的”。好!作为面向对象的程序员,我们要从分类学家的角度去考虑问题!是的,这个世界是由动物、植物等组成的。动物又分为单细胞动物、多细胞动物、哺乳动物等,哺乳动物又分为人、大象、老虎……就这样分下去了!
现在,从抽象的角度,我们给“类”下个定义吧!我的意思是,从抽象的角度,你回答我“什么是人类?”首先让我们来看看人类所具有的一些特征,这个特征包括属性(一些参数、数值)及方法(一些行为,他能干什么)。每个人都有身高、体重、年龄、血型等一些属性。还有人会劳动、人都会直立行走、人都会用自己的头脑去创造工具等方法。人之所以能区别于其他类型的动物,是因为每个人都具有人这个群体的属性与方法。“人类”只是一个抽象的概念,它仅仅是一个概念,它是不存在的实体。但是所有具备“人类”这个群体的属性与方法的对象都叫人。这个对象“人”是实际存在的实体。每个人都是人这个群体的一个对象。老虎为什么不是人?因为它不具备人这个群体的属性与方法,老虎不会直立行走,不会使用工具等,所以说老虎不是人。
由此可见,类描述了一组有相同特性(属性)和相同行为(方法)的对象。在程序中,类实际上就是数据类型,例如,整数、小数等。整数也有一组特性和行为。面向过程的语言与面向对象的语言的区别就在于,面向过程的语言不允许程序员自己定义数据类型,而只能使用程序中内置的数据类型。而为了模拟真实世界,为了更好地解决问题,我们需往往要创建解决问题所必需的数据类型。
面向对象编程为我们提供了解决方案。以下的考题来自真实的笔试资料,希望读者先不要看答案,自我解答后再与答案加以比对,找出自己的不足。
11.1 面向对象的基本概念
面试例题1:对象与实例有什么区别?
解析:在Java的内存分配中,对象和实例是不同的,前者分配在内存堆里,后者分配在堆栈里,至于为什么要这样分,参考一下其他的资料。对象是不变的东西,它是对客观事物的抽象,实例是对操作对象的引用,你不能直接操作对象。
答案:对象和实例从宏观的角度看,区别是:对象是同类事物的一种抽象表现形式,而实例是对象的具体化,一个对象可以实例化很多实例,对象就是一个模型,实例是照着这个模型生产的最终产品。实际上就是这样,一个对象可以实例化N个实例。就像根据一个模型可以制造多个实际的产品一样。
从内存分配的角度来看,对象是保存在堆中的,而实例是存储在栈中的,实例其实只是对象的一个引用,也就是指向对象的指针。
面试例题2:Java中所有的类都继承了java.lang.Object类,而在C++中没有像java.lang.Object这样的类,这是为什么呢?都是面向对象,Java这样做有什么好处呢?
解析:Java采用的是单根结构,所有的类都继承了java.lang.Object类。对于Java这种纯面向对象的语言来说,这种设计具有很好的灵活性,比如对垃圾收集来说很有利,所有的类都具有java.lang.Object类具有的方法等。C++没有更多这样的方法,大概是为了向后兼容。向C兼容,满足它设计上最大的灵活性。
答案:C++的特点是指针,一个指针可以指向任何的对象、结构、基本类型、函数。
Java没有指针类型,所以Java用Object基础类的共同特征来实现所有对象类型之间的转换。
面试例题3:声明与定义之间的区别是什么?在Java里声明和定义能否分开?
解析:
声明:一种把一个名称引入或者重新引入到某个作用域的构造。
定义:它也是一种声明,但该声明必须给出被声明实体的细节。
对于变量而言,这里的细节是指:为被声明实体保留存储空间。
对于class类型和函数定义而言,指的是包含有一对花括号内容的声明。
对于外部变量而言,指的是前面没有关键字extern或者在声明时就进行初始化。
变量的声明有以下两种情况。
一种是需要建立存储空间的。例如,int a在声明的时候就已经建立了存储空间。
另一种是不需要建立存储空间的,例如,extern int a。其中,变量a是在别的文件中定义的。前者是“定义性声明(defining declaration)”,或者称为“定义(definition)”,而后者是“引用性声明(referencing declaration)”。从广义的角度来讲,声明中包含着定义,但是并非所有的声明都是定义,例如int a,它既是声明,同时又是定义。然而对于extern a来讲,它只是声明不是定义。在一般的情况下我们常常这样叙述,把建立空间的声明称为“定义”,而把不需要建立存储空间的声明称为“声明”。很明显在这里指的声明的范围是比较窄的,也就是说非定义性质的声明。
答案:
变量的定义和声明的区别在于是否分配内存,如果分配内存就是定义,否则就是声明。
类中的变量只是声明而不是定义,因为它只是类声明的一部分。不同于变量的定义,类的定义是一种新的类型的定义,只有实例化后才会分配内存。所以类成员变量只是声明而不是定义。
在Java中,利用Interface,也可以将声明和实现分开。如下所示。
//MyInterface.java
public interface MyInterface
{
void method();
}
//MyImpl.java
public class implements MyInterface
{
public void method()
{
//……
}
}
面试例题4:Which is incorrect about the class?(关于类的描述下面哪个是错误的?)[金山公司2005年面试题]
A.A class is a blueprint to objects.
B.We use the keyword class to create a class construct.
C.Once a class is declared, the class name becomes a type name and can be used to declare variables.
D.The class is same as the struct, and there are no different betweenclass and struct.
解析:这道题的考点是类的概念。
答案:D
面试例题5:Which is incorrect about the OOP?(下面关于面向对象技术的叙述哪个是错误的?)[金山公司2005年面试题]
A.The central idea of OOP is to build programs using software objects.
B.The OOP focuses mainly on the step-by-step procedure as procedure-oriented programing.
C.The OOP offers many advantages: simplicity,modularity,modifiability,extensibility, and so on.
D.The key concept of object orientation is the attachment of procedure to data.
解析:OOP的概念面试例题。面向对象和面向过程不能混为一谈。
答案:B,D