簡體   English   中英

“X類擴展Y(抽象),Y實現Z(接口)。 “不能調用接口Z的抽象方法”

[英]“Class X extends Y (abstract), Y implements Z (interface). ”Cannot call abstract method of interface Z"

這是我的PHP抽象類。 最底層的類是擴展抽象類並將一些復雜的計算邏輯留給父實現的類之一。

接口類(最頂層的抽象)的要點是強制那些較低的實現具有自己的static public function id($params=false){方法。

// My top level abstraction, to be implemented only by "MyAbstraction"
interface MyInterface{
      static public function id();
}

// My second (lower) level of abstraction, to be extended
// by all child classes. This is an abstraction of just the
// common heavy lifting logic, common methods and properties.
// This class is never instantiated, hence the "abstract" modifier.
// Also, this class doesn't override the id() method. It is left
// for the descendant classes to do.

abstract class MyAbstraction implements MyInterface{

    // Some heavy lifting here, including common methods, properties, etc
    // ....
    // ....

     static public function run(){
          $this->id = self::id(); // This is failing with fatal error
     }
}

// This is one of many "children" that only extend the needed methods/properties
class MyImplementation extends MyAbstraction{

     // As you can see, I have implemented the "forced"
     // method, coming from the top most interface abstraction
     static public function id(){
         return 'XXX';
     }
}

最終的結果是,如果我打電話:

$o = new MyImplementation();
$o->run();

我得到致命錯誤: Fatal error: Cannot call abstract method MyInterface::id();

為什么MyAbstraction::run()調用其父(接口)的id()方法而不是在其子(后代)類中找到的方法?

  1. 在接口中聲明的所有方法都必須是公共的; 這是界面的本質。 參考 - PHP界面

  2. 你在MyAbstraction類中使用self::id()self總是指同一個類。 引用自我與靜態

你應該使用靜態而不是自我。 請參閱以下代碼。

interface MyInterface{
    public function id();
}

abstract class MyAbstraction implements MyInterface{

    public $id;
    // Some heavy lifting here, including common methods, properties, etc
    // ....
    // ....

    public function run(){
        $this->id = static::id(); // This is failing with fatal error
    }
}

class MyImplementation extends MyAbstraction{

    // As you can see, I have implemented the "forced"
    // method, coming from the top most interface abstraction
    public function id(){
        return 'XXX';
    }
}

$o = new MyImplementation();
$o->run();

在上面的代碼中, static::id()將調用上下文中的類函數,即MyImplementation類。

這種現象稱為后期靜態綁定

“self”是指“MyAbstraction”類(本身)。 所以它試圖搜索MyAbstraction::id() ,並得到一個錯誤。

  1. 你應該使用“static”關鍵字static::id();
  2. 你不能在靜態方法中使用$ this ($this->id)
  3. 您的所有方法都是靜態的,因此您不需要實例化對象。 您可以使用靜態調用執行相同的操作: MyImplementation::run();

嘗試用static::id()替換你的self::id() static::id()

你在這里使用PHP的Late Static Bindings

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM