Java语言概述.docx
- 文档编号:8834221
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:19
- 大小:73.99KB
Java语言概述.docx
《Java语言概述.docx》由会员分享,可在线阅读,更多相关《Java语言概述.docx(19页珍藏版)》请在冰豆网上搜索。
Java语言概述
第2章Java语言概述
像所有其他的计算机语言一样,Java的各种要素不是独立存在的,它们作为一个整体共同构成了Java语言。
这种关联使得不讲其他方面而单独描述Java的某一方面是困难的。
讨论一个特性经常要先具有另外一个特性的知识。
因此,本章先对Java的若干主要特性做简单综述。
这里描述的主题将给你一个立足点:
能够使你编写和理解简单的Java程序。
大多数讨论话题将在第1部分的其他章节详细叙述
2.1面向对象编程
Java的核心是面向对象编程。
事实上,所有的Java程序都是面向对象的,你别无选择。
这一点与C++不同,因为在那里你可以选择是否面向对象编程。
面向对象编程与Java密不可分,因此,在你编写哪怕是最简单的Java程序以前,也必须理解它的基本原则。
因此,本章先从面向对象编程的概念讲起。
2.1.1两种范型
我们知道,所有的计算机程序都由两类元素组成:
代码和数据。
此外,从概念上讲,程序还可以以它的代码或是数据为核心进行组织编写。
也就是说,一些程序围绕“正在发生什么”编写,而另一些程序则围绕“谁将被影响”编写。
这两种范型决定程序的构建方法。
第一种方法被称为面向过程的模型(process-orientedmodel),用它编写的程序都具有线性执行的特点。
面向过程的模型可认为是代码作用于数据,像C这样的过程式语言采用这个模型是相当成功的。
然而,正如在第1章提到的,当程序变得更大并且更复杂时,就会出现问题。
为了管理不断增加的复杂性,第二种方式,也就是面向对象的编程(object-orientedprogramming)被构思出来了。
面向对象的编程围绕它的数据(即对象)和为这个数据严格定义的接口来组织程序。
面向对象的程序实际上是用数据控制对代码的访问。
下面你将看到,将控制的实体变换为数据,可使程序在组织结构上从若干方面受益。
2.1.2抽象
面向对象编程的一个实质性的要素是抽象。
人们通过抽象(abstraction)处理复杂性。
例如,人们不会把一辆汽车想象成由几万个互相独立的部分所组成的一套装置,而是把汽车想成一个具有自己独特行为的对象。
这种抽象使人们可以很容易地将一辆汽车开到杂货店,而不会因组成汽车各部分零件过于复杂而不知所措。
他们可以忽略引擎、传动及刹车系统的工作细节,将汽车作为一个整体来加以利用。
使用层级分类是管理抽象的一个有效方法。
它允许你根据物理意义将复杂的系统分解为更多更易处理的小块。
从外表看,汽车是一个独立的对象。
一旦到了内部,你会看到汽车由若干子系统组成:
驾驶系统,制动系统,音响系统,安全带,供暖,便携电话,等等。
再进一步细分,这些子系统由更多的专用元件组成。
例如,音响系统由一台收音机、一个CD播放器、或许还有一台磁带放音机组成。
从这里得到的重要启发是,你通过层级抽象对复杂的汽车(或任何另外复杂的系统)进行管理。
复杂系统的分层抽象也能被用于计算机程序设计。
传统的面向过程程序的数据经过抽象可用若干个组成对象表示,程序中的过程步骤可看成是在这些对象之间进行消息收集。
这样,每一个对象都有它自己的独特行为特征。
你可以把这些对象当作具体的实体,让它们对告诉它们做什么事的消息作出反应。
这是面向对象编程的本质。
面向对象的概念是Java的核心,对程序员来讲,重要的是要理解这些概念怎么转化为程序。
你将会发现,在任何主要的软件工程项目中,软件都不可避免地要经历概念提出、成长、衰老这样一个生命周期,而面向对象的程序设计,可以使软件在生命周期的每一个阶段都处变不惊,有足够的应变能力。
例如,一旦你定义好了对象和指向这些对象的简明的、可靠的接口,你就能很从容很自信地解除或更替旧系统的某些组成部分。
2.1.3面向对象编程的3个原则
所有面向对象的编程语言都提供帮助你实现面向对象模型的机制,这些机制是封装,继承及多态性。
现在让我们来看一下它们的概念。
封装
封装(Encapsulation)是将代码及其处理的数据绑定在一起的一种编程机制,该机制保证了程序和数据都不受外部干扰且不被误用。
理解封装性的一个方法就是把它想成一个黑匣子,它可以阻止在外部定义的代码随意访问内部代码和数据。
对黑匣子内代码和数据的访问通过一个适当定义的接口严格控制。
如果想与现实生活中的某个事物作对比,可考虑汽车上的自动传送。
自动传送中包含了有关引擎的数百比特的信息,例如你正在以什么样的加速度前进,你行驶路面的坡度如何,以及目前的档位。
作为用户,你影响这个复杂封装的方法仅有一个:
移动档位传动杆。
例如,你不能通过使用拐弯信号或挡风玻璃擦拭器影响传动。
所以档位传动杆是把你和传动连接起来的惟一接口。
此外,传动对象内的任何操作都不会影响到外部对象,例如,档位传动装置不会打开车前灯!
因为自动传动被封装起来了,所以任何一家汽车制造商都可以选择一种适合自己的方式来实现它。
然而,从司机的观点来看,它们的用途都是一样的。
与此相同的观点能被用于编程。
封装代码的好处是每个人都知道怎么访问它,但却不必考虑它的内部实现细节,也不必害怕使用不当会带来负面影响。
Java封装的基本单元是类。
尽管类将在以后章节详细介绍。
现在仍有必要对它作一下简单的讨论。
一个类(class)定义了将被一个对象集共享的结构和行为(数据和代码)。
一个给定类的每个对象都包含这个类定义的行为和结构,好像它们是从同一个类的模子中铸造出来似的。
因为这个原因,对象有时被看作是类的实例(instancesofaclass)。
所以,类是一种逻辑结构,而对象是真正存在的物理实体。
当创建一个类时,你要指定组成那个类的代码和数据。
从总体上讲,这些元素都被称为该类的成员(members)。
具体地说,类定义的数据称为成员变量(membervariables)或实例变量(instancevariables)。
操作数据的代码称为成员方法(membermethods)或简称方法(methods)。
如果你对C/C++熟悉,可以这样理解:
Java程序员所称的方法,就是C/C++程序员所称的函数(function)。
在完全用Java编写的程序中,方法定义如何使用成员变量。
这意味着一个类的行为和接口是通过方法来定义的,类这些方法对它的实例数据进行操作。
既然类的目的是封装复杂性,在类的内部就应该有隐藏实现复杂性机制。
类中的每个方法或变量都可以被标记为私有(private)或公共(public)。
类的公共接口代表类的外部用户需要知道或可以知道的每件事情;私有方法和数据仅能被一个类的成员代码所访问,其他任何不是类的成员的代码都不能访问私有的方法或变量。
既然类的私有成员仅能被程序中的其他部分通过该类的公共方法访问,那么你就能保证不希望发生的事情就一定不会发生。
当然,公共接口应该小心仔细设计,不要过多暴露类的内部内容(见图2-1)。
图2-1封装:
可用来保护私有数据的公共方法
继承
继承(Inheritance)是一个对象获得另一个对象的属性的过程。
继承很重要,因为它支持了按层分类的概念。
如前面提到的,大多数知识都可以按层级(即从上到下)分类管理。
例如,尊贵的猎犬是狗类的一部分,狗又是哺乳动物类的一部分,哺乳动物类又是动物类的一部分。
如果不使用层级的概念,我们就不得不分别定义每个动物的所有属性。
使用了继承,一个对象就只需定义使它在所属类中独一无二的属性即可,因为它可以从它的父类那儿继承所有的通用属性。
所以,可以这样说,正是继承机制使一个对象成为一个更具通用类的一个特定实例成为可能。
下面让我们更具体地讨论这个过程。
大多数人都认为世界是由对象组成的,而对象又是按动物、哺乳动物和狗这样的层级结构相互联系的。
如果你想以一个抽象的方式描述动物,那么你可以通过大小、智力及骨胳系统的类型等属性进行描述。
动物也具有确定的行为,它们也需要进食、呼吸,并且睡觉。
这种对属性和行为的描述就是对动物类的定义。
如果你想描述一个更具体的动物类,比如哺乳动物,它们会有更具体的属性,比如牙齿类型、乳腺类型等。
我们说哺乳类动物是动物的子类(subclass),而动物是哺乳动物的超类(superclass)。
由于
哺乳动物类是需要更加精确定义的动物,所以它可以从动物类继承(inherit)所有的属性。
一个深度继承的子类继承了类层级(classhierarchy)中它的每个祖先的所有属性。
继承性与封装性相互作用。
如果一个给定的类封装了一些属性,那么它的任何子类将具有同样的属性,而且还添加了子类自己特有的属性(见图2-2)。
这是面向对象的程序在复杂性上呈线性而非几何性增长的一个关键概念。
新的子类继承它的所有祖先的所有属性。
它不与系统中其余的多数代码产生无法预料的相互作用。
多态性
多态性(Polymorphism,来自于希腊语,表示“多种形态”)是允许一个接口被多个同类动作使用的特性,具体使用哪个动作与应用场合有关,下面我们以一个后进先出型堆栈为例进行说明。
假设你有一个程序,需要3种不同类型的堆栈。
一个堆栈用于整数值,一个用于浮点数值,一个用于字符。
尽管堆栈中存储的数据类型不同,但实现每个栈的算法是一样的。
如果用一种非面向对象的语言,你就要创建3个不同的堆栈程序,每个程序一个名字。
但是,如果使用Java,由于它具有多态性,你就可以创建一个通用的堆栈程序集,它们共享相同的名称。
多态性的概念经常被说成是“一个接口,多种方法”。
这意味着可以为一组相关的动作设计一个通用的接口。
多态性允许同一个接口被必于同一类的多个动作使用,这样就降低了程序的复杂性。
选择应用于每一种情形的特定的动作(specificaction)(即方法)是编译器的任务,程序员无需手工进行选择。
你只需记住并且使用通用接口即可。
图2-2拉不拉多猎犬继承所有其超类的封装
再拿狗作比喻,一条狗的嗅觉是多态的。
如果狗闻到猫的气味,它会在吠叫并且追着它跑。
如果狗闻到食物的气味,它将分泌唾液并向盛着食物的碗跑去。
两种状况下是同一种嗅觉器官在工作,差别在于闻到了什么气味,也就是有两种不同类型的数据作用于狗的鼻子!
在一个Java程序中使用方法时,也可以采用这个通用的概念。
多态性、封装性与继承性相互作用
如果用得当,在由多态性、封装性和继承性共同组成的编程环境中可以写出比面向过程模型环境更健壮、扩展性更好的程序。
精心设计的类层级结构是重用你花时间和努力改进并测试过的程序的基础,封装可以使你在不破坏依赖于类公共接口的代码基础上对程序进行升级迁移,多态性则有助于你编写清楚、易懂、易读、易修改的程序。
在前面两个与现实生活有关的实例中,汽车更能全面说明面向对象设计的优点,为介绍继承而用狗作类比也很有趣。
总的来说,汽车与程序很相似,所有的驾驶员依靠继承性很快便能掌握驾驶不同类型(子类)车辆的技术。
不管是接送学生的校车,或是默西迪斯私家轿车,或是保时捷汽车,或是家庭汽车,司机差不多都能找到方向盘、制动闸和加速器,并知道如何操作。
经过一段驾驶,大多数人甚至能知道手动档与自动档之间的差别,因为他们从根本上理解这两个档的超类——传动。
人们在汽车上看见的总是封装好的特性。
刹车和踏脚板隐蔽着不可思议的复杂性,但接口却是如此简单,你的脚就可以操作它们!
引擎、制动闸及轮胎的大小对于你如何定义踏脚板类的接口没有任何影响。
最后的属性,多态性,在汽车制造商基于相同的交通工具所提供的多种选择的能力上得到了充分反映。
例如,刹车系统有正锁和反锁之分,方向盘有带助力或不带助力之分,引擎有4缸、6缸或8缸之分。
无论设置如何,你都得脚踩刹车板来停车,转动方向盘来转向,按离合器来制动。
同样的接口能被用来控制许多不同的实现过程。
正如你所看到的,通过封装、继承及多态性原理,各个独立部分组成了汽车这个对象。
这在计算机程序设计中也是一样的。
通过面向对象原则的使用,可以把程序的各个复杂部分组合成一个一致的、健壮的、可维护的程序整体。
正如本节开始时提到的,所有的Java程序都是面向对象的。
或者,更精确地说,每个Java程序都具有封装性、继承性及多态性。
尽管在本章将要介绍的简单示例程序及以后几章的示例程序中并未体现所有这些特性,但也有所体现。
你将看到,Java提供的许多特性是它的内置类库的一部分,这个库使封装性、继承性及多态性得到更广泛应用。
2.2第1个简单程序
既然Java面向对象的基础已经被讨论过了,接下来让我们看一些实际的Java程序。
让我们从编译及运行下面这个简短示例程序开始。
你将看到,这个程序的功能比你想像的要多。
/*
ThisisasimpleJavaprogram.
Callthisfile"Example.java".
*/
classExample{
//Yourprogrambeginswithacalltomain().
publicstaticvoidmain(Stringargs[]){
System.out.println("ThisisasimpleJavaprogram.");
}
}
注意:
在下面的介绍中,将使用标准JDK(JavaDeveloper’sKit,Java开发工具包),它可从SunMicrosystems公司得到。
如果你正在使用其他的Java开发环境,则Java程序编译、运行过程可能有所不同。
在这种情况下,请你查阅编译器的用户手册来获得具体指导。
2.2.1键入程序
对大多数计算机语言,包含程序源代码的文件名是任意的,但对于Java就不行。
关于Java,你需要知道的第一件事就是源文件的名字非常重要。
对这个例子,源程序文件名应该是Example.java。
下面我们将解释其中的原因。
在Java中,一个源程序文件被称为一个编译单元(compilationunit)。
它是一个包含一个或多个类定义的文本文件。
Java编译器要求源程序文件使用.java文件扩展名。
请注意,文件扩展名长度是4个字符。
所以,你的操作系统一定要有支持长文件名的能力。
这意味着DOS和Windows3.1是不支持Java的(至少在目前是这样)。
当然,它可在Windows95/98和WindowsNT/2000下正常工作。
从上述示例程序中可以看出,程序中定义的类名也是Example。
这不是巧合。
在Java中,所有的代码都必须驻留在类中。
按照约定,类名必须与源程序的文件名相同。
你也应该确保文件名的大小写字母与类名一样,这是因为Java是区分大小写的。
虽然文件名与类名必须一致的约定似乎有点专制,但是这个约定有助于你轻松地维护及组织程序。
2.2.2编译程序
要编译示例程序Example,须运行编译器程序javac,并在命令行上指定源程序文件名,格式如下所示:
C:
\>javacExample.java
编译器javac产生了一个名为Example.class的文件,该文件包含程序的字节码。
前面已讨论过,Java字节码中包含的是Java解释程序将要执行的指令码。
因此,javac的输出并不是可以直接运行的代码。
要真正运行该程序,你必须使用名叫java的Java解释器。
具体做法是把类名Example作为一个命令行参数输入,格式如下所示:
C:
\>javaExample
运行这个程序,将输出如下内容:
ThisisasimpleJavaprogram.
当Java源代码被编译后,每个单独的类都被放入自己的输出文件中,并以类的名字加“.class”扩展名为其文件名。
这就是为什么Java源程序文件必须与其中包含的类同名的原因——源程序文件将与“.class”文件相同。
运行Java解释器实际上是指定你想要解释器运行的类的名字,它会自动搜索包含该名字且带有.class扩展名的文件。
如果找到,它将运行包含在该指定类中的代码。
2.2.3详细讨论第1个示例程序
尽管Example.java很短,但它包括了所有Java程序具有的几个关键特性。
让我们仔细分析该程序的每个部分。
程序开始于以下几行:
/*
ThisisasimpleJavaprogram.
Callthisfile"Example.java".
*/
这是一段注释(comment)。
像大多数其他的编程语言一样,Java也允许你在源程序文件中加注释。
注释中的内容将被编译器忽略。
事实上,注释是为了给任何阅读源代码程序的人说明或解释程序的操作。
在本例中,注释对程序进行说明,并提醒你该源程序的名字叫做Example.java。
当然,在真正的应用中,注释通常用来解释程序的某些部分如何工作或某部分的特殊功能。
Java支持3种类型的注释。
在示例程序顶部的注释称为多行注释(multilinecomment)。
这类注释开始于“/*”,结束于“*/”。
这两个注释符间的任何内容都将被编译器忽略。
正如“多行注释”名字所示,一个多行注释可以包含若干行文字。
程序的下一行代码如下所示:
classExample{
该行使用关键字class声明了一个新类,Example是类名标识符,整个类定义(包括其所有成员)都将位于一对花括号({})之间,花括号在Java中的使用方式与C或C++相同,目前,不必考虑类的细节,只是有一点要注意,在Java中,所有程序活动都发生在类内,这就是为什么Java程序是面向对象的。
下面一行程序是单行注释:
//Yourprogrambeginswithacalltomain().
这是Java支持的第二种类型的注释。
单行注释(single-linecomment)始于“//”,在该行的末尾结束。
通常情况下,程序员们对于较长的注释使用多行注释,而对于简短的、一行一行的注释则使用单行注释。
下一行代码如下所示:
publicstaticvoidmain(Stringargs[]){
该行开始于main( )方法。
正如它前面的注释所说,这是程序将要开始执行的第一行。
所有的Java应用程序都通过调用main( )开始执行(这一点同C/C++一样),我们在此还不能对该行的每一个部分作出精确的解释,因为这需要详细了解Java封装性的特点,但是,由于本书第1部分中的大多数例子都用到这一行代码,我们将对各部分作一个简单介绍
。
关键字public是一个访问说明符(accessspecifier),它允许程序员控制类成员的可见性。
如果一个类成员前面有public,则说明该成员能够被声明它的类之外的代码访问(与public相对的是private,它禁止成员被所属类之外的代码访问)。
在本例中,main( )必须被定义为public类型,因为当程序开始执行时它需要被它的类之外的代码调用。
关键字static允许调用main( )而不必先实现该类的一个特殊实例。
这是必要的,因为在任何对象被创建之前,Java解释器都会调用main()。
关键字void仅通知编译器main()不返回任何值。
你将看到,方法也可以有返回值。
如果这一切似乎有一点令人费解,别担心。
所有这些概念都将在随后的章节中详细讨论。
前面已经介绍过,main()是Java程序开始时调用的方法。
请记住,Java是区分大小写的。
因此,main与Main是不同的。
Java编译器也可以编译不包含main()方法的类,但是Java解释程序没有办法运行这些类。
因此,如果你输入了Main而不是main,编译器仍将编译你的程序,但Java解释程序将报告一个错误,因为它找不到main()方法。
你要传递给方法的所有信息由方法名后面括号中指定的变量接收,这些变量被称为参数(parameters)。
即使一个方法不需要参数,你仍然需要在方法名后面放置一对空括号。
在main()中,只有一个参数,即Stringargs[],它声明了一个叫做args的参数,该参数是String类的一个实例数组(注:
数组是简单对象的集合)。
字符串类型的对象存储字符的串。
在本例中,args接收程序运行时显示的任何命令行参数。
本例中的这个程序并没有使用这些信息,但是本书后面讲到的其他一些程序将使用它们。
该行的最后一个字符是“{”。
它表示了main()程序体的开始。
一个方法中包含的所有代码都将包括在这对花括号中间。
另外,main( )仅是解释器开始工作的地方。
一个复杂的程序可能包含几十个类,但这些类仅需要一个main( )方法以供解释器开始工作。
当你开始引用被嵌入在浏览器中的Java小应用程序时,你根本不用使用main( )方法,因为Web浏览器使用另一种不同的方法启动小应用程序。
接下来的代码行如下所示。
请注意,它出现在main( )内。
System.out.println("ThisisasimpleJavaprogram.");
本行在屏幕上输出字符串“ThisisasimpleJavaprogram.”,输出结果后面带一个空行。
输出实际上是由内置方法println()来实现的。
在本例中,println()显示传递给它的字符串。
你将会看到,println()方法也能用来显示其他类型的信息。
该行代码开始于System.out,
现在对它作详细说明为时尚早,需涉及很多复杂内容。
简单的说,System是一个预定义的可访问系统的类,out是连接到控制台的输出流。
可能你已经猜到了,控制台输出(输入)在实际的Java程序和小应用程序中并不经常使用。
因为绝大多数现代计算环境从本质上讲都是窗口和图形界面的,控制台I/O主要被用简单的实用工具程序和演示程序使用。
在本书后面,你将会学到用Java生成输出的其他方法。
但是目前,我们将继续使用控制台I/O方法。
请注意,println()语句以一个分号结束。
在Java中,所有的语句都以一个分号结束。
该程序的其他行没有以分号结束,这是因为从技术上讲,它们并不是程序语句。
程序中的第一个“}”号结束了main( ),而最后一个“}”号结束类Example的定义。
2.3第2个示例程序
对于编程语言来说,变量是一个最为基本的概念。
你可能知道,变量是一个有名字的内存位置,它能够被赋值。
而且,在程序的运行过程中,变量的值是可以改变的。
下一个程序将介绍如何声明变量,如何给变量赋值。
另外,该程序也说明了控制台输出的某些新特点。
从程序开始的注释可以看出,你应该把这个文件命名为Example2.java。
/*
Hereisanothershortexample.
Callthisfile"Example2.java".
*/
classExample2{
publicstaticvoidmain(Stringargs[]){
intnum;//thisdeclaresavariablecallednum
num=100;//thisassignsnumthevalue100
System.out.println("Thisisnum:
"+num);
num=num*2;
System.out.print("Thevalueofnum*2is");
System.out.println(num);
}
}
运行该程序时,你将会看到如下的运行结果:
Thisisnum:
100
Thevalueofnum*2is200
让我们来进一步查看这个结果是如何产生的。
我们重点考虑与前一示例不同的代码,在上一个程序中未出现的第一行代码是:
intnum;//thisdeclaresavariablecallednum
该行声明了一个名为num的整型变量。
和其他大多数语言一样,在Java中一定要先声明变量,然后再使用变量。
下面是声明变量的一般形式:
typevar-name;
在这里,type表示所要声明的变量的类型,va
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 语言 概述
![提示](https://static.bdocx.com/images/bang_tan.gif)