为什么接口定义的引用可调用Object中的方法?
看以下例子:
//file InFace.java
public interface InFace
{
public void inFaceA();
}//file Imple.java
public class Imple implements InFace
{
public void inFaceA()
{
System.out.println("InterFace method!");
}
public void impleB()
{
System.out.println("Implement method!");
}
}//file TestIn.java
public class TestIn
{
public static void main(String[] args)
{
InFace i = new Imple();
i.inFaceA() ;
System.out.println( i.toString() );
//此处i只能显示调用inFaceA,不能调用impleB,这是正常的,但是我
//不明白的是i也能调用toString(),这应该是Object中的方法,但是
//接口是不能继承类的,
//我想问接口是不是也有一个类似Object这样的
//顶级接口,若不是,为什么i可以调用Object中的方法??
}
}
看以下例子:
//file InFace.java
public interface InFace
{
public void inFaceA();
}//file Imple.java
public class Imple implements InFace
{
public void inFaceA()
{
System.out.println("InterFace method!");
}
public void impleB()
{
System.out.println("Implement method!");
}
}//file TestIn.java
public class TestIn
{
public static void main(String[] args)
{
InFace i = new Imple();
i.inFaceA() ;
System.out.println( i.toString() );
//此处i只能显示调用inFaceA,不能调用impleB,这是正常的,但是我
//不明白的是i也能调用toString(),这应该是Object中的方法,但是
//接口是不能继承类的,
//我想问接口是不是也有一个类似Object这样的
//顶级接口,若不是,为什么i可以调用Object中的方法??
}
}
我们平时写的
public class ClassType{}默认就是继承自Object类的,只是不用写出来而已,所以
public class ClassType implements Interface{}同样是默认继承了Object类的。
我们平时写的
public class ClassType{}默认就是继承自Object类的,只是不用写出来而已,所以
public class ClassType implements Interface{}同样是默认继承了Object类的。
==============================================================================
可是接口里没有定义toString() 方法啊 就像接口 里没有定义public void impleB()一定
不能调用impleB 为什么可以调用toString()
toStrting调用的是Object中的方法
你页可以覆盖他
Object是一切类的祖先!里面有toString(),equals()等等公共方法,所有的类都可以调用这些方法!可以参考一下API,查查java.lang.Object
那谁给我解释一下为什么InFace i = new Imple();
i不能调用impleB()方法
//以下这是正确的
public class Aclass extends Object
{
}
//以下这是不正确的
public interface Bface extends Object
{
}
//错误是:
//The type Object cannot be a superinterface of InFace; a superinterface must be
// an interface
//我定义的InFace是interface, i 对象只能调用InFace接口中的方法,所以虽然i指向
//Imple 对象,但由于i被定义为InFace,只能调用InFace接口中的方法,要调用ImpleB ,
//要做强制转换即:((Imple)i).impleB();
//上面各位高人都说“所有的类都是继承Object”,若接口也继承Object,不是和接口的定义
//即:
//接口中只能“声明”方法,不能“定义”方法矛盾吗,因为它继承了一个“定义”了方法的类
//Object。若你说i可以调用Object的方法是由于指向了Imple的原因,那我更不认同,
//没有做强制转换前,i不能调用Imple中自己定义的方法,和它的父类的方法。如:
//in file ImpleFather.javapublic class ImpleFather
{
public void impleFa()
{
System.out.println("Imple father method");
}
}
//in file Imple.javapublic class Imple extends ImpleFather implements InFace
{
public void inFaceA()
{
System.out.println("InterFace method!");
}
public void impleB()
{
System.out.println("Implement method!");
}
}//如此定义后,main中的i是不能调用impleFa(),和impleB()的,
//so,so,我问接口是不是有一个顶级接口!!!!!!
“public class Object”
public class ImpleFather其实他是这样子的
public class ImpleFather extends java.lang.Object,后面那部分省掉了,你看不见。。
也就是说默认继承Object类
我想地球人都知道,你还没有明白我说什么,我想joejoe1991() 明白我说什么。
//以下这是正确的
public class Aclass extends java.lang.Object
{
}
//以下这是不正确的
public interface Bface extends java.lang.Object
{
}
举个例子
jdk 中如String类层次是
java.lang.Object
|_java.lang.StringControl接口层次是
public interface Control extends Serializable
Serializable 接口层次是 public interface Serializable,就是说Serializable已经是顶级父接口了。
若Serializable继承Object,jdk会写出来的。
我确实同意这是在钻牛角尖。但是我没有自以为是啊!!!!
最后我猜这问题应该是:接口语法上虽然不能继承类,但是java内部搞了点特殊,令所有接口也继承了Object,只是作为用户的我们不能做而已。
============================================================================
连楼主意思都没看明白 你有什么资格去骂人?
我承认我基础学的不好
难道你一生出来就很牛B么! 我就是不明白接口里没有toString() 方法 为什么还可以调用!
难道接口也继承Object类? 我想这应该和Object是任何类的基类这一点没什么关系的吧?
如果你说因为toString() 是Object类的方法 所以可以调用 那我就又不明白了 为什么继承的方法都可以通过接口类型的引用调用 而自身的impleB()却不可以?讲明白了我随便让你们骂 讲不明白骂人的我当你是肛门和嘴长错了位置!
JSJ不是人人都能学的
这是JAVA多态的基础
接口名.class
这样也是取得到值的,只是不知道取道的是接口(类?)吗?
InFace i = new Imple();
i不能调用impleB()方法
这里只写了调用了inFaceA() 当然可以
lz代码里面没有i.inFaceB()吧 当然不能调用......
貌似接口中有隐式的toString()方法。
LZ不觉得你自己的想法才奇怪吗
JAVA的接口只是不允许做实现的特殊抽象类而已
:
public class A extends Object{}
能通过
public interface A extends Object{}
能通过吗?
能不能把问题看明白再回答呀??????
那接口怎么继承Object呢?
假如说有这么几个类和接口:
interface TestA {
}
interface TestB {
}
class TestC {
}
class TestD {
}
那么他们的关系可以是:
class Test1 implements TestA{
}
class Test2 implements TestB{
}
class Test3 implements TestA, TestB {
}
class Test4 extends TestC {
}
class Test5 extends TestD {
}
interface Test6 extends TestA {
}
interface Test7 extends TestB {
}
interface Test8 extends TestA, TestB {
}
class Test9 extends TestC implements TestA {
}
class Test10 extends TestC implements TestA, TestB {
}一个类可以继承另一个类,如果它没有显示的去继承认何类的话,那么他就默认的继承Object,所以一个类一出生,就一定是某个类的子类。
一个类只能继承一个类,不能继承多个类,当你显示的继承了一个类的话就不再继承Object了,但是,你继承的那个类可能继承Object,就算你继承的那个类没有继承Object,那么你继承的那个类继承的那个类(超类的超类)也可能继承了Object(一个类一出生就是某个类的子类)往下推............所以归根到底还是要认Object这个根,而且还是单根.
一个类可以实现多个接口,一个类也可以同时继承一个类和实现多个接口
接口只能继承接口,但是一个接口可以继承多个接口~!!!楼主的
public class Imple implements InFace
这句话的完整表述是:
public class Imple extends Object implements InFace
............我想你到了这里应该明白了吧~~~对待初学者应该要负责任一点,楼主想把问题严究透彻一点是好事,有点能力的应该要有点耐心~~~ 呵呵,话说多了~~~
InFace i = new Imple();
能被实例化出来,肯定是一个“活生生”的对象~~于是java语言规范实现了对任何对象都可以调用toString~~ 不要老是盯着 InFace i
要看new Imple();i不过是个reference而已~
LZ可以这样理解:
InFace i = new Imple();
能被实例化出来,肯定是一个“活生生”的对象~~于是java语言规范实现了对任何对象都可以调用toString~~ 不要老是盯着 InFace i
要看new Imple();i不过是个reference而已~
胡说八道~!!!!!!
有问题。但是像LZ说接口不能继承类,这没有错,
其实是你的这个类写好之后,它首先继承了object类了然后实现了InFace
只是LZ现解上有点问题吧。
星手说的对
public class Imple implements InFace =public class Imple extends Object implements InFace
而public class Imple implements InFace extends Object语法上就是有错,我们还争什么啊。
但接口对象也应该先继承object类了吧。
你没看到我上面回答了吗,就在你头上~~~ 可见你~~~~~~~~~~~~~~~~~~~~~~~~~
#############你没有看到i被cast了吗?谈何继承自object
******************************************我来说一下,希望能理解我的意思******************************************
******************************************这里牵扯到java虚拟机在new出对象时做了哪些事情:
1、InFace i = new Imple();
先看右边的new Imple();
这时jvm在堆区创建一个对象
如果没有显式继承一个类则默认继承于Object,因此当然可以调用Object中的方法了,就像
dreamover(梦醒了〖http://hellfire.cn〗) 说的:
public class Imple implements InFace =public class Imple extends Object implements InFace2、然后jvm在栈区生成一个类引用类型变量InFace i(在这里实质上是接口引用类型)
因为引用类型变量i是InFace 类型的,当然不能调用impleB()方法了,因为impleB()方法属于imple类的。再不懂,我就晕了
我擦擦汗去先!
就像默认的构造函数一样
因为这些方法写不写出来都不影响编码,所以就省略了
楼主的
public class Imple implements InFace
这句话的完整表述是:
public class Imple extends Object implements InFace
首先Imple类是这样定义的:public class Imple implements InFace (extends Object)
然后初始化对象i:InFace i = new Imple();
i就是类Imple的对象,而该类自动继承Object,
那么System.out.println( i.toString() );这句话很显然是类Imple的对象调用的父类Object中的toString()方法.
为什么你要觉得这个方法是调用接口中的方法?
等于
A extends Object implements B{}
接口对象的实例化实际上是一个接口对象作为一个引用,指向实现了它方法的那个类中的所有方法,这一点非常象C++中的函数指针,但是却是有区别的。java中的接口对象实例化实际上是一对多的,而C++中的函数指针是一对一的。
因此你将接口实例化后调用toString()实际上也指向了实现它方法的那个类中的相应方法..
}interface cc{
}Class c=cc.class;
System.out.println(c.getSuperclass()); Class[] cs=c.getInterfaces();
for(int i=0;i<cs.length;i++)
System.out.println(cs[i]);结果 null改为dd
结果
class java.lang.Object
interface test.cc
******************************************我来说一下,希望能理解我的意思******************************************
******************************************这里牵扯到java虚拟机在new出对象时做了哪些事情:
1、InFace i = new Imple();
先看右边的new Imple();
这时jvm在堆区创建一个对象
如果没有显式继承一个类则默认继承于Object,因此当然可以调用Object中的方法了,就像
dreamover(梦醒了〖http://hellfire.cn〗) 说的:
public class Imple implements InFace =public class Imple extends Object implements InFace2、然后jvm在栈区生成一个类引用类型变量InFace i(在这里实质上是接口引用类型)
因为引用类型变量i是InFace 类型的,当然不能调用impleB()方法了,因为impleB()方法属于imple类的。再不懂,我就晕了
我擦擦汗去先!
===================================================================================
一看就你是根本没有好好看贴子!下面这句话是你自己说的:
因为引用类型变量i是InFace 类型的,当然不能调用impleB()方法了,因为impleB()方法属于imple类的。那我问你toString()方法是属于Object类的! 为什么InFace类型的引用可以调用!如果你说因为Imple 类继承了Object类 所以可以调用! 那小菜我又有问题了! 为什么自身的impleB()方法都不能调用却能调用父类的方法?还有 那些老说Object类是所有类的基类的 也是没有认真看贴子的。
…………………………………………………….我想对于初学者最好不要去研究这些问题,要不能你们可能会陷进去而“走火入魔”的,因为你们对知识的积累还不多,还无法让自身现有的知识去接受它,等你们对Java有所了解了之后,再回来研究一下这些问题吧~!!!
但是确实通过接口可以在没有定义的情况调用Object的方法 不只是上面提到的toString 这应该是JRE在处理接口时的问题也许是作于这样的考虑 由于接口不是类(说接口是类的应该是把它更抽象类弄混了) 所以接口是没办法实例化的。
楼主InFace i = new Imple(); 实际上i这个InFace接口的引用是依托于一个Imple的对象存在的(也就是一个接口引用最终实际上是指向一个实现这个接口的类的对象)
然后就如上面的各位所说,在Java中,一个类都直接或间接派生至Object类 而Object类也定义了一个类最常用的基本方法 所以JRE就允许接口可以在没有定义的情况调用
不然如果System.out.println(i);就更难解释了。上面仅是猜测 具体怎样 也许只有JRE源代码能解释一切
*****
***我想对于初学者最好不要去研究这些问题,要不能你们可能会陷进去而“走火入魔”的,因为你们对知识的积累还不多,还无法让自身现有的知识去接受它,等你们对Java有所了解了之后,再回来研究一下这些问题吧~!!!********
*****
***同志,你终于理解LZ同志的意思了~~~~
-----------------------
1、在JAVA语言中,你想实现的内容,都是靠CLASS或者CLASS的对象来实现的,JAVA的虚拟机,运行的永远是CLASS或者CLASS的对象。
2、接口。接口是一套通用功能的表示,如果一个CLASS,他使用了某个接口,即CLASS IMPLEMENTS INTERFACE,说明该CLASS遵循此INTERFACE的规范,可以实现此INTERFACE的功能。
3、public class Imple implements InFace 。是在告诉编译器,CLASS Imple遵循INTERFACE InFace的标准,也就是说,CLASS Imple具体的实现了INTERFACE InFace的功能,当你想使用INTERFACE InFace时,允许你吧CLASS Imple做为这个接口的具体实现。
4、InFace i = new Imple();是在告诉编译器我要使用接口InFace,是依托类Imple做为具体的 功能实现的,现在使用的、操作的只是一个接口InFace,就是说只能调用InFace声明的方法,就像作者缩说的://此处i只能显示调用inFaceA,不能调用impleB,这是正常的
5、JAVA语言是单根继承的,祖先类是OBJECT.
6、//不明白的是i也能调用toString(),这应该是Object中的方法。结合我上面1、2、5所说的,假如我是编译器,首先我能肯定的是CLASS Imple能实现OBJECT 的所有方法,也能实现INTERFACE InFace的所有方法,此时,我操作的仅仅是一个INTERFACE InFace,我所能肯定的就是该INTERFACE和祖先类OBJECT的所有方法肯定会被实现,所有ToString()肯定是能被调用的。
public class A implements I{}等价于:public class A extends Object implements I{}这种说法我同意,但是:但是:我的引用是I ======>>(I i=new A();)i.toString();我用的是I这个接口啊,不是A啊,我承认A里面有toString()方法,但是I里没有啊???按理说应该是:
if(i instanceof A){
A a=(A)i;
a.toString();
}运行时类型是A,但编译时类型是I啊,应该编译都无法通过才对呀
难道 Object o=(Object)i;
这样写,怎么看都怎么别扭
==============================================================================我们的问题不是在你说的这些
我们的问题是 为什么接口里没有toString() 方法而接口的引用却可以调用它!
你说的继承了object类 这谁都知道! 可是这跟接口能调用这个方法有啥关系?
你说的继承了object类 这谁都知道! 可是这跟接口能调用这个方法有啥关系?
========================================================================这样是为了调用方便,既然所有的实例都已经继承Object类,任何一个实例理所当然可以调用Object的方法,这样会给编写代码带来方便,谁会喜欢在将一个实例强制去转换为Object,然后在去调用里面的toString方法。
=============================================================================
我觉得你还是没有看懂我们问的是什么。
总之一句话 为什么接口里没有定义一个方法 却可以用这个接口的引用去调用这个方法
比如接口A里有method() 方法
类B实现了接口A 也实现了method方法 同时类B里还有一个othermethod() 方法
这个时候 A b=new B();
b.method();///没错
b.othermethod(); /////报错! 虽然B类里有othermethod() 方法 可是接口A里没有定义这个方法!可是
b.toString(); 没有报错同样是接口A里没有定义toString()方法 为什么却可以调用 这下明白我们问什么了吧?
如果你自己写一个编译器,允许b.othermethod()通过编译,编译后的class文件在jvm中运行应该是不会报错的。
所以,我觉得是编译器为接口作了特殊处理。
我觉得LZ就当JVM做了特殊的假定好了i虽然是一个接口引用,但它引用的肯定是一个实例对象而且任何实例对象都是Object
==================================================================================
问题是接口中如果没有暴露TOSTRING方法那他就不会看到实例中大TOSTRING方法啊
const #1 = class #7; // InFace
const #2 = class #8; // java/lang/Object
const #3 = Asciz inFaceA;
const #4 = Asciz ()V;
const #5 = Asciz SourceFile;
const #6 = Asciz 1.java;
const #7 = Asciz InFace;
const #8 = Asciz java/lang/Object;const #1 为class文件中this_class项所指
const #2 为class文件中super_class项所指
自认为n天前发的帖子解释的很清楚了,我实在没招了
建议不明白的去看看《深入java虚拟机》,懒的看的,建议查阅一下对象生成的整个过程,jvm在内存中的三个区(堆、栈、方法区)到底做了哪些事 ,再查查动态绑定!!!
************************
建议 joejoe1991()
************************
*********************** 去看看jvm是怎样调用成员方法、父类(或接口)方法、怎样调用实例变量、怎样调用静态变量、怎样调用..............看看动态绑定吧
已经好几个星星了,不该这样啊,呵呵
针对帖子,不是针对人啊,呵呵
************************
建议 joejoe1991()
************************
*********************** 去看看jvm是怎样调用成员方法、父类(或接口)方法、怎样调用实例变量、怎样调用静态变量、怎样调用..............看看动态绑定吧
已经好几个星星了,不该这样啊,呵呵
针对帖子,不是针对人啊,呵呵
====================================================================================
三角多并不代表技术就有多好。
偶基础知识不怎么样滴。
偶现在正在补基础知道
有时间会看看你推荐的那本书的
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.
http://blog.csdn.net/zhangxiaoxiang/archive/2006/09/03/1173253.aspx
signature s, return type r, and throws clause t
学习了