接口、抽象与包
主讲人,xxxx
重庆信息学院软件一系
Java精品课程
本章内容
? 4.1 接口
? 4.2 抽象类
? 4.3 包
教学目标
掌握接口的声明与实现,理解抽象类和抽象
方法,了解包的声明与引用、系统程序包。
重点、难点
? 重点是接口声明与实现,抽象类与抽象方法。
? 难点是理解抽象类和抽象方法。
课前思考
? 什么是抽象类、接口?它们各自又有哪些
特性?
? 你知道 java语言在面向对象编程方面有何独
特的特点吗?
4.1 接口( interface)
接口
接口是抽象类的一种,只包含常量和方法的
定义,而没有变量和方法的实现,且其方法都是
抽象方法。它的用处体现在下面几个方面:
◇ 通过接口实现不相关类的相同行为,而无需
考虑这些类之间的关系。
◇ 通过接口指明多个类需要实现的方法。
◇ 通过接口了解对象的交互界面,而无需了解
对象所对应的类。
1)接口的定义
接口的定义包括接口声明和接口体。
接口声明的格式如下:
[public] interface interfaceName[extends
listOfSuperInterface] { … }
extends 子句与类声明的 extends子句基本相同,不
同的是一个接口可有多个父接口,用逗号隔开,而一
个类只能有一个父类。
接口体包括常量定义和方法定义
常量定义格式为,type NAME=value; 该常量被实
现该接口的多个类共享 ; 具有 public,final,static的属
性。在接口中只能声明常量,不可以声明变量。
方法体定义格式为,(具有 public和 abstract属性,
不能声明为 protected)
returnType methodName([paramlist]);
注意:在接口的实现类中,实现的接口方法必须声明为 public,因为接口
中定义的方法为 public(默认)。所以其实现必须声明为 public.否则编
译不会通过。
补充
? 由于接口中不能有初始化块和构建器,所以
在定义有名常量时必须包含初始化表达式
? 接口中的方法不能被声明为 static,因为类
方法不是抽象的。
2) 接口的实现
在类的声明中用 implements子句来表示一个类使用某个
接口,在类体中可以使用接口中定义的常量,而且必须实
现接口中定义的所有方法。一个类可以实现多个接口,在
implements子句中用逗号分开。
3) 接口类型的使用
接口作为一种引用类型来使用。任何实现该接口的类的
实例都可以存储在该接口类型的变量中,通过这些变量可
以访问类所实现的接口中的方法。
例 1、接口定义
? public interface A{ }
? 也可以用 extends去继承已有的接口
public interface A extends B //B是已定义了的接口
{ }
? 在类中使用接口需要使用关键字 implements:
public class A implements B //这里 A为类,B为接口
{ }
√ Java类只允许单一继承,即一个类只能继承 (extends)一个父类;但一个类可
以实现多个接口,Java支持接口的多重继承。在 Java类定义中,可以同时包括
extends子句和 implements子句,如果存在 extends子句,则 implements子句应跟
随 extends子句后面。
例 2 接口实现
? interface A{
? int x = 1;
? void method1();
? }
? interface B extends A{
? int x = 2;
? void method2();
? }
? public class Example implements B{
? public void method1(){
? System.out.println("x = " + x);
? System.out.println("A.x = " + A.x);
? System.out.println("B.x = " + B.x);
? System.out.println("Example.x = " + Example.x);
? }
? public void method2(){
? }
? public static void main(String[] args){
? Example d = new Example();
? d.method1();
? }
? }
例 3接口作为类型
? class Worker implements Runnable{
? public void run(){
? System.out.print("Worker run!");
? }
? }
? public class Server{
? public static void main(String[] args){
? Runnable w = new Worker();
? (new Thread(w)).start();
? }
? }
接口不应改变
? 修改某个接口,为其添加一个方法,这个简单的
修改可能会造成牵一发而动全身的局面:所有实
现这个接口的类都将无法工作,因为现在他们已
经不再实现这个接口了。你要么放弃对这个接口
的修改,要么连同修改所有实现这个接口的所有
类。
? 在设计接口的最初,预测出接口的所有功能,这
可能是不太现实。如果觉得接口非改不行,可以
创建一个新的接口或者扩展这个接口,算是一种
折衷的解决方法。其他相关的类可以保持不变,
或者重新实现这个新的接口。
4.2 抽象类
什么是抽象
抽象就是抽出事物的本质特性而暂时不考虑
它们的细节。过程抽象和数据抽象是常用的
两种主要抽象手段。
客观世界的
对象和操作
计算机算法
解空间
数据
程序员对问题的表达(抽象)
客观世界的算法
结果
客观世界的
对象
程序设计的
对象和操作
输出数据
问题空间
如何用面向对象的方法实现抽象
一个抽象数据类型( Abstract Data Type,
ADT)可以分解成 4个部分,如图 4-2所示。
语法和语义构成抽象数据类型 ADT的说明,
让使用者了解这个抽象数据类型的特征。属
性和方法构成 ADT的实现,展示这个 ADT
是怎样做成的。
抽象数据类型
说明
实现
语法
语义
属性
方法
? 当一个类被声明为 abstract时, 这个类被称为是抽象类 。
所谓抽象类就是没有具体实例对象的类 。
? 针对这个问题, Java专门提供了一种机制, 名为, 抽象方
法, 。 它属于一种不完整的方法, 只含有一个声明, 没有
方法主体 。 下面是抽象方法声明时采用的语法:
? abstract void X();
? 人类就是一个典型的抽象类 。 我们知道, 类是对象的集合,
对象是类的实例化, 而人类这个类却不存在一个仅属于它
的具体对象 。
抽象方法
? 作为类方法修饰符, abstract则声明了一种
仅有方法头, 而没有具体的方法体和操作实
现的抽象方法 。
可见, abstract方法只有方法头的声明, 而
用一个分号来代替方法体的定义:至于方法
体的具体实现, 那是由当前类的不同子类在
它们各自的类定义中完成的 。
? 需要特别注意的是,所有的抽象方法,
都必须存在于抽象类之中。
? 除了抽象方法,抽象类也可以有具体的
数据和方法。例如,Person类存储人的
名字并且用一个具体的方法来返回它。
? 在 Java编程语言中抽象方法是非常重要
的概念。在接口里你会大量的用到它。
? 抽象方法只能出现在抽象类中

