<%@ page contentType="text/html; charset=gb2312"%> 关于java中接口的认识
网站公告:   ◆北天JAVA技术网热情为java爱好者服务,本网内容包括JAVA(JSP、servlet、EJB、webservice、j2ee、javabean、应用服务器、JavaScript),数据库(MYSQL、SQL Server、Sybase、Oracle、DB2、数据库综合知识),设计研究(设计模式、Struts、Spring、Hibernate、设计框架、设计综合知识),WEB2.0新技术(主要介绍AJAX),以及各种技术的入门、实例、例子等等,欢迎各位多来坐坐!◆  诚邀各位JAVA爱好者加盟!◆  本网站内容丰富,更新快,保证每周20篇以上!  
加入收藏
设为首页
联系站长
承接项目
  相关资源:网站首页 | 免费培训学院 | 技术论坛 | JAVA聊天室 | 作家专栏 | 开发工具 | 认证考试 | 会员俱乐部
  JAVA技术初学者园地 | jsp与servlet | javascript | Java源代码 | EJB | web service | 应用服务器 | JAVA综合知识
  设计研究设计模式 | 设计框架 | Struts | Spring | Hibernate | 开源项目 | 面向对象设计 | 设计综合知识
  数 据 库MYSQL | SQL Server | Sybase | Oracle | DB2 | Informix | Access | 数据库综合知识
  其他资源:AJAX新技术 | 网站开发 | ERP软件 | OA办公软件 | 商业智能BI | 开发综合知识 | 承接项目 | 项目试用

 
 
关于java中接口的认识
     发布者: 发布时间:2007-01-21
java中的类类似于c中的指针唯一的区别是你不能像c中那样去操作它,new运算符在运行期间为对象分配内存,因此运行一次new,就分配一块内存区域。假如有两个类A和B,
public class A {

method1();{}
method2();{}
method3();{}
method4();{}
}
类B只使用method1()则

public class B {

A a=new A();
a.method1();
}
因此运行一次new,就开辟了一块内存区域(即使不使用method2() method3() method4()也开辟与之对应的内存区域),所以存在耦合

如果有了接口就不这样了,可以根据接口灵活调用类中的方法,降低了耦合。
我觉得这才是java中的接口产生的最根本的原因和最根本的作用

 sakulagi 回复于:2005-09-06 07:34:41
即使有了interface,也还是实例化同样的对象,并没有减少内存的使用

另外method()占用的内存和new没有关系,无论是c还是java都不会在每次new的时候都给某个方法或是函数分配空间的,那不是太浪费了么?

 TAxxjszxlkjf 回复于:2005-09-06 17:13:54
public interface callback {
       public void method1();
}
public class A { 

method1();{} 
method2();{} 
method3();{} 
method4();{} 

public class B { 

callback a=new A(); 
a.method1(); 

如果不使用接口B要调用A的方法, 会将A当作参数传给B,然后B再调用A的方法method1(),如果使用接口,则B在调用A的方法时候直接调用method1()方法即可。
(如果我的理解不正确,求求大哥版主了,给我一个接口可以降低耦合的实例好吗)

 dennis2 回复于:2005-09-06 23:44:23
public class A {

应该是

public class A implements callback {

才对。这样你才能做 callback a = new A();

接口是面向对象编程的很重要的概念之一,它定义了调用与被调用方的 Contract。你可以完全替换掉一个接口的实现,而你只需在调用方改动一个语句。比如,你现在又有一个类实现 callback 这个接口:

class C implements callback {
method1() {
// an entirely different implementation
}
}

在 class B 里面,你只需把 

callback a=new A();

替换成

callback a = new C();

后面的语句不用改,那么整个 callback 的实现就变成 class C 的实现了。

 TAxxjszxlkjf 回复于:2005-09-07 00:36:26
不好意思粘贴错了应该是
public interface callback { 
      public void method1(); 

public class A implements callback   { 

method1();{} 
method2();{} 
method3();{} 
method4();{} 

public class B { 

callback a=new A(); 
a.method1(); 
}

 sakulagi 回复于:2005-09-07 07:34:05
dennis2讲的是对的,这样其实就是在降低耦合度

