零点起飞学Java
第 5章 面向对象编程
除了基本的类和对象,Java语言的面向对象编程还包括抽象类、接口、内部类及包等
高级特性。通过对这些高级特性的支持,Java语言全面实现了面向对象的编程。本章将进
一步深入介绍 Java语言面向对象编程方面的知识。
5.1 类的三大特性
第 4章介绍了有关类定义的基本知识。面向对象中的类还具有封装、继承与多态的特
性,这也是面向对象编程所具有的重要特点。Java语言对类的封装、继承及多态均有很好
地体现,下面分别进行介绍。
5.1.1 隐藏细节——封装
封装是...
第 5章 面向对象编程
除了基本的类和对象,Java语言的面向对象编程还包括抽象类、接口、内部类及包等
高级特性。通过对这些高级特性的支持,Java语言全面实现了面向对象的编程。本章将进
一步深入介绍 Java语言面向对象编程方面的知识。
5.1 类的三大特性
第 4章介绍了有关类定义的基本知识。面向对象中的类还具有封装、继承与多态的特
性,这也是面向对象编程所具有的重要特点。Java语言对类的封装、继承及多态均有很好
地体现,下面分别进行介绍。
5.1.1 隐藏细节——封装
封装是指隐藏对象的属性及实现细节,对外仅提供接口可见。封装实现了信息隐藏,
有利于软件复用。这种技术带来的好处是达到了模块化的
,从而提高了代码的复用程
度。在某种程度上,封装也大大改善了软件开发的可维护性,降低了构建复杂软件系统的
风险。
在 Java语言中,对象的属性和方法均可以进行访问控制。使用前面介绍的访问控制修
饰符 public、private、protected 和 default,可以实现不同程度的信息封装。下面通过一个
具体的示例来介绍 Java语言中封装的实现。
【示例 5-1】 定义一个电视机类 TV,其代码如下所示。
01 public class TV() {
02 private int volume;
03 private int color;
04
05
06 public int getVolume() {
07 return volume;
08 }
09
10
11 public void setVolume(int volume) {
12 this.volume = volume;
13 }
14
15
16 public int getColor() {
类 TV
音量 volume 属性 颜色 color
查看音量 getVolume()
设置音量 setVolume ()
查看颜色 getColor()
设置颜色 setColor()
开机 turnOn()
方法
关机 turnOff()
第 5章 面向对象编程
·65·
17 return color;
18 }
19
20
21 public void setColor(int color) {
22 this.color = color;
23 }
24
25
26 public void turnOn() {
27 turnOn_impl(); //调用内部开机实现
28 }
29
30
31 public void turnOff() {
32 turnOff_impl(); //调用内部关机实现
33 }
34
35 //开机内部实现
36 private void turnOn_impl() {
37 //...
38 //电视机内部部件实现开机
39 }
40
41 //关机内部实现
42 private void turnOff_impl() {
43 //...
44 //电视机内部部件实现关机
45 }
46
47 }
分析:上面代码定义了一个电视机类 TV,包含音量 volume 和颜色 color 两个属性。
还定义了一些方法,包括音量、颜色的查看、设置方法,电视机的开、关方法及开、关的
内部实现方法。
从类的属性可以看到,音量 volume和颜色 color属性均定义成 private私有类型,只能
通过相关方法对其值进行操作。类 TV对其属性 volume和 color实现了封装,只能通过外
部的具体动作影响其值。在某些情况下,比如想限制用户读取其值,只要将对应的 get 方
法也设置成 private即可。
类 TV的方法中开机、关机的内部实现也被封装成 private方法,不允许用户直接调用。
用户在外面只能看到类 TV 提供的公开开机、关机方法,不知道具体的实现细节。在程序
中内部实现方法也略去了具体实现,在现实过程中这将是一个很复杂的过程,需要调用多
个零部件联合完成。
在实际编程过程中,具体哪个对象的哪些属性、方法需要封装,封装到什么力度,需
要视具体情况分析而定。而这种分析也已经上升为设计领域,需要读者对面向对象思想有
更深的领悟及更多的相关领域经验。
5.1.2 变相“抄袭”——继承
继承是指一个类是从另一个类派生而来的,派生类自动具有了被继承类的所有特性。
第 1篇 Java开发基础
·66·
其中被继承的类称为“父类”,继承父类的类称为“子类”。继承可以使子类具有父类的
各种属性和方法,而不需要再次编写相同的代码。继承也极大地促进了软件的复用,而且
继承的形式可以更加复杂。Java语言中类继承的语法格式如图 5.1所示。
图 5.1 继承语法图
【示例 5-2】 对电视机类实现一个比较简单的继承,其代码如下所示。
01 class TV {
02 int volume = 1;
03
04
05 public void setVolume(int volume) {
06 this.volume = volume;
07 }
08 }
09
10 class GeneralTV extends TV {
11 public static void main(String args[]) {
12 GeneralTV tv = new GeneralTV ();
13
14 System.out.println(tv.volume);
15 tv.setVolume(10);
16 System.out.println(tv.volume);
17 }
18 }
程序执行结果如下:
1
10
分析:以上代码实现了一个比较简单的继承。首先定义了类 TV,代表各种电视的基
类。类 TV包含 default类型的属性 volume和 public类型的方法 setVolume()。然后定义了
类 GeneralTV,代表黑白电视。类 GeneralTV继承自类 TV,作为类 TV的子类。类 GeneralTV
没有定义自己的任何属性,方法也仅包含一个 main()方法。main()方法中创建了类
GeneralTV的一个对象 tv,首先打印 tv的属性 volume(该属性继承自类 TV),打印结果
为 1。然后,调用继承自类 TV的方法 setVolume()。最后再次打印 tv的属性 volume,打印
结果为 10。
父类 TV
父类变量 volume
父类方法 setVolume()
子类对象 tv
继承父类变量 tv.volume
继承父类方法 tv.setVolume(10)
子类 GeneralTV
子类变量 volume
子类方法 setVolume()
实例化类对象
继承自父类
第 5章 面向对象编程
·67·
注意:子类无法继承父类中使用 private修饰符修饰的类成员。前面章节也讲过类中限定
为 private的成员只能被这个类本身访问。比如示例 5-2中,如果属性 volume被
定义为 private,则语句 tv.volume会报错。
子类除了继承父类的属性和方法外,还可以定义自己的属性和方法,这被称为类扩展。
扩展的子类既具有父类中普遍通用的功能特性,还具有自身独特的属性和方法,从而具有
更加完备的功能。
【示例 5-3】 在继承电视机类的同时,实现类的扩展,其代码如下所示。
01 class TV {
02 int volume = 1;
03
04 //定义 public方法 setVolume
05 public void setVolume(int volume) {
06 this.volume = volume;
07 }
08 }
09
10 class ColourTV extends TV {
11 private int color; //定义 private属性 color
12
13 public static void main(String args[]) {
14 ColourTV tv = new ColourTV();
15
16 System.out.println(tv.volume);
17 tv.setVolume(10);
18
19 System.out.println(tv.volume);
20
21 System.out.println(tv.color);
22 tv.setColor(5);
23 System.out.println(tv.getColor());
24 }
25
26 //得到属性 color
27 public int getColor() {
28 return color;
29 }
30
31 //设置属性 color
32 public void setColor(int color) {
33 this.color = color;
34 }
35 }
程序执行结果如下:
1
10
0
5
分析:以上代码在继承的同时,实现了类的扩展。同示例 5-2一样,首先定义了类 TV,
代表各种电视的基类。类 TV 包含 default 类型的属性 volume 和 public 类型的方法
setVolume。
子类对象 tv
子类自身属性 color
getColor() 子类自身方法
setColor(int color)
继承父类变量 tv.volume
继承父类方法 tv.setVolume(10)
调用自身属性 tv.color
调用自身方法 tv.setColor(5)
第 1篇 Java开发基础
·68·
然后定义了类 ColourTV,代表彩色电视。类 ColourTV 同样继承了父类 TV 的属性
volume()和 setVolume()方法。除了继承父类外,类 ColourTV还定义了自己的属性 color及
相应的获取、设置方法 getColor()、setColor()。Main()方法中先创建了类 ColourTV 的一个
对象 tv。然后也是调用相关父类的属性和方法,并进行打印。下面一组代码则调用类
ColourTV自身的属性和方法,并打印相关结果。
5.1.3 灵活应对——多态
多态是指对于一种服务功能,可以具有不同的实现方式,即多种形态。多态形象地描
述了现实世界的复杂形态,使程序具有良好的扩展性。在继承的基础上,方法重载是实现
多态的方式之一。
【示例 5-4】 用方法重载实现不同国家的人多态的问候方式的应用举例,其代码如下
所示。
01 class Human {
02
03
04 public void sayHello(char c) {
05 System.out.println("Hello!");
06 }
07
08 public void sayHello(String str) {
09 System.out.println("您好!");
10 }
11
12 }
13
14 public class TeatClass {
15
16 public static void main(Stringargs[])
17 {
18 Human human = new Human();
19 human.sayHello("s");
20 }
程序执行结果如下:
您好!
分析:以上代码首先定义了类 Human,还有一个 public方法 sayHello(char c)。然后重
载了 sayHello方法——sayHello (String str)。在测试类 TestClass中,创建 Human对象,并
调用了 sayHello (String str)方法,打印的结果为“您好!”。
说明:对于上述示例,父类更好的实现方式是采用抽象类或接口。有关抽象类或接口的
概念在 5.2节会详细介绍。
5.2 抽象类和接口
抽象类是 Java 语言中一种特殊的类,其中包含只进行了声明没有具体实现的抽象方
类对象 human
调用类方法 human.sayHello("s")
类 Human
sayHello(char c) 类方法
sayHello(String str)
实例化类对象
第 5章 面向对象编程
·69·
法。而接口更像是一种特殊的抽象类,其中所有方法都只进行了声明没有具体实现。抽象
类和接口有着相似之处,不过也有许多区别。本节将分别对它们进行详细地介绍。
5.2.1 抽象类
抽象类是指包含了抽象方法的类。其中,抽象方法只声明方法名称,而不指明方法体。
当需要表示对问题域进行分析、设计中得出的抽象概念时需要使用抽象类。抽象类比类的
继承更高一层,是对类的抽象。抽象类拥有未实现的方法,不能被实例化,只能被继承扩
展。通常 Java语言中抽象类的语法格式如图 5.2所示。
图 5.2 定义抽象类
注意:类体中至少包含一个抽象方法。抽象方法不含方法体,无需“{}”。
【示例 5-5】 定义一个简单的抽象类,其代码如下所示。
01 abstract class AbstractClass {
02
03 public void test1() {
04 System.out.println("this is test1!");
05 }
06
07 //定义抽象方法 test2,不含方法体
08 public abstract void test2();
09 }
10
11 public class SubClass extends AbstractClass {
12 //定义类 subClass,继承了抽象类 AbstractClass
13
14
15 //实现了抽象类中的 test2方法
16 public void test2() {
17 System.out.println("this is test2!");
18 }
19
20 public static void main(String args[]) {
21 SubClass sc = new SubClass();
22
23 sc.test1();
子类 SubClass
实现抽象方法 test2()
抽象类 AbstractClass
一般方法 test1()
抽象方法 test2()
实现抽象类
子类对象 sc
调用父类
一般方法 test1()
调用子类实现
的抽象方法 test2()
第 1篇 Java开发基础
·70·
24 sc.test2();
25 }
26 }
程序执行结果如下:
this is test1!
this is test2!
分析:此段代码首先定义了一个抽象类,类的名字为 AbstractClass。该类包含两个方
法,一个为一般方法 test1(),另一个是抽象方法 test2()。需要特别注意的是,test1()方法包
含方法体有具体的实现过程。test2()方法被 abstract修饰没有方法体,只是定义了方法结构。
然后定义了类 SubClass,该类继承了抽象类 AbstractClass。在类 SubClass内,实现了抽象
类 AbstractClass中的抽象方法 test2()。最后,在 main()方法中创建了类 SubClass的一个实
例,分别调用了 test1()方法和 test2()方法。
通过语法定义和示例可以看出,抽象类有如下特点:
至少包含一个抽象方法。
不能被实例化。
继承抽象类的子类必须实现其所有抽象方法才能实例化,否则该子类还是抽象类。
在具体使用方面,抽象类能更准确地模拟对问题领域的理解。而且它可以提供实现的
模式,使实现功能的代码更简单。抽象类一般用于关系密切的对象。其实在好多方面,抽
象类和接口有着相似之处。下面介绍接口的概念,会与抽象类作一些比较。
5.2.2 接口
接口是面向对象编程中又一重要概念。在实际问题中,有些互不相关的类具有某种相
同的行为,这时可以采用接口来定义这种行为。接口只定义提供什么功能,而不定义功能
的具体实现,这一点与抽象类似。在 Java语言中,不提供类的多继承,一个子类只能继承
自一个父类。为了解决多继承的问题,在 Java中可以采用接口来实现。一个类虽然不能同
时继承多个类,却可以同时实现多个接口,从而可以解决现实中的多继承问题。有关接口
的知识包括接口定义和接口实现,下面分别进行介绍。
1.接口定义
要使用接口,首先需要定义接口。接口定义的语法格式如图 5.3所示。
图 5.3 定义接口
一个接口可有多个父接口,用逗号隔开。另外在接口的接口体中,所有成员变量默认
第 5章 面向对象编程
·71·
为 public、static、final 类型。成员方法默认为 public 和 abstract 类型,只能包含常量及抽
象方法。
【示例 5-6】 定义一个简单的接口,其代码如下所示。
01 public interface InterfaceExm {
02 public static final int X = 1;
03 public void test();
04 }
分析:以上代码定义了一个比较简单的接口,接口名为 InterfaceExm。接口 InterfaceExm
的接口体包含 int型变量 X和方法 test()。
与一般类、抽象类相比,接口在定义方面有如下特点:
接口体只能包含常量及抽象方法。
接口可以继承多个接口,而类不能多继承。
接口不能包含构造方法。
2.实现接口
接口定义只规定了接口对外提供的功能定义,没有对功能具体实现。要真正使用接口
定义的功能,需要定义类实现接口。非抽象类实现接口主要是实现接口中定义所有抽象方
法。实现接口的语法格式如图 5.4所示。
图 5.4 实现接口
一个类可以实现多个父接口,用逗号隔开。另外,在类的类体中,应该实现父接口中
的所有抽象方法。
【示例 5-7】 接口实现的举例,其代码如下所示。
01 interface InterfaceExm {
02
03 public void test();
04 }
05
06 class TestClass1 implements
InterfaceExm {
07
08 public void test() {
09 System.out.println("this is first interface test!");
10 }
11 }
12
接口实现类 TestClass1
实现抽象方法 test()
实现接口
接口 InterfaceExm
接口变量 x
接口方法 test()
接口 InterfaceExm
接口方法 test()
实现接口
接口实现类 TestClass2
实现抽象方法 test()
第 1篇 Java开发基础
·72·
13 class TestClass2 implements
InterfaceExm {
14
15 public void test() {
16 System.out.println("this is
second interface test!");
17 }
18 }
19
20 public class Test {
21 public static void main
(String[] args) {
22 InterfaceExm ie;
23
24
25
26
27 ie = new TestClass1();
28
29 ie.test();
30
31
32
33
34 ie = new TestClass2();
35 ie.test();
36 }
37 }
程序执行结果如下:
this is first interface test!
this is second interface test!
分析:以上代码首先定义了一个比较简单的接口,接口名为 InterfaceExm,其只包含
一个抽象方法 test()。然后分别定义了两个接口实现类 TestClass1和 TestClass2,这两个类
都实现了接口 InterfaceExm。类 TestClass1和 TestClass2在类体内都分别实现了接口中的抽
象方法 test(),实现的不同是打印不同的语句。最后定义了一个测试类 test,只包含一个main()
方法。main()方法中首先定义了接口 InterfaceExm类型变量 ie,然后分别对变量 ie赋予不
同的值,分别为 TestClass1对象和 TestClass2 对象,并同时调用接口 InterfaceExm的抽象
方法 test。程序执行结果为打印出不同的语句。
通过示例的执行结果可以看出,虽然调用的形式都是接口 InterfaceExm的方法 test(),
但由于来自不同的对象,具有不同的实现,所以执行的结果各不相同。这也是通常使用接
口的一种方式。
最后
一下,在实现接口方面有如下特点:
一个类可以同时实现多个接口。
接口不能被实例化,只能通过类实现接口的抽象方法。
虽然接口不能被实例化,但可以定义接口类型变量。
当类实现接口时,非抽象类必须实现所有抽象方法,否则为抽象类。
类 Test
类型 InterfaceExm 类变量
名称 ie
TestClass2对象 ie
调用接口方法 ie.test()
TestClass1对象 ie
调用接口方法 ie.test()
第 5章 面向对象编程
·73·
5.3 类中类——内部类
内部类指的是在类的内部嵌套定义的类。内部类本身的结构同普通类没什么不同,只
不过定义的位置是在另一个类的内部。定义的内部类同样可以被外部引用。内部类可以只
定义类体,没有名称,这就是匿名内部类。关于内部类的这些知识下面分别进行介绍。
5.3.1 内部类
根据内部类的概念,内部类定义的位置是在类的内部。在一个类的任意代码块内,均
可以进行内部类的定义。如可以直接作为类成员定义,可以定义在类的成员方法内及循环
体内等。
【示例 5-8】 定义一个简单内部的类,其代码如下所示。
01 public class Outer {
02 private int x = 1;
03
04
05 void sayHello() {
06 System.out.println("Hello!");
07 }
08
09 class Inner {
10 int y = 0;
11
12 void test() {
13 System.out.println(x);
14 sayHello();
15 }
16 }
17 }
分析:首先程序最外层定义了外部类 Outer,类 Outer 包含成员变量 x 和成员方法
sayHello()。然后,作为类 Outer的成员,定义了内部类 Inner。内部类 Inner有自己的成员
变量 y,自己的成员方法 test()。在内部类 Inner的成员方法 test()中,第一行代码打印了外
部类 Outer的成员变量 x的值,第二行代码调用了外部类 Outer的成员方法。
通过示例可以看出,内部类可以任意访问外部类中的成员。在其他代码块中定义内部
类与示例类似,这里不再举例说明。
需要特别说明的是,内部类可以被修饰为 static 属性,这在普通类是不行的。修饰为
static的内部类相当于提升了类的层次,变成了外部类,当然也不能再访问外部类的非 static
成员。
【示例 5-9】 定义一个 static内部类,其代码如下所示。
01 public class Outer {
02 static class Inner {
//定义内部类 static成员变量 x
03 static int x = 0;
外部类 Outer
类变量 x
类方法 sayHello()
内部类 inner
类变量 y
类方法 test()
第 1篇 Java开发基础
·74·
04
05
06 //定义内部类 static成员方法 test
07 static void test() {
08 System.out.println("test");
09 }
10 }
11
12 public static void main(String
args[]) {
13 System.out.println(Outer.Inner.x);
14
15 Outer.Inner.test();
16
17 }
18}
程序执行结果如下:
0
test
分析:同样,程序最外层定义了外部类 Outer。然后定义了内部类 Inner,并且被修饰
为 static 属性。内部类 Inner 具有 static 类型成员变量 y,static 成员方法 test()。在外部类
Outer中定义了 main()方法。main()方法第一行代码打印了内部类 Inner的成员变量 x的值,
第二行代码调用了内部类 Inner的成员方法 test()。
注意:static内部类可以包含 static成员,而非 static内部类却不可以包含 static成员。
5.3.2 “更隐蔽”的内部类——匿名内部类
匿名内部类是一种没有类名的特殊内部类。就像仅使用一次的变量可以不定义名称一
样,匿名内部类也是用作定义仅使用一次的类。匿名内部类通常具有特殊的用途,也能使
程序显得更加简洁。
【示例 5-10】 使用匿名内部类实现“Say Hello”功能的应用举例,其代码如下所示。
01 abstract class SayHello {
02
03 public abstract void hello();
04 }
05
06 public class Test {
07
08 //定义方法 hello,参数为抽象类 SayHello类型
09 public void hello(SayHello sh) {
10 sh.hello();
11 }
12
13 //定义 main方法
14 public static void main(String args[]) {
15 Test t = new Test();
类 Test
类方法 hello()
类对象 t
调用类方法 t.hello()
抽象类 sayHello
抽象方法 hello()
实例化类对象
内部类 inner
类变量 x
类方法 test()
外部类 outer
调用内部类变量 Outer.Inner.x
调用内部类方法 Outer.Inner.test()
第 5章 面向对象编程
·75·
16
17 //调用 Test的方法 hello,参数为匿名内部类
18 t.hello(new SayHello() {
//实现了抽象类 SayHello的方法 hello
19 public void hello() {
20
21
22 System.out.println("Hello!");
23 }
24 }
25 );
26 }
27}
程序执行结果如下:
Hello!
分析:以上代码首先定义了一个抽象类 SayHello,包含一个抽象方法 hello()。然后定
义类 Test,类 Test包含成员方法 hello()。Test的成员方法 hello()参数为抽象类 SayHello类
型,方法体调用参数变量 sh的 hello()方法。最后,类 Test定义了 main()方法。main()方法
体首先创建了类 Test的对象 t,然后调用了 t的方法 hello()。关键就在这里,调用 t的方法
hello()时,参数为一段代码,这段代码其实就定义了一个匿名内部类。匿名内部类没有类
名,直接用 new关键字创建对象,后面{}部分为匿名内部类的类体。
通过示例可以看出,使用匿名内部类可以不用定义类名,直接创建类的对象。匿名内
部类适用于为该类只创建一个对象的场合,在后续章节将介绍的图形界面部分会经常使用
匿名内部类。对于初学者来说,刚接触匿名内部类会比较困惑。要解决这个问题,需要多
结合具体程序实例,多多练习、揣摩,从而能够加深理解,对其很好地掌握。
5.4 类的仓库——包
在面向对象编程中,包是 Java语言所特有的概念。包用来将相关的一组类组织在一起
进行管理,类似操作系统中的文件管理。包在外在形式上就是操作系统中的文件夹,包的
就是类文件。不同的包可以包含同名的类,包机制有效解决了命名冲突问题。有关包
的知识包括创建包和使用包,下面将分别进行介绍。
5.4.1 创建包
在使用包之前,首先需要创建包。创建包的语法格式如下所示。
图 5.5 创建包
匿名内部类 new SayHello()
实现抽象类方法 hello()
第 1篇 Java开发基础
·76·
【示例 5-11】 创建包的实例,其代码如下所示。
01 package TestPackage; //声明所属包为 TestPackage
02
03 public class Test {
04 //类体
05 }
分析:以上代码首先定义了一个包,包名为 TestPackage。然后定义了一个类 Test,该
类所在的包即为 TestPackage。
包可以多个层次嵌套,也就是包内还可以有包。Java语言中的包在外在形式上对应着
操作系统中的目录结构。嵌套的包用“.”号分隔,对应于操作系统,也就是目录中还具有
目录。比如“com.sun”,第一级包为 com,包 com内包含第二级包 sun。在操作系统中,
存在名为 com的目录,com目录下又具有名为 sun的目录。
注意:在编写程序过程中,package语句必须写在类文件的最上面。
5.4.2 使用包
创建了包之后,经常需要使用不同包中的类。使用不同包中的类主要具有两种形式:
包名加类名形式和 import导入形式。另外,在 Java SE 5.0版本之后,还提供了静态导入功
能。对这些内容,下面将分别进行介绍。
1.包名加类名
第一种形式采用包名加类名的方式,语法格式如图 5.6所示。
图 5.6 包名加类名使用包
其中,参数 PackageName1、PackageName2和 PackageName3…表示多层次的包的调用,
可以支持任意层次。
注意:此种形式的使用需要使用完整的包路径。完整的包路径就是从最顶层的包直到包
含该类文件的最底层的包的完整路径结构。并且,所有引用该类的地方都要加完
整的包路径。
【示例 5-12】 使用包中的类的第一种形式举例,其代码如下所示。
01 package TestPackage;
02
03 public class Test {
//引用包路径“java.util.regex”下的类 Pattern
04 java.util.regex.Pattern p1;
05 //引用包路径“java.util.regex”下的类 Pattern
第 5章 面向对象编程
·77·
06 java.util.regex.Pattern p2; }
分析:以上代码定义了一个类 Test,该类属于包 TestPackage。Test类定义了两个成员
变量,变量类型为外部包“java.util.regex”下的 Pattern类。可以注意到,虽然两个变量都
是引用同一个类 Pattern,但是每个变量的类型引用前都要包含完整的包路径。
2.import导入
第二种形式采用 import语句导入的方式,语法格式如图 5.7所示。
图 5.7 import导入包
这种形式首先使用 import语句将要使用的类所在的包导入,包为完整路径。导入包后,
就可以在程序的任意位置引用包中的类,类名前不用再加第一种形式中的那种完整包路径。
【示例 5-13】 使用包中的类的第二种形式举例,其代码如下所示。
01 package TestPackage;
02
03 import java.util.regex.Pattern; //导入包
04
05 public class Test {
06 Pattern p1;
07 Pattern p2;
08 }
分析:同形式一的示例一样,该示例定义了一个 Test 类,该类属于包 TestPackage。
Test类同样定义了两个成员变量,变量类型都为 Pattern。不同的是,变量类型 Pattern前没
有形式一示例中的完整的包名,Pattern类所在的包在程序开始处通过 import语句导入,使
程序更加简洁。
相对于包名加类名的形式,实际编程过程中更多的是使用 import导入形式。许多 Java
集成开发环境支持包导入的快捷键,采用 import导入形式编写程序更方便和简洁。
技巧:如果要用到一个包中的多个类,可以采用“import PackageName1. PackageName2.
PackageName3…*”的形式同时导入包中的所有类。
3.静态导入
静态导入是 Java SE 5.0 之后提供的功能,其语法格式如图 5.8所示。
图 5.8 静态导入
第 1篇 Java开发基础
·78·
静态导入与普通导入的区别就是在导入的对象之前增加了 static 修饰符。下面通过具
体的实例说明静态导入的作用。
【示例 5-14】未采用静态导入,实现打印圆面积的实例,其代码如下所示。
01 import util.Constant; //导入 Constant类
02
03 public class Test {
04 public static void main(String args[]) {
05 //打印圆的面积
06 double r = 3.0; //半径
07 double zz = Constant.PI * r * r; //面积
08
09 System.out.println(zz);
10 }
11
12 }
导入的 Constan类的代码如下所示。
01 package util;
02
03 public class Constant {
04 public static final double PI = 3.14; //定义常量 pai
05 }
程序执行结果如下:
28.259999999999998
分析:Test类的 main()方法实现了打印圆面积的功能。其中,用到的常量 PI在 util包
中的 Constant 类中定义。在 Test 类的头部导入了 Constant 类,使用常量 PI 的格式为
“Constant.PI”。
上面的实例代码未采用静态导入的形式。下面采用静态导入的方式对原实例进行改
造。改造后的代码如下所示。
01 import static util.Constant.PI; //静态导入 Constant类
02
03 public class Test {
04 public static void main(String args[]) {
05 //打印圆的周长
06 double r = 3.0; //半径
07 double zz = PI * r * r; //周长
08
09 System.out.println(zz);
10 }
11
12 }
程序执行结果如下:
28.259999999999998
其中,Constant 类的代码没有变化。可以看出,在采用了静态导入之后,可以直接使
用导入类中的变量,不需再采用“Constant.”的形式。对于使用导入类的方法的情况也是
一样。
第 5章 面向对象编程
·79·
5.5 小 结
本章进一步深入地介绍了 Java语言中面向对象编程的相关知识,包括类的封装、继承、
多态以及抽象类、接口、内部类和包等。本章最后给出了一个完整的实例。其中抽象类与
接口的具体运用是本章的难点。抽象类与接口是面向对象编程中更加抽象的概念,要想能
真正发挥它们的特点需要多结合具体需求反复实践。第 6章将介绍 Java语言中复合数据类
型相关的内容,如数组、字符串、集合等。
5.6 习 题
1.定义一个 Person 类,声明 id、name 和 age 成员变量,以及 getId()、getName()和
getAge()等成员方法。
【分析】本题主要考查读者对类的封装的掌握。
【核心代码】本题的关键代码如下所示。
public class Person {
int id;
String name;
int age;
public int getId(){
return id;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}
2.定义 Person 类,声明 int 型变量 id,初始化为 7,声明方法 setId()。定义 Student
类继承于 Person类,创建 student对象,调用父类的 setId()方法,然调用父类的 id变量,
输出 set后的 id值。运行结果如下。
6
【分析】本题主要考查读者对类的继承的掌握。子类继承父类之后,就可以调用父类
中不被声明为 private的变量和方法。
【核心代码】本题的关键代码如下所示。
public class Student extends Person{
public static void main(String[] args) {
Student student = new Student();
第 1篇 Java开发基础
·80·
student.setId(6);
System.out.println(student.id);
}
}
class Person {
int id = 7;
public int setId(int id){
this.id = id;
return id;
}
}
3.定义 Human 类,还有一个 public 方法 sayHello (String str)。然后重载了 sayHello
方法——sayHello(char c)。在测试类 TestClass中,创建Human对象,并调用了 sayHello (char c)
方法,输出结果。运行结果如下。
Hello
【分析】本题主要考查读者对类的多态中方法重载的掌握。重载的方法具有相同的方
法名,只是方法的参数类型不同。
【核心代码】本题的关键代码如下所示。
class Human {
public void sayHello(String str) {
System.out.println("您好!");
}
public void sayHello(char c) {
System.out.println("Hello!");
}
}
public class TeatClass {
public static void main(String args[]) {
Human human = new Human();
human.sayHello('c');
}
}
本文档为【零点起飞学Java】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。