Java语言提供了一种接口(interface)机制。这种接口机制使Java的面向对象编程变得更加灵活。我们可以用接口来定义一个类的表现形式,但接口不能包含任何实现。在《Thinking in Java》一书中,作者对接口有这样的描述:“接口(interface)比抽象(abstract)的概念更进了一步。你可以把一个接口看成是一个纯的抽象类。”我认为作者对接口的这一解释再准确不过了。

理解并用好接口机制将帮助我们更好的掌握Java这种面向对象的编程语言。下面我们来讨论一下接口的使用规则以及相关的应用。

一、接口的定义及实现

定义接口和定义类相似,只是要把 class关键字换为 interface。定义方法时只需要方法名,返回类型和参数列表,不能有方法体。接口中可以定义字段,这些字段都被暗指为 static 和 final,因此应该根据需要先定好这些字段的值。例如:

public interface Flyable {

void fly();

}

public interface Talkable {

void talk();

}

public interface Message {

int MAX_SIZE = 4096;

String getMessage();

}

上面定义的几个接口中,Flyable 和 Talkable 只定义了一个方法,而 Message 里除了方法外还有一个字段 MAX_SIZE。可以看出这些接口只定义了类的表现形式,而不包含任何实现,所以不能直接使用。要使用这些接口就需要有相应的类去实现它们。实现接口时应该先在类名后用 implements 关键字申明将要实现的接口,如果要实现多个接口,应该用逗号将它们隔开,然后一一实现这些接口中定义的方法。如下面的例子:

public class Parrot implements Flyable, Talkable {

public void fly() {

System.out.println("Flying like a parrot…");

}

public void talk() {

System.out.println("Hello! I am a parrot!");

}

}

public class TextMessage implements Message {

String message;

public void setMessage(String msg) {

message = msg;

if (message.length() > MAX_SIZE)

message = message.substring(0, MAX_SIZE);

}

public String getMessage() {

return message;

}

}

在 Parrot(鹦鹉)例子中,我们用接口 Flyable 来表示飞行能力,Talkable 表示说话能力,但它们并不包含具体实现。而 Parrot 同时具有这两种能力,所以我们为 Parrot 类同时实现了 Flyable 和 Talkable 这两个接口。同样我们还可以定义一个Swallow(燕子)类,但燕子只有飞行能力,所以我们只需要为 Swallow 实现 Flyable 就行了。因为它们各自的的飞行方法有所不同,所以它们有各自关于飞行的具体实现。

另外,正因为一个类可以同时实现多个接口,使得Java的面向对象特性变得非常灵活。运用这种特性,我们可以实现类似C++语言中多继承那样的特性,甚至更灵活的一些特性。下面我们来讨论一下接口在实际中的应用。

二、用接口来定义一些全局变量

因为接口内的字段都是static和final的,所以我们可以很方便的利用这一点来创建一些常量。例如:

public interface Constants {

String ROOT = "/root";

int MAX_COUNT = 200;

int MIN_COUNT = 100;

}

在使用时可以直接用Constants.ROOT这样的形式来引用其中的常量。我们还可以用下面这种方法来创建初始值不确定的常量。

public interface RandomColor {

int red = Math.random() * 255;

int green = Math.random() * 255;

int blue = Math.random() * 255;

}

其中red、green和blue的值会在第一次被访问时建立,然后保持不变。三、用接口来定义基本数据结构

在设计一套软件系统的初期,我们可以用接口来对一些基本数据元素的特性来进行一些描述,再根据需要进行不同的实现。请大家看看下面这个例子:

public interface User {

int getAge();

String getName();

String getPassword();

}

public class XMLUser implements User {

// 这里用XML技术实现User接口中的方法

public int getAge() { ... }

public String getName() { ... }

public String getPassword() { ... }

}

public abstract class UserFactory {

public static UserFactory getUserFactory() {

return new XMLUserFactory();

}

public User getUser(String name);

public User getAdmin();

public User createUser(String name, String password, int age);

public void addUser(User user);

public void delUser(User user);

}

public class XMLUserFactory extends UserFactory {

// 这里用XML技术实现的UserFactory的抽象方法

}

在这个例子中,我们定义了一个接口User和一个抽象类UserFactory。然后我们用XML技术实现这两个类。可以看出,我们只需要从用 UserFactory的getUserFactory()就可以得到一个UserFactory的实例,而不用去考虑这个实例的具体实现方法。通过 UserFactory的这个实例我们还可以直接得到User的实例,也不用去考具体的实现方法。

如果我们决定用JDBC技术来实现 User和UserFactory,我们只需要按上面的形式实现JDBCUser和JDBCUserFactory就行了。然后把UserFactory 中的getUserFactory方法修改一下就可以改变了它们的实现方法。而我们已经写好的调用UserFactory和User的部分不需要做任何修 改。

这是用接口来定义数据结构的一个简单的例子,在实际应用中还有很多灵活的使用方法,大家需要在学习过程中不断的去体会。

四、理解分布式应用的原理

目前有很多软件项目都使用了分布式的技术。Java 有多种支持分布式应用的技术,早期用的比较多的有 RMI、CORBA 等技术,而现在 EJB 技术更为流行一些。但这些技术不管怎么发展,其实都是以接口为基础的。

以远程方法调用 RMI(Remote Method Invocation)为例。在编写 RMI 应用时,我们需要做两件最基本的事,首先要定义一个接口,这个接口要继承 java.rmi.Remote 接口,这个接口中应该包含你要从远端调用的方法名。接下来就是写一个类来实现这个接口中的方法。例如:

public interface Product extends java.rmi.Remote {

String getName() throws java.rmi.RemoteException;

}

public class ProductImpl implements Product {

String name;

public ProductImpl(String n) {

name = n;

}

public String getName() throws java.rmi.RemoteException {

return name;

}

}

在这个例子中,接口 Product 是放在客户端的,而 ProductImpl 是放在服务器端的,客户在使用时只需要用指定的规则得到Product 的实例就行了,不用去考虑 Product 接口里的方法是如何实现的。在定义好这两个类后,用Java开发包命令“rmic ProductImpl”就可以帮助我们自动生成两个类 ProductImpl_Skel 和 ProductImpl_Stub。这两个类就包含了RMI调用的运作机制。有兴趣的朋友可以把这两个类反编译后研究一下。你会发现其中 ProductImpl_Stub 实际上是接口 Product 的一个实现类。RMI 机制就是用这个类来生成 Product 的实例供客户端使用。另一个类 ProductImpl_Skel 则是在服务端响应 ProductImpl_Stub 的调用请求的类。而 RMI 最底层的通讯原理则是利用 ObjectInputStream 和 ObjetOutputStream 通过 Socket 将要调用的方法名及参数列表传到服务器端,服务器端再通过特定的方法调用实现类(在本例中是 ProductImpl)的对应方法,然后将结果通过 Socket 传回客户端就行了。由于 Skel 和 Stub 类是用工具生成的,所以就大大节省了开发的时间。另外,如果我们需要修改一些实现方法或错误,只需要对服务器端的实现类进行修改就可以了,也就是说这种分布式应用的大部分维护工作在服务器端就可以完成。

现在越来越多的应用使用了 EJB 这种技术。EJB 是从 RMI 发展而来的一项技术,它比RMI定义得更加完善,可以获得更好的面向对象的特性。但它的规则要比RMI复杂一些。但是不管它多复杂,它同样是使用了接口来 定义各种不同的 Bean,也同样需要编写相应的实现类来完成具体的功能,最后还要通过 Socket 来进行通讯。EJB的运作机制本身有一定的复杂性,所以其应用的效率理所当然就会受到一定的影响。因此在选择开发技术时应该根据应用的规模和特点仔细考 虑,不一定流行的技术就一定能适应你的应用。如果你很好的掌握了面向对象的设计原则,你就可以自行设计。也许你可以根据自己应用的特点设计出更合适的分布 式应用结构。

五、结论

除了上述的一些应用外,还有很多地方可以使用接口,比如在Java的事件机制中就常用到接口。另外,对于一些已经开发好的系统,在结构上进行较大的调整已经不太现实,这时可以通过定义一些接口并追加相应的实现来完成功能结构的扩展。

总之,学好接口可以帮助我们更好的理解和运用面向对象的设计原则。使我们能设计出更好的软件系统。由于本人水平的限制,如有错误之处还请多多指正

