Topic: 关于继承的深入讨论 |
Print this page |
1.关于继承的深入讨论 | Copy to clipboard |
Posted by: jameszhang Posted on: 2005-08-11 19:24 来点基础的
谁能给出结果,并进行详细说明,如果是C++ 会怎样呢? |
2.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: truthawp Posted on: 2005-08-11 23:22 恩,通过对楼主代码修修改改,又对继承概念有了进一步了解,希望是彻底弄懂了 呵呵 C++的,不会^_^! |
3.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: hxz5830 Posted on: 2005-08-15 18:38 result:test1 test2(验证过的) 过程是:生成一个子类对象Test2,上传给父类Test1。好象调用函数getStr()时,是子类对象作用;而调用 Str时,又体现成父类对象。不是太清楚, 请高手指教 |
4.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: ww1ww1 Posted on: 2005-08-15 20:35 有人能说why吗。。。 |
5.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: jigsaw Posted on: 2005-08-15 22:12 看看javap便知 常识 |
6.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: whyuaou Posted on: 2005-08-16 09:17 运行结果和楼上的一样 Test1 Test2 不知道这样的理解有没有问题,还请高手们指教啊! |
7.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: ww1ww1 Posted on: 2005-08-16 10:03
如果interface也是一种class的话,那么something是子类Cat的实例,在interface中讲run() implements(实现)了Animals的run()方法,如果Animals是solid class那么就是override(重定义)了父类的run()方法 大多数人会认为System.out.println(t1.str);结果是test2 关键是System.out.println(t1.str);这个地方怎么理解。。。 但是如果将interface变成solid class 你会发现一个编译错误
|
8.Re:关于继承的深入讨论 [Re: whyuaou] | Copy to clipboard |
Posted by: jameszhang Posted on: 2005-08-16 19:25 whyuaou wrote: 有点自相矛盾,前面说 t1 是 Test1的实例,后面又说t1调用的是 Test2里面的方法 |
9.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: ww1ww1 Posted on: 2005-08-16 20:38 很少将类里面的成员变量public用的,一般都是private,然后get出来用的,所以较少碰到 t1.str 的问题。 另外发现,如果 Test2中有Test1中没有的方法例如:getSomething()
会报错误,说 getSomething()没有在Test1中定义。。。 |
10.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: breezehou Posted on: 2005-08-17 12:58 只有方法才能被overridden,而成员变量不可以,所以t1.getStr());调用的是子类的方法。 |
11.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: whyuaou Posted on: 2005-08-17 14:12 jameszhang wrote: 不矛盾啊,Test1里的getstr()方法被Test2的getstr()覆盖了啊,所以t1 调用的是Test2里的getstr()方法啊。 |
12.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: jokehan Posted on: 2005-08-17 15:56 字段是不能重写的,只有方法能重写! 楼主例子例子里,'t1'的型别在“编译期”就已经确定了是'Test1',而在“运行期”被向下转型为它的派生类'Test2',所以这时't1'里的'getStr()'方法被重写了,因此当调用't1.str'时,因字段不能重写,所以返回的还是'Test1'里的'str',而当调用't1.getStr()'时,因'Test1'里的'getStr()'方法被'Test2'重写了,所以调用的是被重写后的'getStr()'方法,也就是'Test2'里的'getStr()'方法,并返回内联字段'str',也就是'Test2'里的'str' :) |
13.Re:关于继承的深入讨论 [Re: ww1ww1] | Copy to clipboard |
Posted by: ww1ww1 Posted on: 2005-08-17 17:20 ww1ww1 wrote: t1不是Test2的实例吗,它怎么不可以调用Test2的方法。。。难道。。。 深度套牢中。。。。。 |
14.Re:关于继承的深入讨论 [Re: breezehou] | Copy to clipboard |
Posted by: jameszhang Posted on: 2005-08-17 21:09 breezehou wrote: 真有人用类的特性来解释,呵呵,“成员变量不可以“ 那么t2.str 的值说明什么? |
15.Re:关于继承的深入讨论 [Re: jokehan] | Copy to clipboard |
Posted by: jameszhang Posted on: 2005-08-17 21:41 jokehan wrote: 好哇! 快接近了,虽然从编译和运行期来看是这样,但为什么,也许你会说面向对象中的继承就是这样的,那好我们来看C++ 中是怎样的(请斑竹让我在java板块中写段C++代码,谢谢) ---------------------------------------------------- TestA.h
TestB.h #include "TestA.h" TestA.cpp #include "TestA.h" TestB.cpp
只是为了举例子所以写的很简单,在vc6上跑的结果是 |
16.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: jameszhang Posted on: 2005-08-20 10:09 其实这是个我们经常会忽略的语言中的概念 “隐藏规则“ |
17.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: jameszhang Posted on: 2005-08-28 14:29 这样做的好处实现动态绑定,如果按这样隐藏规则,java 能实现 动态绑定 ,而C++不能实现了, 动态绑定 又是多态 实现重要部分 , C++ 是 面向对象的语言,也是非常灵活的语言怎么会不支持动态绑定,哈哈,C++如果改变 隐藏规则,只需要在 基类的 函数前面加上 virtual,就跟java的实现一样了,呵呵 |
18.加精 [Re: jameszhang] | Copy to clipboard |
Posted by: ww1ww1 Posted on: 2005-08-28 23:13 |
19.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: hxz5830 Posted on: 2005-08-29 15:03 jokehan wrote: 字段是不能重写的,只有方法能重写! 字段也可以重写吧. ww1ww1 wrote: Test1 t1 = new Test2(); t1.getSomething(); //getSomething()这个方法存在于Test2中,不存在于Test1中 编译报错,说 getSomething()没有在Test1中定义。。。 t1不是Test2的实例吗,它怎么不可以调用Test2的方法。。。难道。。。 这样理解应该t1是Test1的实例,而不是Test2的实例.对吗? 楼主能说下t1是Test1的实例,还是Test2的实例,还是不能这样理解? |
20.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: jameszhang Posted on: 2005-08-29 21:21 = 的左边 是个变量 右边 是在堆里 分配的空间的 地址 左边 和 右边 要用隐藏规则来看 |
21.Re:关于继承的深入讨论 [Re: hxz5830] | Copy to clipboard |
Posted by: ww1ww1 Posted on: 2005-08-29 23:02 hxz5830 wrote: 这个东西好多书好像都没讲的,属于盲区。。。 |
22.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: ccikk Posted on: 2005-08-31 10:53 core java 的polymorphism描述中,明确说了,java的继承中,对象方法调用是late binding:object-oriented languages use the concept of late binding. When you send a message to an object, the code being called isn’t determined until run time. The compiler does ensure that the method exists and performs type checking on the arguments and return value (a language in which this isn’t true is called weakly typed), but it doesn’t know the exact code to execute 还举了例子: void doStuff(Shape s) { s.erase(); // ... s.draw(); } Circle c = new Circle(); Triangle t = new Triangle(); Line l = new Line(); doStuff; doStuff; doStuff(l); 而对class的成员变量,则使用early binding。只会根据变量的类型,来获取成员变量的值。 所以楼主的问题就很明确了。 |
23.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: ccikk Posted on: 2005-08-31 11:14 我觉得楼上的朋友用C++对比来说明很能说明问题,我也试了一下: #include "stdio.h" class TestA { public: int m; TestA() { m = 1; } virtual int getM() { return m; } }; class TestB : public TestA { public: int m; TestB() { m = 2; } int getM() { return m; } }; void main() { TestA *a = new TestB(); printf("%d\r\n", a->m); printf("%d\r\n", a->getM()); } 打印结果: 1 2 如果把TestA中getM的virtual修饰符号去掉, 打印结果: 1 1 这样我们就明白了,java的默认方式是lata binding(也叫动态帮顶),而C++默认的是静态绑定,除非使用了virtual修饰符。 还有,无论c++还是java,对成员变量都不能动态绑定的。 |
24.Re:关于继承的深入讨论 [Re: jameszhang] | Copy to clipboard |
Posted by: zcjl Posted on: 2005-09-05 21:14 《Java Pitfalls》 Item 1、5、6有说明:隐藏(Hidden)和覆盖(Overridden)的区别 |
Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1 客服电话 18559299278 客服信箱 714923@qq.com 客服QQ 714923 |