随笔 - 4  文章 - 10  trackbacks - 0
<2026年11月>
日一二三四五六
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

常用链接

留言簿(1)

随笔档案

文章分类

文章档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜

出处:http://www.blogjava.net/crazycy/archive/2006/10/11/74622.html

< 示例1>

 


 1 class  Base {
 2      int  x  =   2 ;
 3      int  method() {
 4          return  x;
 5     }

 6 }

 7
 8 class  SubClass  extends  Base {
 9      int  x  =   3 ;
10      int  method() {
11          return  x;
12     }

13 }

14
15 public   class  Main  { 
16          public   static   void  main(String[] args)  {
17         Base b  =   new  SubClass ();
18         System.out.println(b.x);
19         System.out.println(b.method());
20     }

21 }

 


2 , 3

 

 

<练习>

 


 1 class   s1    {   
 2        public   String  s = " s1 " ;   
 3        public   String  get()   {   
 4            return   s;   
 5       }
   
 6 }
   
 7 class   s2   extends   s1    {   
 8       public    String   s = " s2 " ;   
 9        public    String   get()    {   
10            return    s;   
11       }
   
12  }
   
13 public     class    s   {   
14        public     static     void    main(String[]   args)   {   
15           s1  a    =     new   s2();   
16           System.out.println(a.s);   
17           System.out.println(a.get());     
18       }
   
19  }
  

 


 1 这个地方就是多态的一个陷阱;   
 2 多态是对方法而言的,不是对变量;   
 3 s1 a  =   new  s2();这里生成的对象是s1类的实例,但是是由s2类构造的;   
 4     
 5   java中对变量的选择是静态的,对方法的选择是动态的,是在运行时决定的。(static除外)   
 6   运行时实际上调用的是实例的方法,即s1的方法;但对于继承(多态的一种方式),方法的定位是在动态执行时选择的,选择实际构造者,因此就出现了本题的现象了。   
 7
 8 另外:多态是对方法而言的,不是对变量;这样说有些不严密,方法应该有个修饰,就是除了final修饰的方法外,java中对函数的调用都是后期绑定,所谓的后期绑定就是动态选择
 9
10 摘自 崔毅解答csdn疑问时给出的分析
11
12

 


< 示例2>

 


 1 class  Base {
 2      private   final   void  f() {
 3         System.out.println( " Base.f() " );
 4     }

 5 }

 6
 7 class  Derived  extends  Base {
 8      public   final   void  f() {
 9         System.out.println( " Derived.f() " );
10     }

11 }

12
13 public   class  Main  { 
14          public   static   void  main(String[] args)  {
15         Derived op1  =   new  Derived();
16         Base op2 = op1;
17         op1.f();
18         op2.f();
19     }

20 }

21

 


op2.f();

 


<示例3>

 


 1 class    Parent {   
 2        private     void    method1() {   
 3           System.out.println( " Parent's   method1() " );   
 4       }
   
 5        public     void    method2() {   
 6           System.out.println( " Parent's   method2() " );   
 7           method1();   
 8       }
   
 9   }
   
10    class    Child    extends    Parent {   
11        public     void    method1() {   
12          System.out.println( " Child's   method1() " );   
13       }
   
14        public     static     void    main(String   args[]) {   
15           Parent   p    =     new    Child();   
16           p.method2();   
17       }
   
18   }
   

 


1 答案是:prints:   parent’s   method2()     parent’s   method1()   
2 如果把父类中method1改成public,那么答案是
3 prints:   parent’s   method2()     child’s   method1()

 


分析

多态:

Java 中的函数,除了声明外 final 的外,都是后期绑定。

所谓绑定是建立“函数调用”和“函数本体”的关联。、

所谓的后期绑定是指执行时根据对象类别而进行

多态仅仅对函数而言,不对变量而言;

变量的访问依赖于编译期引用指向的类型;

方法的访问依赖于执行期对象的类型;

向上转型后,调用某个函数,若 derived class overriding 了该函数,则会调用该 derived class 中的函数,否则会调用 base class 中的函数。

向上转型后,只能调用 base class 中被 derived class overriding 的函数,不能调用 derived class 中 extend 函数。

即向上转型后,只能调用 base class 中的方法,不能调用 derived class 中的扩展方法 
 

 


 1 public   class  CalC  {
 2      void  amethod() {
 3         System.out.println( " CalC.amethod " );
 4     }

 5     CalC() {
 6         amethod();
 7         System.out.println( " Hu? " );
 8     }

 9      public   static   void  main(String[] args)  {
10         CalC cc  =   new  CalChild();
11         cc.amethod();
12     }

13 }

14 class  CalChild  extends  CalC {
15      void  amethod() {
16         System.out.println( " CalChild.amethod " );
17     }

18 }

 


1 output:
2 CalChild.amethod
3 Hu ?
4 CalChild.amethod
5 为什么CalC Constructor调用的不是自己的amethod()呢

 


1 方法在内存中只有一个备份,所以的对象都共享这个备份,为了区分开到底是哪个对象在调用这个方法,关键的地方就是this的使用。this把调用方法的上下文对应到当前对象上。
2
3 第二,调用java中的所有成员变量或者成员函数都隐含了this。
4
5 所以这个地方就很明了了:构造子类,this指针代表的当前对象是子类实例,子类实例为啥不调用自己overriding的方法呢?!
6
posted on 2007-09-04 17:09 冬天出走的猪 阅读(283) 评论(0)  编辑  收藏 所属分类: j2se