 TAxxjszxlkjf 回复于:2005-09-07 11:22:29
public class A { 

method1();{} 
method2();{} 
method3();{} 
method4();{} 


class C  { 
method1() { 
// an entirely different implementation 




public class B  { 

A a=new A(); 
a.method1(); 



把A a=new A() 改为C a=new C()不就行了吗
怎么体现降低耦合度呢
callback a=new A() 和 A a=new A()
是不是后者直接把类当参数传递前者可以直接调用方法

 tinywind 回复于:2005-09-07 11:31:43
因为你用A a=new A()的时候,还是知道A是一个具体的实现,所以你没法解耦,解决方法有很多。作为参数传入是一种,利用factory模式创建也可以,现在时髦的IOC也是一种方式。

 TAxxjszxlkjf 回复于:2005-09-07 13:44:42
楼上朋友 我的意思是说A a=new A() 改为C a=new C()是不是降低了耦合?

 tinywind 回复于:2005-09-07 14:13:24
当然不是,你这种情况就是强耦合,也就是我们要避免地情况

 TAxxjszxlkjf 回复于:2005-09-07 15:43:37
楼上的朋友
callback a=new A() 和 A a=new A() 
那么这样的方式(使用接口)是不是就降低了耦合呢

 tinywind 回复于:2005-09-07 16:22:04
如果class A是interface callback的一个实现的话,对于调用者来说A就是透明的,所以不应该有new A()这种操作存在
至于调用者怎么获得interface的实现,可以参考我前面回帖中说的方法

 sakulagi 回复于:2005-09-07 16:35:24
楼主的代码上还是没有降低耦合度。
我举个别的例子吧:
[code:1:3652374f12]
import java.util.Iterator;
import java.util.Vector;

//Interface Decouble Example

public class  ChinaUnixJavaCircusShow{

public static void main(String[] args) {
Circus c = new Circus();
c.addAnimalActors(new Bear());
c.addAnimalActors(new Horse());
c.addAnimalActors(new Dog());
c.bigShow();
}
}

interface AnimalActor {
public void showBestPose();
}

class Bear implements AnimalActor {

public void showBestPose() {
System.out.println("This bear show!!");
}
}

class Horse implements AnimalActor {

public void showBestPose() {
System.out.println("This horse show!!");
}
}

class Dog implements AnimalActor {

public void showBestPose() {
System.out.println("This dog show!!");
}
}

class Circus {
private Vector actors = new Vector();

public void addAnimalActors(AnimalActor a) {
actors.add(a);
}

public void bigShow() {
Iterator i = actors.iterator();
while (i.hasNext()) {
((AnimalActor) i.next()).showBestPose();
}
}
}
[/code:1:3652374f12]
由于使用了接口,Circus不再理会参加演出的具体的动物演员的类,只要是实现了AnimalActor接口的类都可以参加Big Show。
如果没有使用接口,那么Circus的代码中就要包含Horse,bear, dog类的引用。现在Circus的代码和具体可能有多少种动物无关,这就是解藕

 dennis2 回复于:2005-09-07 21:45:03
版主说得没错,例子很形象 :)

我原本也想回这个贴,但一时没有找到好的例子。

 TAxxjszxlkjf 回复于:2005-09-08 08:30:30
这种例子我也是知道的
类F
package com.examples.basics;
interface wuqi{
    public void gongji();
}
 class A implements wuqi {
public void gongji() {
System.out.println("Inside A's constructor.");
}
}
 class B implements wuqi {
public void gongji() {
System.out.println("Inside B's constructor.");
}
}

 
class C implements wuqi {

public void gongji() {
System.out.println("Inside C's constructor.");
}
}

 class F  {
public static void main(String args[]){
wuqi a = new A();
a.gongji();
wuqi b = new B();
b.gongji();
wuqi c = new C();
c.gongji();
}
}


类Epackage com.examples.basics;
class A  {
public void gongji() {
System.out.println("Inside A's constructor.");
}
}
 class B  {
public void gongji() {
System.out.println("Inside B's constructor.");
}
}

class C {
public void gongji() {
System.out.println("Inside C's constructor.");
}
}
class E  {
public static void main(String args[]){
A a = new A();
a.gongji();
B b = new B();
b.gongji();
C c = new C();
c.gongji();
}
}


类D
package com.examples.basics;
interface wuqi{
    public void gongji();
}
 class A implements wuqi {
public void gongji() {
System.out.println("Inside A's constructor.");
}
}
 class B implements wuqi {
public void gongji() {
System.out.println("Inside B's constructor.");
}
}

 
class C implements wuqi {

public void gongji() {
System.out.println("Inside C's constructor.");
}
}
class wqkzt {
 
public void kaihuo(wuqi w) {
   w.gongji();
}
}
 class D  {
public static void main(String args[]){
wqkzt e=new wqkzt();
e.kaihuo(new A());
e.kaihuo(new B());
e.kaihuo(new C());
}
}


其中类D的实现应该和版主的例子是一样的,我只是想知道类D中e.kaihuo(new C())传递参数传递的是对象还是方法。如果是对象的话,那么不就和类E F不就一样了吗。即类D中若多一项e.kaihuo(new D());
那类E 
D d = new D();
d.gongji();
类 F
wuqi d = new C();
d.gongji();
(其中类D也实现gongji();)
3个类比起来从哪里可以看出解耦呢

 sakulagi 回复于:2005-09-08 08:49:43
传递的当然是对象。

wqkzt类不再关心具体武器的类型。只是对wuqi这个接口进行操作,这就是解耦

 sakulagi 回复于:2005-09-08 09:10:18
不过楼主的例子还真是弓虽
用拼音做类名……-_-||

 TAxxjszxlkjf 回复于:2005-09-08 19:02:29
e.kaihuo(new A()); 
e.kaihuo(new B()); 
e.kaihuo(new C());
 wqkzt类这样不也得关心武器的类型吗
(真郁闷就是不明白。)

 dennis2 回复于:2005-09-09 00:28:49
>  wqkzt类这样不也得关心武器的类型吗

在 wqkzt 这个类的定义中不用(也不可能)关心武器的类型。

 sakulagi 回复于:2005-09-09 08:40:05
[quote:06f9522c31="TAxxjszxlkjf"]e.kaihuo(new A()); 
e.kaihuo(new B()); 
e.kaihuo(new C());
 wqkzt类这样不也得关心武器的类型吗
(真郁闷就是不明白。)[/quote:06f9522c31]你是所有类的程序员,所以你看到了所有的细节。假设你只开发了wqkzt类,其他类你没有source code,你看到了什么?能看到具体的武器类型么?

 白色乌鸦 回复于:2005-09-09 11:25:04
@_@! kaihuo??

so cool!!!

 TAxxjszxlkjf 回复于:2005-09-09 11:51:47
类D中
wqkzt e=new wqkzt();
e.kaihuo(new A());
类F中
wuqi a = new A(); 
a.gongji(); 
二者的实现没什么区别了
版主
在 wqkzt 这个类的定义中不用(也不可能)关心武器的类型只是使用接口的一个优点好处我觉得并不是
接口存在和产生的本质原因

 sakulagi 回复于:2005-09-09 13:46:54
解耦就是接口存在的本质原因了。楼主觉得还有什么其他的好处呢?

 TAxxjszxlkjf 回复于:2005-09-09 16:57:09
类D中 
wqkzt e=new wqkzt(); 
e.kaihuo(new A()); 
类F中 
wuqi a = new A(); 
a.gongji(); 
二者实质上不就一样了吗没什么区别了

 sakulagi 回复于:2005-09-09 18:57:54
楼主说的“实质上一样”的意思是什么?
[quote:4b409ea867="TAxxjszxlkjf"]类D中 
wqkzt e=new wqkzt(); 
e.kaihuo(new A()); 
[/quote:4b409ea867]
D这段代码里有两个对象
[quote:4b409ea867]
类F中 
wuqi a = new A(); 
a.gongji(); 
二者实质上不就一样了吗没什么区别了[/quote:4b409ea867]F这段代码里只有一个对象。

怎么会实质上一样呢?

 TAxxjszxlkjf 回复于:2005-09-10 00:21:17
我的意思 类E F D最终实现的结果是一样的,类E F中是不是就存在着耦合,如果存在,在什么地方,怎么耦合的。类D和类E F比起来是怎么去解耦的。
(我觉着类D中 
wqkzt e=new wqkzt(); 
e.kaihuo(new A()); 
类F中 
wuqi a = new A(); 
a.gongji(); 
二者实质上不就一样了吗没什么区别了(从耦合的角度讲))

 sakulagi 回复于:2005-09-10 16:15:24
倒,原来你还在看这3个类。D,E,F都不能说明接口的作用,虽然看上去好像是使用了接口。真正体现接口好处的是wqkzt类

我再强调一下:
[quote:e669f41c2f]你是所有类的程序员,所以你看到了所有的细节。假设你只开发了wqkzt类,其他类你没有source code,你看到了什么?能看到具体的武器类型么?
[/quote:e669f41c2f]

 TAxxjszxlkjf 回复于:2005-09-11 00:14:23
我问的就是这个意思3个程序最终实现的结果是一样的D.java中使用了wqkzt类,与E F比起来优越在什么地方(程序E F中是不是就存在着耦合,如果存在,在什么地方,怎么耦合的。程序D和程序E F比起来是怎么去解耦的)

 sakulagi 回复于:2005-09-11 06:51:57
【1】 只有D使用了wqkzt;E,F没有。
【2】D和E, F相比没有解耦,因为E, F的问题在于E, F这两个类和其他类有强耦合,但是D同样和其他类有耦合。

我说的是如果wqzkt在E, F里有不同的实现:比如下边的实现:
F
[code:1:99afb29279]
class wqzkt {
    public void kaihuo(A a) { 
      a.gongji(); 
    }

    public void kaihuo(B b) { 
      b.gongji(); 
    }

    public void kaihuo(C c) { 
      c.gongji(); 
    }

}
[/code:1:99afb29279]

 sakulagi 回复于:2005-09-11 06:57:55
这就是没有使用接口的时候wqzkt的实现。如果使用了接口,就好多了。而且可以支持包括A, B, C在内的所有实现了wuqi接口的类,而不限于这三个类。

所以我说你的那个例子不好。我的例子没有写出没有不用接口的Circus,缺少了对比的效果;你看的那个例子却基本上是误导你用一些错误的类(E, F, D)在对比……

 TAxxjszxlkjf 回复于:2005-09-11 13:23:16
既然D和E, F相比没有解耦,也就是说只有在都使用wqzkt类这个前提下才能体现接口的本质,那接口存在还有什么意义。(我觉得只有一个使用接口如程序D,和一个不使用接口如程序E相比较才能反映出接口的本质。)因为E F里没必要实现
class wqzkt { 
   public void kaihuo(A a) { 
     a.gongji(); 
   } 

   public void kaihuo(B b) { 
     b.gongji(); 
   } 

   public void kaihuo(C c) { 
     c.gongji(); 
   } 

}

 sakulagi 回复于:2005-09-11 20:17:26
[quote:30871f136d="TAxxjszxlkjf"]既然D和E, F相比没有解耦,也就是说只有在都使用wqzkt类这个前提下才能体现接口的本质,那接口存在还有什么意义。(我觉得只有一个使用接口如程序D,和一个不使用接口如程序E相比较才能反映出接口的本质。)因为E F里没必要实现 
[/quote:30871f136d]
你说对了,只有使用了接口的程序才能看出接口的好处。但是,不是使用了接口,就一定能享受到接口的好处。比如F,就没有什么好处,因为不是最佳的使用接口的方式。“解耦”意味着“用接口代替类”,而不是接口和类并存,F那个程序充其量只是演示了一下类到接口的类型转换的语法而已,没有任何意义。接口在定义了之后,一定要有一个很好的使用者,比如wqzkt这样的类,才能看出它的用处;对D和F这两个类来说(我不是指D程序和F程序),不是发挥接口优势的类,所以比较D, E, F类是没有意义的。

---------------------------------

至于说E, F里没有必要实现wqzkt类,我只能说这个例子里没有体现wqzkt类存在的必要性。因为这个程序没有需求。只有在复杂的程序里,多人开发的环境中,才能体会到接口的好处。所以在没有需求的情况下,只是单纯的对比D和E是不能看出接口存在的意义的。我是假设wqzkt有存在的意义(抱歉,我无法从这个类的名字看出它的含义),那么最佳的wqzkt类的设计方式是在wqakt类中使用wuqi接口,而不是A, B,C。而你的前提是wqzkt类没有存在的必要,所以只有在有需求的情况下才能看出wuqi接口的作用。

---------------

其实很多软件工程的基本概念开始都不是太容易理解。多写写程序,参与一些实际的项目,然后就会有更清晰的认识。

 TAxxjszxlkjf 回复于:2005-09-12 09:38:35
我使用类文件F那种例子就是为了和文件D进行单纯的比较,去比较接口产生的本质。因为我觉得使用接口是java编程的一种方式,讨论它产生的本质不应该局限在都使用类似于wqkzt(武器控制台)类的前提下去讨论(使用接口的好处我也知道,特别是面向不同客户的大型程序中,但那只是它产生后人们发现的好处,和他产生的本质没关系,“多写写程序,参与一些实际的项目,然后就会有更清晰的认识”这样只能更好的理解使用接口的好处,更好的去使用它。我现在只想知道接口为什么产生,是为什么产生的,人们为什么要设计接口。(接口产生的本质)如我举的例子,要实现同一个结果,程序D,程序F两种方式,如果二者在编程的本质上没什么区别(如耦合),虽然外形不一样,那用程序F不就可以了吗,还设计接口干什么。

 sakulagi 回复于:2005-09-12 11:00:42
接口设计的目的就是因为有复杂的大型程序,如果是简单的程序,那么面向对象都没有必要,用汇编就够了,何况“接口”。这就是接口产生的目的。

所有的语法现象,包括接口,包括面向对象,都是因为有需求,所以才出现的。所以如果你明白了接口的好处,自然就知道了接口出现的目的。

你举的例子没有需求分析,同时也比较简单,所以看不出接口的作用。也就是说,从你的例子看来,接口这个东西是没有任何用处的。甚至看不出解耦有什么用,因为程序里没有什么太大的耦合度。

Java没有什么特殊的,接口也不是什么神秘的东西,设计java和接口的人就是为了在设计和开发大型程序的时候,有接口这么个东西比没有要方便,而不是为了某个神秘的“本质”设计接口的。我觉得你把接口产生的原因和结果混淆了。不是接口产生了,人们才发现用来设计大型应用程序用接口好;而是因为大型软件的开发要求了“接口”的出现。其实整个软件工程这门科学都是这样。总不能说是“先有了软件工程,大家才发现软件工程可以用来设计和开发软件”吧、

 白色乌鸦 回复于:2005-09-12 11:06:02
劳模,当之无愧

 sakulagi 回复于:2005-09-12 11:09:56
劳模?俺?

 白色乌鸦 回复于:2005-09-12 11:26:28
[quote:0bac37d82b="sakulagi"]劳模?俺?[/quote:0bac37d82b]

恩,pf死你了,呵呵,超有耐心~~~~,很称职的说~~~~~~~~~~~ :)

 sakulagi 回复于:2005-09-12 13:45:14
:)
讨论基本的问题是理清思路,学习概念的最好方法