? abstract class Graphic{
? public static final double PI = 3.1415926;
? double area(){
? return 0;
? };
? abstract void draw();
? }
? class Point extends Graphic{
? protected double x,y;
? public Point(double x,double y) {
? this.x = x;
? this.y = y;
? }
? void draw(){
? //在此实现画一个点
? System.out.println("Draw a point at ("+x+","+y+")");
? }
? public String toString(){
? return "("+x+","+y+")";
? }
? }
? class Line extends Graphic{
? protected Point p1,p2;
? public Line(Point p1,Point p2){
? this.p1 = p1;
? this.p2 = p2;
? }
? void draw(){
? //在此实现画一条线
? System.out.println("Draw a line from "+p1+" to "+p2);
? }
? }
? class Circle extends Graphic{
? protected Point o;
? protected double r;
? public Circle(Point o,double r) {
? this.o = o;
? this.r = r;
? }
? double area() {
? return PI * r * r;
? }
? void draw() {
? //在此实现画一个圆
? System.out.println("Draw a circle at "+o+" and r="+r);
? }
? }
? public class GraphicDemo{
? public static void main(String []args){
? Graphic []g=new Graphic[3];
? g[0]=new Point(10,10);
? g[1]=new Line(new Point(10,10),new Point(20,30));
? g[2]=new Circle(new Point(10,10),4);
? for(int i=0;i<g.length;i++){
? g[i].draw();
? System.out.println("Area="+g[i].area());
? }
? }
? }
抽象类和接口的比较
? 抽象类在 Java语言中体现了一种继承关系,要想使得继承关系
合理,抽象类和继承类之间必须存在 "是一个 (is a)"关系,即抽
象类和继承类在本质上应该是相同的。而对于接口来说,并不
要求接口和接口实现者在本质上是一致的,接口实现者只是实现了接口定义的行为而已。
? Java中一个类只能继承一个父类,对抽象类来说也不能例外。
但是,一个类却可以实现多个接口。在 Java中按照继承关系,
所有的类形成了一个树型的层次结构,抽象类位于这个层次中
的某个位置。而接口却不曾在这种树型的层次结构,位于树型
结构中任何位置的任何类都可以实现一个或者多个不相干的接口。
? 在抽象类的定义中,我们可以定义方法,并赋予的默认行为。
而在接口的定义中,只能声明方法,不能为这些方法提供默认
行为。抽象类的维护要比接口容易一些,在抽象类中,增加一
个方法并赋予的默认行为,并不一定要修改抽象类的继承类。
而接口一旦修改,所有实现该接口的类都被破坏,需要重新修改。
7.3包
? 包在 JAVA中的作用:
文件夹将文件和应用程序组织为组,包将类组织为组
包减少了命名冲突带来的问题,如果所有类放在同一个包中
就容易产生命名冲突
? 引入包以后,声明类前必须声明类所在的包,格式:
package 包 1名,包 2名 … 包 n名 ;
例如, package java.awt; 或, package javax.swing.event;
如果一个类访问另一个包中的类,必须通过包来引用,有两种引用
方法
1) 声明该类前,使用 import语句
例如,import java,awt.Button; //Button为被访问的类,位于包
java,awt中
import java,awt.*; //引入包 java,awt中的全部类
2)访问另一个包中的类时,使用包名
例如,java,awt.Button b=new java,awt.Button ();
Example(自定义包使用)
? // example one
? //类在同一个包中
? public class Date2
? { int year,month,day;
? void setDate(int y,int m,int d)
? { year=y; month=m; day=d; }
? void print()
? {System.out.println(year+" "+month+" "+day);}
? }
? class UseDate2
? {
? public static void main(String args[])
? { Date2 b=new Date2();
? b.setDate(2004,9,1);
? b.print();
? }
? }
//类在不同包中
//Date2.java
package p1.p2;
public class Date2
{ int year,month,day;
public void setDate(int y,int m,int d)
{ year=y; month=m; day=d; }
public void print()
{System.out.println(year+" "+month+" "+day);}
}
//UseDate2.java
import p1.p2.Date2;
class UseDate2
{
public static void main(String args[])
{ Date2 b=new Date2();
b.setDate(2004,9,1);
b.print();
}
}
Example 在 DOS窗口下的运行
DOS窗口下必须手动建立包
一 编译 Date2.java
1) 建立保存 p1.p2.Date2的文件夹,例如 E:\db031
2) 设置环境变量,右击我的电脑选属性、高级、环境变量,双
击系统变量中的 CLASSPATH,在变量值中加入保存
p1.p2.Date2的文件夹,例如 ; E:\db031(不要忘了环境变量以;
隔开)
3) E:\db031下建立 p1和 p2文件夹,将 Date2.java保存
E:\db031\p1\p2下
4) 打开 DOS窗口,进入 Date2所在目录,即 E:\db031\p1\p2 。
打开 DOS窗口的方法, 显示器左下角,点击开始、程序、附件、
命令提示符;
进入 E:\db031\p1\p2 的方法:
切换 C,\> E,即输入 E:然后回车(如文件保存在 C
盘,不须切换);
进入 E\> cd \db031\p1\p2
5) 编译,E,\db031\p1\p2>javac Date2.java 并回车
二 编译并运行 UseDate2.java
1) 建立保存 UseDate2的文件夹,例如:
C:\db032
2) 保存 UseDate2.java,编译 javac
UseDate2.java 3)
3) 运行 C:\db032下 java
q.UseDate2.java
Example 在 Jcreator下的运行
Jcreator下,系统按源文件中的 package语句自动建立包
1) 建立保存 p1.p2.Date2的空 project,例如 E:\db031,保存
Date2.java并编译,可看到 p1和 p2已经自动生成
2) 编译 UseDate2.java
3)建立保存 UseDate2.java的空 project,保存
UseDate2.java,此时编译会报错
4)设置环境变量
在 Jcreator主菜单的 project下选择 project settings…
选择 required libraries后按 new…
选择 classes后按 add 选 add path,找到 p1.p2.Date2所
在文件夹 (E:\db031)
在 Name中给该路径命名,按 OK
此时可看到该路径名出现在文本框中,选中该路径名,可
看到该路径已加入到 ClassPath中
5)编译 UseDate2.java并运行
环境变量 classpath的配置
Classpath的作用
当一个类访问位于其它包中的其它类时,Classpath帮助该
类找到其它类,
Classpath的值,Classpath就是包含被访问的类所在的包的文
件夹
被访问的类所在的包由被访问的类的 package语句声明,并
且必须建立同名的文件夹
这样,被访问的类的路径包括两部分,Classpath的值和包
两个必须的 Classpath值
,(实心句号 ) 表示当前文件夹
(J2sdk)的安装目录 \lib 表示 JAVA类库所在文件

