What & How & Why

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录前一修订版
后一修订版
前一修订版
cs:programming:java:courses:gtx_cs1311x:oop_n_algorithms [2024/01/22 11:48] – [Method Calls] codingharecs:programming:java:courses:gtx_cs1311x:oop_n_algorithms [2024/01/22 12:36] (当前版本) – [实例:扔骰子] codinghare
行 250: 行 250:
     - 访问私有变量一定要通过 Accessor     - 访问私有变量一定要通过 Accessor
     - 除了 ''Math.Random()'',Java 还提供了 ''util.Random'' 供使用。本例使用了 ''Random.nexInt(bound)'' 实现了骰子的随机结果。     - 除了 ''Math.Random()'',Java 还提供了 ''util.Random'' 供使用。本例使用了 ''Random.nexInt(bound)'' 实现了骰子的随机结果。
 +      - ''Random.nexInt(bound)'' 返回的区域是 $[0, bound)$
 //Source code with comments//: {{ :cs:programming:java:courses:gtx_cs1311x:craps.zip |}} //Source code with comments//: {{ :cs:programming:java:courses:gtx_cs1311x:craps.zip |}}
 ====Inheritance==== ====Inheritance====
行 1000: 行 1001:
 //error, Canine doesn't define enterDogShow, even if pixy's instantiate type is Poodle //error, Canine doesn't define enterDogShow, even if pixy's instantiate type is Poodle
 pixy.enterDogShow(); pixy.enterDogShow();
- 
-//in case of using enterDogshow(), we need casting  
-(Poodle)pixy.enterDogShow(); 
 </code> </code>
 <WRAP center round tip 100%> <WRAP center round tip 100%>
-method call **只考虑声明类型**中是否存在该函数的定义,不考虑对象类型+method call **只考虑声明类型**中是否存在该函数的定义,不考虑对象类型;**除非对象类型中存在着该 method 的 overriding**(详情见之后的动态绑定)
 </WRAP> </WRAP>
 +===Casting===
 +上述例子中,如果我们希望使用 ''pixy'' 直接访问 ''enterDogShow()'',我们需要将其转换为 ''Poodle'' 类型:
 +<code js>
 +//ok, in case of using enterDogshow(), we need casting 
 +// !!!notice the praentheses!!!
 +((Poodle)pixy).enterDogShow();
 +</code>
 +Casting 可以在继承关系树上**向上**,或是**向下**进行(注意不是 is-a 或者 has-a 的关系不行!),得到的结果是一个**临时的**转换后的 Object 类型(的引用)。我们只需要确保 Casting 之后的**类型可以访问被调用的方法**即可。
 +<WRAP center round info 100%>
 +Casting 只是生成了一个**临时的**,对应的 Object 类型的引用。''pixy'' **永远**都是指向 ''Canine'' 类型的引用。
 +</WRAP>
 +
 +==Casting 潜在的问题==
 +Casting 带来了一个问题。来看以下例子:
 +<code js>
 +Canine dg;
 +dg = new Dog(...);
 +
 +//is thi legal?
 +((Poodle)dg).enterDogShow();
 +</code>
 +这种情况下, ''dg'' 的 object type 是 ''Dog'',而不是 ''Poodle''。Casting 是可以进行的;但是在调用 method 的时候,//JVM// 会做 //Is a// 的检测。上面的例子中,我们调用的是 ''Poodle'' 类型实现的 method,在调用之前,编译器会询问:调用者的 object type 是不是 method 实现所在的 object type? (此处就是在问:''Dog'' 是 ''Poodle'' 吗?)如果不是,那该 method call 就无法通过编译。
 +===Dynamic Binding===
 +在检测 method call 是否合法的同时,JVM 还会同时在**运行期**检测哪一个版本最适合当前的 call。处理该调用匹配的过程被称为**动态绑定**(//Dynamic Binding//)。总的来说:
 +  * 如果 object type 和 declar type 中存在不一样的实现(即 object type 中有重写),那么选择 object type 的版本
 +<code js>
 +//if Canine & Poodle both have a bark() implementation
 +Canine pixy;  
 +pixy = new Poodle(...); 
 +
 +//call Poodle.bark()
 +pixy.bark();
 +</code>
 +  * 如果 object type 中不存在重写,JVM 会按照继承树**逐级往上查询**,直到找到对应的实现
 +<code js>
 +//if Canine & Dog both have a bark() implementation, but Poodle dosen't
 +Canine pixy;  
 +pixy = new Poodle(...); 
 +
 +//call Dog.bark()
 +pixy.bark();
 +</code>