JAVA高手进:接口本质上是类吗,接口和类有什么区别和联系,主要是联系,接口是否具备类的特征,接口是否是Object,请给出根据,用测试代码证明自己的观点

解决方案 »

  1.   

    接口本质上是一种类
    不过他与类的区分还是很明显的——不能实例化
    他的精髓在于提供一些类共同的地方,而且能“多继承”
    我们知道所谓对象其实是数据和方法的封装。接口的作用更多的是工程上的,一般上我们用他来封装通用的行为,来达到程序的多态。不必用object的观点来统一接口,在我的感觉中,继承简化对象结构,增加代码重用,接口抽象行为。
      

  2.   

    interface编译后就是一个.class
    接口只是一个协议,如果你实现该接口,那么,你就必须实现该接口下所有的方法。
      

  3.   

    我昨天也问了类似的问题http://community.csdn.net/Expert/topic/4901/4901025.xml?temp=.4183466  可还是不太明白!
    强烈关注中!!!
      

  4.   

    1. 接口本质上是类吗   这个,要看你认为“类的本质是什么”了,过多纠缠于这个说法,很容易陷入文字之争,意义不大。2. 接口和类有什么区别和联系,主要是联系   区别:
            类的定义需要“实现”,接口的定义只需要“声明”;
            类能实例化出一个对象,接口不能;
            类只能单根继承,接口可以多根继承;
            继承一个类,相当于借用了它已实现的功能,实现一个接口,相当于对外做了一个承诺;
            ……   联系:类可以“实现”接口3. 接口是否具备类的特征   这要看你认为哪些是“类的特征”,hehe,比如,“编译后会生成一个 .class 文件”算不算特征……4. 接口是否是Object   不是。但可以用一个接口型的变量来引用一个对象,而且,被引用的对象,说到底,一定是一个 Object。
      

  5.   

    1接口是类吗?
    我觉得既然interface和class根本就不是一个单词。没道理理解为一种东西。
    4接口是否Object?
    既然不是类了,自然不可能跟祖先类有什么关系。
    在引用上,接口很像是数据库中的视图,是一个虚的外表。不过在其他方面就不像了。
    其他的楼上的说的挺多了。
    楼主应该很郁闷接口这种无能的东西有什么用吧,如果稍微看一下设计模式,马上就会明白。实在是太有用了
      

  6.   

    楼上的解释一下
    interface A{}
    public class B implements A{
    public static void main(String [] args){
    A a = new B();
    System.out.println(a.toString());
    }
    }
    为什么a可以调用toString()不会出错?既然它跟祖先类没有关系的话。很困扰啊!
      

  7.   

    使用instanceof()发现是true,说明应该还是继承关系即interface implementser Is a interface.
      

  8.   

    回复(特兰克斯):B是Object的子类,它也就拥有了toString()方法.
    偶同意(地球是圆的)的说法:A a = new B() 也只是一个上溯造型引用的问题.
    a引用了B类的一个实例,所以也就拥有了toString()方法.偶也认为
    接口和Object无血缘关系.
    OU LE.
      

  9.   

    上溯造型引用不是只能调用自己有的方法吗?如果我自己加一个方法是会报错的!
    interface A{}
    public class B implements A{
            public void xxx(){}
             public static void main(String [] args){
                      A a = new B();
                      a.xxx();
    System.out.println(a.toString());
    }
    }
      

  10.   

    我也同意接口和Object无血缘关系,但我无法解释接口可以调用Object的方法!可以看一下我昨天的帖子http://community.csdn.net/Expert/topic/4901/4901025.xml?temp=.4183466
    有人说是Class类的原因,我有点趋向于这种说法。
      

  11.   

    “通过 interface 引用可以调用 Object.toString()”这个现象,从语法上讲,确实有一点点奇怪,毕竟这个 interface 身上并没有 toString() 的影子。我想,只能解释成 Java 语言的特例吧,Java 里的任何一个对象,说到底都是从 Object 派生来的,interface 所引用的,一定是一个“对象”(除非 null),所以,Object 所具有的东西,它一定有。从形式上,我们不妨把这种情况理解为 ((Object)intf).toString(),这就好比你定义一个 class 的时候,并没有把它写成 class MyClass extends Object,是一个道理。Java 语言的特例,我这么理解。
      

  12.   

    'ma:kju 的说法,我同意啊!能交个朋友吗?你的思维很清晰哦,相信可以从你那学到很多东西。我的msn:[email protected]
      

  13.   

    TO dwys0343(特兰克斯):多谢鼓励 !
    工作关系,我对聊天工具的使用很有限。CSDN 里会经常见到的,多多交流吧  :D
      

  14.   

    大家,快下班了,我说两句,对于
    interface A{}
    public class B implements A{
    public static void main(String [] args){
    A a = new B();
    System.out.println(a.toString());
    }
    }
    这个程序,为什么不会出错,并不是调用了接口a的toString()方法,而是调用了类B的toString()方法,所以大家不要误会,如果有怀疑,大家可以测试一下,将上面个程序改为如下:
    interface A{}
    public class B implements A{
    public String toString(){
    return "class B";
    }
    public static void main(String [] args){
    A a = new B();
    System.out.println(a.toString());
    }
    }
    以上是我的一些理解
      

  15.   

    肯定是调用对象B的toString()方法啊!在Thinking in java 的多态性一章中说得很清楚,java方法的绑定是采用后绑定的,也就是运行时绑定,也叫动态绑定,也就是说运行时根据对象的类型来决定绑定哪个方法。除了static和final,java中所有的方法都是采用后绑定的。
      

  16.   

    changsoso: 你可以运行一下下面的小程序,就清楚了
    class A{
    public static void a(){
    System.out.println("a");
    }
    public void b(){
    System.out.println("ab");
    }
    }
    public class Example extends A{
    public static void a(){
    System.out.println("Example");
    }

    public void b(){
    System.out.println("Examplebbbb");
    }

    public static void main(String [] args){
    A b = new Example();
    b.a();
    b.b();

    Example e=new Example();
    e.a();
    e.b();
    }
    }
      

  17.   

    说一下我的理解:接口是对类的抽象,这一点相信大家是深信不疑的。
    接口在抽象级别层次上高于所有类,因此接口在本质上不是类,而是对类的抽象。问题出在“向上转型”这个机制上。以楼主的这个例子来说,A是一个接口,而B是一个实现了接口A的类,B的实例a可以向上转型为Object,亦可以向上转型为A。实际上,一个接口不可能存在直接实例,任何一个接口类型的对象本质上都是Object类的实例。所以:new B()是一个B,也可以是一个Object,但从机制上看,它不可能是一个A(尽管从逻辑上可以这么说)。结论是:不存在一个纯粹的“接口的实例”!那么A a = new B();这种写法意味着什么呢?我觉得,这其实意味着将new B()向上转型为一个类,这个类的定义形于:
    public class Object implements A { }也就是说,A a = new B();这句将new B()转型为一个实现了接口A的Object。把一个实现了某接口的Object直接写为该接口,在Java中并不少见。比如定内部类的实例时,可以这样写:
    void f() {
      Comparable o = new Comparable() {
        public int compareTo(Object o) { }
      };
    }这里的Comparable是一个接口,但是却可以定义接口的实例o,同样是这种制机,o在本质上是一个实现了Comparable的Object的实例。
      

  18.   

    总之:如果A是接口,那么把 A a = new B(); 理解为a是一个“A的实例”是不对的。不存在“A的实例”,只存在“实现了A的Object的实例”。
      

  19.   

    接口本身就是类,但他只能本继承和实现,本能被事例化,有点像虚拟类,但又不完全的是,比如你定义某些功能,但用户要实现这些功能的话,必须继承你的接口,并实现你的借口中定义的方法。
    你说的A a = new B(); 其中A就是一个虚拟类而不是一个接口,
    就像
    List ab=new List();就不可以,因为它是虚拟类被能被事例化
    而List ab= new ArrayList();就可以了
    但List并不是一个接口欢迎java和jsp的爱好者加入! 
    共同探讨,共同进步 
    群号:8137004 有问题也欢迎到这里
      

  20.   

    还有,在java中,每一个object都有toString();的方法
      

  21.   

    啊!这么多人讨论啊?可能大家还没明白我的意思!我说简单一点吧:所有接口里面都有没有toString()的声明呢?如果没有,它的引用可以调用toSring()方法,这有点不符合接口回调的定义!'ma:kju的说法应该可以接受!
      

  22.   

    楼上的:有没有看我的那个回帖?接口中没有定义toString(),没错。但是A a = new B(); 这里的a不是A的实例。不存在A的实例,只有实现了A的Object的实例!也就是说:你将引用转型为接口的类型,也剥夺不了它作为Object的权利。不存在一个“纯粹”的接口的实例。
      

  23.   

    楼主,一个类可以实现多个接口,所有接口A中没有toString()方法,并不代表实现该接口的类不能调用toString()方法.请看看JDK文档,JAVA是单根继承模型,所有类都是从Object派生而来的,toString()是Object中定义的,所以所有类都能调用toString()方法.
      

  24.   

    http://www.boxigroup.com B/S、C/S、数据库开发帮助网站、欢迎光临
      

  25.   

    > 楼主,一个类可以实现多个接口,所有接口A中没有toString()方法,并不代表实现该接口的类不能调用toString()方法.看到这里,我想大家都已经清楚事实是什么样的了,只是说法上还没有统一。其实很多问题都是这样,比如那个经典的“Java 调用参数是值传递还是引用传递”。如果大家都已经清楚是怎么回事,写程序也不会出错了,那么,再争下去,也只是文字游戏了。我替 dwys0343(特兰克斯) 说一句吧,他的意思是,I intf = new C() 的时候,intf 指向的东西是一个 Object 当然没错,但 intf 的定义(I 的定义)并没有 toString() 这一项,为什么 intf.toString() 不会报编译错误。这就好比,List list = new ArrayList(),你不能调用 list.ensureCapacity(),尽管 ArrayList.ensureCapacity() 是有定义的,但 List.ensureCapacity() 并没有定义,你如果调用 list.ensureCapacity() 就会报编译错误。所以 intf.toString() 这种调用方式从语法上将的确是有点奇怪的,我看还是把它当作 Java 语言的特例好了。在 Java 里,Object 这个 class 是比较特殊的,它有着其它任何一个 class 所没有的特殊地位,所以,编译器特殊处理一点也没什么大不了的。
      

  26.   

    呵呵,我不是楼主哦!大家这么晚还在讨论,好辛苦啊!睡觉去咯!'ma:kju,还是你会解释哦,好些人都不懂啥意思就回帖了!不过,楼主,我们讨论得这么辛苦,意思一下,每人给一点分撒~!
      

  27.   

    我比较赞同 "maquan('ma:kju)" 的说法.
    Java 和 C++ 不一样, Java有一个共同的祖先在管理着,这一点比C++强.
    Java接口 是通过 引用对象的祖先 来管理 实现所有对象的,下面有个例子.
    不管结果是什么,编译过了是没错的.楼上的那位大哥:
        从形式上,我们不妨把这种情况理解为 ((Object)intf).toString(),这就好比你定义一个 class 的时候,并没有把它写成 class MyClass extends Object,是一个道理。意思差不多!!!java 隐式地会把一个对象展化为 Object 为什么不能 在定义接口时,隐式地将其转化为Object的引用呢?如果 接口不能操作那些方法, 那会发生什么... ...interface A {
    }public class B implements A {
    public String reStr() {
    return ("hello word.");
    } public String toString() {
    return ("look look...");
    } public static void main(String[] args) throws Exception {
    A a = new B();
    System.out.println(); //能自动调用 Object的 toString()
    //System.out.println(a.reStr()); //不能调用B自定义的方法.
    a.equals(a);
    a.wait();
    a.notify();
    }
    }
      

  28.   

    最最基础的东西:
    接口中的方法 都是默认public性格的,所以实现它的儿子的那个方法也必须是public性格的。
    接口中的属性都是 static final性格的在c++中的类可以多继承~它勤劳且朴素:又干活(方法)又下达指令(抽象)同时还负责财务(属性)~但任务多了~太多东西要管,而且自己家的东西可能别人家的起的名字一样,一不注意就分不清是谁家的 ......容易出乱子(具体出什么乱子-小弟才疏学浅-说不出=_=)java 为了避免类这个家伙惹是生非
    把多继承的任务交给了接口
    从此类专注于代码重用的工作(相对于类,当然不只)
    而接口和抽象类的任务就是规范、约束、定义、模块连接提起继承
    我们的第一反映往往子类重用父类的代码
    但接口确实不具有这个功能,它只会定规则,活都由实现它的孩子们干了,而且很严厉~不干不行~儿子不干只能轮为抽象类、或继承接口~让他们的后代干~活总是要有人干得(否则接口会没有面子~失去意义~但以后很有可能有一个孩子能够实现它的志愿)~实现接口愿望的孩子成为了实实在在的类。
    接口和抽象类的脾气不一样~但配合起来到得心应手~双剑合璧(但有些是面子上的事~骗编译器的~~使用api常套用这样的小把戏)
      

  29.   

    都老掉牙的问题了,楼主还提出来。
    这个都没搞清还自称“EJB冠军”
      

  30.   

    trueblue_lw() 说得挺好,尤其是最后一段。
      

  31.   

    dwys0343(特兰克斯)的问题并不是一个特性,而是在Java中有明确的定义:任何一个实现了接口的类的实例都可以被此接口定义的一个对像的引用所引用(或者说赋值),C#中的接口同样如此。
    接口当然是类,interface关键字就是指定一个类去做什么,而不是怎么做。它是一种抽象类,当然具有类的特征,但接口不能被实例化。类的实例才可以称为Object,接口当然不是。
      

  32.   

    好问题,明天再专门抽时间细看,Mark一下先
      

  33.   

    lollol() "它是一种抽象类,当然具有类的特征"
    但接口不像其他的类,直接或间接的继承了Object的方法啊!接口里面好像没有Object的方法哦!
    这个问题我觉得没有必要再讨论下去了!大家都知道怎么用就行了!希望大家学习和工作顺利!
      

  34.   

    to dwys0343(特兰克斯) :
    法则1,java里所有对象都是Object的子类,能调用Object里定义的方法(相当于java世界的宪法,)
    法则2,接口定义 约束对象不能调用接口里没有定义的方法(相当于java时间的基本法)
     A a = new B();
    //a 是一个对象B,a 接受接口A的约束(a 由B自动向上转型为接口A)
    a.toString();
    //违反法则2,符合法则1,根据宪法优于其他法原则,编译/运行通过
      

  35.   

    论坛发的文字: 
    ---------------------------------------- 
    标题:29号JAVA讲座 还有MP4等你拿 
    ---------------- 
    29号有个全天免费的JAVA/J2EE技术讲座, 
    时间:7月29日(周六)上午10:00 –下午 17:00 
                 9:50签到入场 领抽奖牌 讲座时间       讲座内容 
    10:00 - 11:00  软件行业分析和JAVA软件工程师职业规划 
    11:00 - 12:00  JAVA技术核心概要与学习方法 
    13:00 - 15:00  J2EE企业级案例架构剖析 
    15:00 - 17:00  JAVA/J2EE案例动手实验 现场礼品: 
    一等奖 现场抽取128M MP4 一个     二等奖 光电鼠标一套 地点是 :北京市海淀区长春桥路11号万柳亿城大厦C1座17层 
    有谁去快报名哦 详情访问 
    http://news.csdn.net/n/20060721/92853.html ---- 
    2006-07-24 14:18:32
      

  36.   

    To; szbyk1() :
    法则1,java里所有对象都是Object的子类,能调用Object里定义的方法(相当于java世界的宪法,)
    法则2,接口定义 约束对象不能调用接口里没有定义的方法(相当于java时间的基本法)
     A a = new B();
    //a 是一个对象B,a 接受接口A的约束(a 由B自动向上转型为接口A)
    a.toString();
    //违反法则2,符合法则1,根据宪法优于其他法原则,编译/运行通过有见地!!!
    顶!
      

  37.   

    关于实现接口的类能够使用接口中不存在的toString()问题呵呵,大家可能忘了一点,无论一个类是继承自一个类还是实现一个接口,或者只是单独的一个类,它都隐含的继承了Object这个类的,所以它自然会有Object中的toString()方法了,也就是说,即使一个类不继承其他的类,它也会隐含继承Object这个类的,当然了继承其他的类的时候,由于所有类的父类都是Object,这个类自然也就继承了Object这个类了
      

  38.   

    个人感觉,系统在处理的时候认为只要是一个实例就有所有Object中的方法,因为它一定是继承Object的
      

  39.   

    好吧,我不是说 new B()里面没有Object的方法,有,这是毋庸质疑的!只是说用A的引用调用有点不符合接口回调的定义。呵呵!知道就行了!这个贴现在没有讨论的价值了,再争下去没有任何意义了!知道就行了!大家再别回了啊!
      

  40.   

    感觉interface就是一种特殊的class
      

  41.   

    to dwys0343(特兰克斯):我在你那个贴子里有回复,去看看吧。
      

  42.   

    去看Sun的官方文档TJLS(The Java Language Specification)吧!其中第9章9.2节关于接口有这么一段话:If an interface has no direct superinterfaces, then the interface implicitly
    declares a public abstract member method m with signature s, return type r,
    and throws clause t corresponding to each public instance method m with
    signature s, return type r, and throws clause t declared in Object, unless a
    method with the same signature, same return type, and a compatible throws
    clause is explicitly declared by the interface. It is a compile-time error if the
    interface explicitly declares such a method m in the case where m is declared to
    be final in Object.楼上的老兄,谢了。研究得深入啊,这东西还看!^-^
      

  43.   

    >接口也被编译成.class文件
    ------------------------------
    这并不能证明借口就是类,恰恰相反,如果我们了解一下class file的结构就会发现:
    .class中对interface和class作了非常明确的区分。一个.class文件中有一个access_flags,如果这个标志设置为:ACC_INTERFACE ,则这个文件就是interface,否则就是class。
      

  44.   

    另外,可以简单的测试一下:
    class MyClass extends java.lang.Object {} //编译通过
    interface MyInterface extends java.lang.Object {} //编译出错
    如果interface是一个类,那么也应该继承自java.lang.Object这个类的老祖宗。
      

  45.   

    A a=new B()
    可以这样理解:
    A a代表a可以实现A的所有功能,或者说的正式一点,a实现了接口A
    java是单一继承的,如果没有接口,类之间只有树状结构,例如
    车-四轮车-轿车
      -二轮车-摩托车
    此时,轿车和摩托车的关系只能追溯到"车"了
    如果没有接口,对于"机动车"这个概念,只能定义为类,是"车"的子类,
    轿车和摩托车因为java的单一继承,是无法再继承到"机动车"类下的
    这就是有根树的结构的缺陷
    对于接口,我觉得可以看作是"功能",类看作是"物体"
    A a=new B()
    表示a是B类的"物体",但是又有A的"功能"
      

  46.   

    估计是JAVA的一个BUG!
       因为Interface本质上来说是一个虚指针方法列表的首地址,而一个对象如果实现了一个接口,在内存中就有一段地址存放这些虚函数的首指针的列表,但是通过这个接口实例可以访问的偏移是受限的,受限大小:是接口的定义还有接口所继承的接口方法个数,也就是说他只能访问这一些函数。