J2sdk和 Jcreator的安装
? J2sdk和 Jcreator LE都是自由软件,可免费下载
J2sdk的网址, http://java.sun.com/j2se/1.4.2/download.html
还可下载 Documation及其它资料
Jcreator LE的网址,
http://www.jcreator.com/download.html
? 卸载 J2sdk和 Jcreator LE,方法:我的电脑、添加删除程

选中 Jcreator LE并删除,选中 Java2 runtime environment
和 J2sdk删除
? 从 ftp://10.10.2.119下载 Jcreator 和 J2sdk安装软件
? 安装 J2sdk,安装时可以设置安装路径,如设为,C:\j2sdk
? 根据安装路径设置环境变量 path:
右击我的电脑选属性、高级、环境变量,双击系统变量中
的 path,增加 ;( J2sdk安装路径) \bin 例
如 ;C:\j2sdk\bin
path设置后,打开 DOS窗口,键入 java命令并
回车,可检验设置是否正确
? 设置环境变量 classpath:
右击我的电脑选属性、高级、环境变量,
双击系统变量中的 classpath
增加,; ( J2sdk安装路径) \lib 例
如,,; C:\j2sdk\lib
? 安装 Jcreator LE
J2sdk安装时环境变量的设置
? 设置 path
? 设置 classpath
习题
1.填空题
? (1)我们可以通过 ____________,使得处于不同层
次,甚至互不相关的类具有相同的行为,然后由
每个类分别去实现这些行为。
? (2)接口声明的关键字是 ______________。
? (3)在声明类的同时,我们可通过关键字
__________________ 实现接口。
? (4)使用类实现接口时,必须 __________该接口的
所有方法。
? (5)Java中,我们可通过 ________来管理类
名空间。
? (6)创建包的关键字是,____________。
? (7)引入包 grade的 best类,可使用语句:
____________________________。
2,操作题
1,通过设计一接口, 定义有关算术的属性 。
并创建四个应用该接口的类, 分别进行加减
乘除的运算 。
2,设计一个包, 并在其中创建两个类, 一
个类将小写字母变为大写字母, 另一个类将
大写字母变为小写字母 。 然后创建一个类,
实现将, b”变为, B”和将, E”变为, e”。
下课!