What & How & Why

差别

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

到此差别页面的链接

两侧同时换到之前的修订记录前一修订版
后一修订版
前一修订版
cs:programming:java:courses:gtx_cs1311x:oop_n_algorithms [2024/01/22 12:05] 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====
行 1002: 行 1003:
 </code> </code>
 <WRAP center round tip 100%> <WRAP center round tip 100%>
-method call **只考虑声明类型**中是否存在该函数的定义,不考虑对象类型;**除非对象类型中存在着该 method 的 overriding**+method call **只考虑声明类型**中是否存在该函数的定义,不考虑对象类型;**除非对象类型中存在着该 method 的 overriding**(详情见之后的动态绑定)
 </WRAP> </WRAP>
 ===Casting=== ===Casting===
行 1011: 行 1012:
 ((Poodle)pixy).enterDogShow(); ((Poodle)pixy).enterDogShow();
 </code> </code>
-Casting 可以在继承关系树上**向上**,或是**向下**进行,得到的结果是一个**临时的**转换后的 Object 类型(的引用)。我们只需要确保 Casting 之后的**类型可以访问被调用的方法**即可。+Casting 可以在继承关系树上**向上**,或是**向下**进行(注意不是 is-a 或者 has-a 的关系不行!),得到的结果是一个**临时的**转换后的 Object 类型(的引用)。我们只需要确保 Casting 之后的**类型可以访问被调用的方法**即可。
 <WRAP center round info 100%> <WRAP center round info 100%>
 Casting 只是生成了一个**临时的**,对应的 Object 类型的引用。''pixy'' **永远**都是指向 ''Canine'' 类型的引用。 Casting 只是生成了一个**临时的**,对应的 Object 类型的引用。''pixy'' **永远**都是指向 ''Canine'' 类型的引用。
 +</WRAP>
  
 ==Casting 潜在的问题== ==Casting 潜在的问题==
-Casting 带来了一个后果之前的例子中,''pixy'' 的 Object type 是 ''Poodle''decalr type 是 ''Canine''+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'
 +Canine pixy;   
 +pixy = new Poodle(...);  
 + 
 +//call Dog.bark() 
 +pixy.bark(); 
 +</code>