LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2321|回复: 5

谁能告诉我java的interface有什么用?谢谢

[复制链接]
发表于 2007-2-1 08:20:25 | 显示全部楼层 |阅读模式
参照网上教程interface的例子,我把它简化如下:
--------------------------------------------------------
interface Instrument {
  void play();
  String what();
  void adjust();
}

class Wind implements Instrument {
  public void play() {
    System.out.println("Wind5.play()");
  }
  public String what() { return "Wind"; }
  public void adjust() {}
}

public class Music {
  public static void main(String[] args) {
    Instrument orchestra = new Instrument;
    orchestra = new Wind();
    orchestra.play();
  }
}

-----------------------------------------------------------
这太stupid了,完全可以不用interface,用如下代码替换
-----------------------------------------------------------
class Wind {
  public void play() {
    System.out.println("Wind5.play()");
  }
  public String what() { return "Wind"; }
  public void adjust() {}
}

public class Music {
  public static void main(String[] args) {
    Wind orchestra = new Wind();
    orchestra.play();
  }
}
-------------------------------------------------------------

我不明白用interface倒抵有什么用,除了可以多重继承, 望高手指教~~~~~~~
发表于 2007-2-9 12:48:32 | 显示全部楼层
首先你得好好学习 OOP,深刻理解接口的作用。这是前提。以下我解释一下接口有什么用:

接口声明了一种“作用的集合”。实现这个接口的类必具有这些作用。

举一个简单的数据访问类的例子:

1. 声明一个 IDao 接口,使之具有以下作用:

void create(Object obj);
void update(Object obj);
void delete(Object obj);
Object fetch(int id);

2. 创建一个基于 JDBC 的类 JdbcDao implements IDao

3. 创建一个基于 Hibernate 的类 HibernateDao implements IDao

4. 实现一个类似这样的工厂方法:

IDao getInstance(String implementType) {....}

参数 implementType 用于指定使用 JDBC 的类还是使用 Hibernate 的类。

注意这个函数的返回类型是 IDao ,而不是具体的 JdbcDao 或者 HibernateDao 。从而使得可以在运行时决定这个应用的某个模块使用哪一种数据访问方式。

现在假设某一系列的类不仅具有数据访问作用,还具有通知作用。这种作用使得这些类在每次执行完某些函数之后会发起一个通知其他类的消息。

这时候涉及一个“职责分明”的问题。我需要所有具有数据访问能力的类(可能有很多,视应用规模而言)都具有这个通知的作用。这时候我们可以怎样做?

1)在 IDao 接口里添加声明一个 notify() 方法,然后在所有 DAO 实现类中实现这个方法的细节
2)添加一个接口 INotify ,让所有具有数据访问能力的 DAO 实现类再实现这个接口,如:

public class JdbcDAO implements IDao, INotify
{...}

现在问题来了,如果我们只不过是实现“继承”,那么 JdbcDao 和 HibernateDao 的实现细节很可能完全不同,那么就要重写(override)父类的方法了,这是LZ原贴的疑问。

第二个问题是,接受消息通知的那个通知处理类,可以接受哪些类传递过来的消息呢?是 IDao 系列,还是 INotify 系列?

如果是前者,那么这个消息处理类就只能处理数据访问类传递过来的通知消息,不能处理别的类(没有 implements IDao 的类)。

显然,最好的办法是把函数写成这样:
public void processNotify(INotify obj) {...}

而不是
public void processNotify(IDao obj) {...}

这样一来,这个通知处理类就可以通用了。当你有别的模块需要使用这个通知处理类时,想想你会怎么办?

假设别的模块是邮件发送类 MailSender ,那么最佳做法就是 MailSender implements INotify 而不是 implements IDao ,因为 MailSender 不需要 IDao 的那四个方法(见前面的接口声明)

现在可以理解接口的用处了吗?

附注:
在第一个例子中,的确可以用抽象工厂代替这种写法,如果你的应用不需要继承别的什么东西的话,毕竟只有一次继承,要好好珍惜呢~~呵呵~~
回复 支持 反对

使用道具 举报

发表于 2007-2-20 14:10:28 | 显示全部楼层
u google u get it
回复 支持 反对

使用道具 举报

发表于 2007-3-3 01:17:10 | 显示全部楼层
Head First Java
回复 支持 反对

使用道具 举报

发表于 2007-3-3 17:33:56 | 显示全部楼层
实现多重继承~~!!~~
回复 支持 反对

使用道具 举报

发表于 2007-4-6 08:55:33 | 显示全部楼层
就是加上某个interface之后就必须实现interface里指定的函数,工程管理上有用。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表