关于java中接口的认识(不知理解的是否正确)
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()时的内存空间。(不知道我理解的对不对,斑竹)