我的代码如下所示:
public abstract class BaseClass{
public void update() {
//...
}
public void somethingHappenedSoCallUpdate() {
update();
}
}
public class ExtendingClass extends BaseClass{
@Override
public void update() {
//...
}
}
有一个ExtendingClass
的实例,在某些时候调用方法somethingHappenedSoCallUpdate()
。我希望该方法会调用BaseClass.update()
,但调用ExtendingClass.update()
。有人可以解释原因吗?
答案 0 :(得分:1)
我希望该方法会调用
BaseClass.update()
,但会调用ExtendingClass.update()
。有人可以解释原因吗?
因为这就是Java的定义方式。默认情况下,所有非private
方法都是虚拟,这意味着当您重写方法时,在实例上调用的方法是实例的覆盖率最高的版本({{1在你的情况下,无论通过哪个类型引用进行方法调用。这是现代OOP语言中多态性的基础。
编译时类型引用告诉编译器代码是否可以访问该方法;对象的运行时类型告诉JVM覆盖要调用的方法。
我们举一个简单的例子:
ExtendingClass
答案 1 :(得分:0)
它是多态的:在运行时调用正确的方法,具体取决于它是动态绑定的对象的实际类型。
答案 2 :(得分:0)
您覆盖了方法,因此如果您仍希望运行抽象类中的代码,则需要在重写方法中隐式调用public class ExtendingClass extends BaseClass {
@Override
public void update() {
super.update(); // Call the base method.
}
}
。所以......
public function searchCourier(){
if($this->processRequest){
$err = false;
if(empty($this->requestData['lat'])){
$this->responceData['message'] = "Please enter latitude";
$err = true;
}
if(empty($this->requestData['long'])){
$this->responceData['message'] = "Please enter longitude";
$err = true;
}
if(!$err){
$lat = $this->requestData['lat'];
$long = $this->requestData['long'];
$this->loadModel('UserDetail');
$data = $this->UserDetail->query("SELECT id,courier_address,courier_lat,courier_long,( 3959 * acos( cos( radians( '$lat' ) ) * cos( radians( courier_lat ) ) * cos( radians( courier_long ) - radians( '$long' ) ) + sin( radians( '$lat' ) ) * sin( radians( courier_lat ) ) ) ) AS distance
FROM user_details HAVING distance <= 5 ORDER BY distance LIMIT 0 , 20");
$this->responceData['result'] = array();
// check if has data returned
if($data) {
foreach($data as $val) {
// try to var_dump or print_r the $val
// print_r($val);
// if $val data is = array(
// 'UserDetails' => array(
// "id" => "15",
// "courier_address" => "Globallogic MIHAN SEZ Centre, MIHAN, Nagpur, Dahegaon, Maharashtra, India",
// "courier_lat" => "21.0487625",
// "courier_long" => "79.03471179999997"
// ),
// 0 => array(
// "distance" => 123.3
// )
// );
// store data as array
$this->responceData['result'][] = array(
'user_details' => array(
"id"=> $val['UserDetails']['id'],
"courier_address"=> $val['UserDetails']['courier_address'],
"courier_lat"=> $val['UserDetails']['courier_lat'],
"courier_long"=> $val['UserDetails']['courier_long'],
"distance"=> $val[0]['distance']
)
);
}
}
$this->responceData['status'] = 1;
$this->responceData['message'] = "Success";
$result = array(
'responseData' => array(
'result' => $this->responceData['result']
)
);
return json_encode($result);
} else {
$this->responceData['status'] = 0;
$this->responceData['message'] = "Something Went Wrong.Please Try again";
}
}
}
希望有所帮助:)
答案 3 :(得分:0)
正如@hyde所说,Java方法是虚拟的,这意味着VM在运行时决定调用哪个方法。如果您在扩展somethingHappenedSoCallUpdate()
的实例上调用BaseClass
,则会调用BaseClass.somethingHappenedSoCallUpdate()
,但由于ExtendingClass
覆盖BaseClass.update()
,因此会ExtendingClass.update()
分组而不是BaseClass.update()
。
扩展方法时,你必须这样想:
无论何时扩展一个方法,你把它放在一个堆栈上,当你调用它时,Java会看到这个&#34; stack&#34;并调用最顶层的。这意味着如果你有一个BaseClass
有一个update()
方法,这个类可以通过X类扩展而不是覆盖update()
方法,但是如果X + 1类有,那么Java将永远称之为X + 1的方法。
答案 4 :(得分:0)
因为你覆盖了子类中的更新,并且因为java方法是虚拟重写版本,所以调用它。
覆盖更新,覆盖somethingHappenedSoCallUpdate()
方法并使用super.update()
代替update()
。
在超类中将更新设为私有:
private void update()