JAVA设计一个电视机类_漫谈Java程序设计中的接口应用相关推荐

  1. java设计一个user类_关于JAVA设计一个用户类

    关于JAVA设计一个用户类 关注:152  答案:2  mip版 解决时间 2021-02-02 05:51 提问者安分守己的小青春 2021-02-02 02:23 设计一个用户类,该类有用户编号. ...

  2. JAVA设计一个fan类_北京信息科技大学java语言程序设计-类和对象

    北京信息科技大学java语言程序设计-类和对象 [实验名称]实验2 类和对象 [实验目的] 1.学习和掌握Java创建对象的方法. 2.学习和掌握通过创建对象.使用类的方法. 3.学习和掌握Java类 ...

  3. java设计一个查询模块_采用Java实现的汉语拼音查询模块

    0引言现有管理信息系统的数据库中存储了大量的中文信息,中文信息的检索是MIS的重要功能,对于中文字段的常见查询方法是输入汉字字符串,但是此方法需要过多的击键次数,例如,查询人名为"王晓明&q ...

  4. java 员工类算工资_用java设计一个员工类,可以计算工资个人所得税

    用java设计一个员工类,可以计算工资个人所得税 1. 背景 老师在课上布置了几道java编程题,此为其中之一 2. 题目内容 设计一个员工类.该员工具有下列私有属性:编号,姓名,基本工资,奖金  提 ...

  5. java设计一个立方体类box_实例1: 设计一个立方体类Box,定义三个属性,分别是长,宽,高。定义二个方法,分别计算并输出立方体的体积和表面积。_学小易找答案...

    [填空题]表达式 list(filter(lambda x:x>2, [0,1,2,3,0,0])) 的值为 _________ . [填空题]表达式 len(' 中国 '.encode('ut ...

  6. java形状类_[转载]JAVA 设计一个形状类Shape 求周长和面积

    设计一个形状类Shape,方法:求周长和求面积 形状类的子类:Rect(矩形),Circle(圆形) Rect类的子类:Square(正方形) 不同的子类会有不同的计算周长和面积的方法 创建三个不同的 ...

  7. 【Java入门学习】JAVA设计一个雇员类,创建雇员类对象

    题目:设计一个雇员类,创建雇员类对象,统计雇员的出勤人数 1.属性包括:编号.姓名.年龄.职务.部门.出勤人数 2.方法包括:构造方法.输出信息的方法.签到方法 要求: 1.考虑属性和方法的访问权限 ...

  8. JAVA设计一个汽车类Vehicle,包含的属性有车轮个数wheels和车重weight

    编写一个Java应用程序,设计一个汽车类Vehicle,包含的属性有车轮个数wheels和车重weight.小车类Car是Vehicle的子类,其中包含的属性有载人数loader.卡车类Truck是C ...

  9. 1-6 JAVA [设计一个BankAccount类]

    设计一个BankAccount类,这个类包括: (1)一个int型的balance表时账户余额. (2)一个无参构造方法,将账户余额初始化为0. (3)一个带一个参数的构造方法,将账户余额初始化为该输 ...

最新文章

  1. wxPython 笔记(3)基本结构
  2. Linux学习笔记04
  3. 315. Count of Smaller Numbers After Self 计算右侧小于当前元素的个数
  4. java看图_看图吧,Java
  5. Quote Form OnLoad Implement Add Leftnav, count Activities
  6. linux内核奇遇记之md源代码解读之三
  7. cad电气工程量计算机,CAD电气管线快速算量方法
  8. 关于 HSF框架 (一)简单介绍
  9. 音频ncm格式文件转mp3,ncm转mp3
  10. unknownhostexception错误解决方案
  11. python背单词代码实现
  12. 【LOJ#6198】—谢特(后缀数组+01Trie)
  13. Mybatis的一个连接mysql的坑
  14. 计算机相关专业提升学历的解决方案(博士研究生)
  15. Python爬虫|豆瓣图书Top250
  16. ps4手柄驱动linux,Arduino和单片机区别,及Arduino入门教程
  17. 猿辅导python编程老师面试_猿辅导辅导老师面试一系列的感受
  18. 许久没有写过原创文章了
  19. 教你如何一键重装Windows7系统
  20. 14个资源超级丰富的网站,个个精彩,绝对有你需要的!

热门文章

  1. sql 如何查询上次的记录_学会SQL并不难,小白学习记录之五(多表查询)
  2. 行为像指针的类的对象每次作为参数传入函数或者传出函数时都要小心
  3. docker学习1--dockerfile
  4. HDOJ2013_蟠桃记
  5. OSPF 提升四 Network Types FRAM-RELAY
  6. JavaScript的类型自动转换高级玩法JSFuck
  7. 最简单的CSocket通信流程
  8. C语言课后习题(29)
  9. int *p=new int; int *p=new int[10]; int *p=new int(10);这三个有什么区别
  10. mysql between 等于_MySQL中BETWEEN子句的用法详解