|
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
时间:2005-08-18
首先看两段代码,一个父类,一个子类:
[code:1] public class HelloFather { public HelloFather(){ System.out.println("HelloFather.HelloFather()"); } public void sayHello(){ System.out.println("father hello"); } } [/code:1] [code:1] public class HelloSon extends HelloFather { public HelloSon() { } public static void main(String[] args) { HelloSon helloSon1 = new HelloSon(); helloSon1.execute(); } public void execute() { //execute(super); *********** } public void execute(HelloFather hf) { hf.sayHello(); } public void sayHello() { System.out.println("son hello"); } } [/code:1] 1。为什么打星号的那一句编译不通过呢?(据说在jb8下通过,但是在jb2005,eclipse3.x下都不通过) 2。super到底是什么? this是对当前对象的引用,可是super呢?如果说它是对父类的引用,为什么不能当参数传给别的方式,也不能转型,也不能用==比较。如果说不是,可是它又可以调用父类的方法? 3。 System.out.println("this : " + this.hashCode()); System.out.println("super : " + super.hashCode()); 这两句打印的结果相同,说明了什么? 4。 System.out.println("this : " + this.getClass()); System.out.println("super : " + super.getClass()); 它们打印出来的都是HelloSon,为什么super.getClass()也是HelloSon呢? 5。题外话 super是子类调用父类的方法,那么在子类中怎么调用爷爷类中的方法呢?又不能用this.super.super.xxx()这样的代码 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
时间:2005-08-18
这个问题问得好,顶一下
|
|
| 返回顶楼 | |
|
时间:2005-08-18
又是一个注定要进垃圾箱的帖子...
为什么打星号的地方编译通不过?因为编译器不认。 为什么编译器不认?因为你写错了。 为什么你写错了?因为没有这样的语法。 还需要更进一步的说明吗? |
|
| 返回顶楼 | |
|
时间:2005-08-18
B1-66-ER 写道 又是一个注定要进垃圾箱的帖子...
为什么打星号的地方编译通不过?因为编译器不认。 为什么编译器不认?因为你写错了。 为什么你写错了?因为没有这样的语法。 还需要更进一步的说明吗? 当然有需要进一步说明的地方: super究竟是什么?它的内部运行原理是什么样的? 为什么它拥有实例的引用的功能(可以调用父类对象的函数),或又不完全是一个引用(不能当作引用传给方法)。 为什么在jb8下可以编译,为什么在别的编译器上不能编译(经验证,只能在jb8的IDE环境下运行,在DOS下用jb8的jdk都不能通过编译。在jdk5.0下也不行。另:在jb8下,传super与传this的效果一样) 编译器在编译的时候,究竟是怎么对待super的。 如果你能告诉我这些,再把它丢进垃圾桶吧。 |
|
| 返回顶楼 | |
|
时间:2005-08-18
我一开始思考这个问题的时候,是把super和this做类比的。因为this是指向对象本身的引用,所以super有可能是指向父类对象的引用。而且,的确super拥有部分引用的功能,比如调用父类的函数、属性等,但是慢慢地发现,它又不能像this那样作为引用传给别的函数。
所以我就开始疑惑,到底super是什么? 生成了一个子类对象的时候,是不是有一个同时也生成了一个父类对象?还是父类对象作为一部分,被包含在子类对象中? 这个super,倒底是作为引用存在的,还是只是一个特殊的关键字,被赋予了少量的功能,由编译器来转化和实现。 为什么super.getClass得到的是子类的类型等等? 我真的很想知道,我已经想了6个小时了,有没有人可以提示一下呢? |
|
| 返回顶楼 | |
|
时间:2005-08-18
我没有权限删帖。版主才有。但我猜想本帖不会符合版主的标准。
我很奇怪,你既然有毅力自个想6个小时,为什么不化半个小时去看一下书呢?关于super关键字的问题任何一本Java书籍在关于Class的这一章都会有比较清楚的阐述。 还是那样的回答:编译通不过那是因为你写错了。至于怎样才是对的,书里写得再清楚不过了。 |
|
| 返回顶楼 | |
|
时间:2005-08-19
我也没有看过具体的官方的对super的介绍,就说说自己的理解。
先说"this",作为一个特殊的关键字,它的规则如下: 1。可以表示构造函数传递。this(a,b)表示调用另外一个构造函数。这里面的this就是一个特殊语法,不是变量,没有什么类型。 2。可以在一个类的非static成员内部使用,表示当前这个对象。此时,this就是一个final的普通变量,它有静态类型,就是这个类C本身;它有动态类型,就是当前这个对象的类型。你可以对它调用成员函数,把它传递给别的函数,等等等等。只要一个C类型的final变量可以出现的地方,它就可以出现。 再说"super"。它和"this"类似,但是也有不同的地方。 1。表示调用父类的构造函数。也是一个特殊语法,不是变量,没有什么类型。 2。可以在一个类的非static成员内部使用。比如super.method()。 但是,注意,这个super.method()只是长得跟some_var.method()一样,一个语法糖而已。实质上,"super"根本不是一个变量。 为什么不是?因为如果是就坏了。java里面有一个金科玉律:任何public非static函数的调用都是多态的。 所以,如果super是个变量,也指向当前对象,那么,不管super的静态类型是什么super.method()必然调用的是子类的那个版本,而不会是我们期望的,静态地选择父类的那个版本。 所以,你只要把super.xxx看成一个特殊的语法,比如理解为“super::xxx”就好了。 其实,如果谁熟悉jvm规范的,可以说一下。我估计,jvm规范里面必然有对super调用或者对非多态调用的相应指令。 既然super不是一个变量,那么不能把它象一个普通变量那样"==",或者传递给某个函数就看起来很正常了,是么?何况,你其实也用不着它,有this你这些要求就都可以办到了。 3。super的另外一个作用是调用父类的protected函数。只有通过"super"这个魔咒,我们才能操作父类的protected成员,别无它法。 |
|
| 返回顶楼 | |
|
时间:2005-08-19
谢谢ajoo!
只有你才明白我的疑惑在哪里,你的解答让我想通了许多,多谢! |
|
| 返回顶楼 | |
|
时间:2005-08-19
super是对父类的引用,但不是对父对象的引用(没有父对象这个说法),它不是一个对象,所以不能像this一样作为一个对象去使用。
通过super可以调用(该对象的)在父类中申明的变量和方法。(有访问控制) 为什么 this.getClass()和super.getClass()结果一样?因为子类并没有自己定义自己的getClass()方法,最终都是调用的共通父类的getClass()这个方法。 |
|
| 返回顶楼 | |
|
时间:2005-08-19
super对应的jvm指令是invokespecial,而动态调用是invokevirtual
|
|
| 返回顶楼 | |