 TAxxjszxlkjf 回复于:2005-09-12 23:08:37
程序F E中
..............
class C implements wuqi { 

public void gongji() { 
System.out.println("Inside C's constructor."); 



class F  { 
public static void main(String args[]){ 
wuqi a = new A(); 
a.gongji(); 
wuqi b = new B(); //若改为wuqi a = new B();
b.gongji();        //a.gongji();
wuqi c = new C(); //wuqi a = new C();
c.gongji();       //a.gongji();




............
class E  { 
public static void main(String args[]){ 
A a = new A(); 
a.gongji(); 
B b = new B(); //若改为B a = new B();
b.gongji();    //a.gongji();
C c = new C(); //C a = new C();
c.gongji();    //a.gongji();



作以上更改程序在编译时都会报错是行不通的,所以a b c在被赋值后都会同时占用一定的内存空间,而不会立即释放的。

程序D中
...............
class wqkzt { 

public void kaihuo(wuqi w) { 
  w.gongji(); 


class D  { 
public static void main(String args[]){ 
wqkzt e=new wqkzt(); 
e.kaihuo(new A()); 
e.kaihuo(new B()); 
e.kaihuo(new C()); 


其通过接口就可以避免了以上的情况,谁的方法被调用,内存空间就分给谁,如D,当传递的参数是new B()的时候,便使用了开始当传递的参数是new A()时的内存空间。(不知道我理解的对不对,斑竹)
(转载文章请保留出处:北天JAVA技术网(www.java114.com))
 
更多精彩文章:
业务流程不是需求
学习Spring的小小心得
Java EE 5.0能取代Struts,Spring和Hibernate吗?
敏捷开发的必要技巧:处理不合适的依赖
Hibernate get()和load() 的区别?
Eclipse下实现软件项目的源码管理
 
最近评论:
        
你曾悄悄的来过!
wow gold,wow gold,wow gold,ffxi gil max(8828)
        
冰封的往事!
wow power leveling,wow gold,wow power leveling,wow gold max(5290)
        
冰封的往事!
wow power leveling,wow gold,WoW Gold,wow gold max(4161)
        
回复:关于java中接口的认识
我认为接口 其实就是一个指针,由于一个类可能实现多个接口,就拿List接口来说,我门可以List l=new ArrayList();来使用因为ArrayList类实现几个接口,为了屏蔽掉其他实现接口的方法以及当我门点“。”时方便,并且节省内存空间
        
回复:关于java中接口的认识
a
        
标 题:   
内 容:   
 
                                  
 
免责声明:该文章由网友发表,如果对您造成侵权,请联系站长

首页 - 承接项目 - 网站地图 - 联系我们 -
版权所有北天JAVA技术工作室 ICP证号:粤ICP备06079815号