抽象类方法声明

6
我刚刚写了这样的代码:

这个标签是HTML标签。

<?php
class test
{
// Force Extending class to define this method
abstract protected function getValue();
abstract protected function prefixValue($prefix);

// Common method
public function printOut() {
    print $this->getValue() . "\n";
}
}
class testabs extends test{

public function getValue()
{

}
public function prefixValue($f)
{

}
}
$obj = new testabs();
?>

当我运行这段代码时,我收到了以下错误:
致命错误:类test包含2个抽象方法,因此必须在C:\wamp64\www\study\abstract.php的第12行中声明为抽象或实现剩余方法(test::getValue, test::prefixValue)
我理解了错误信息的前半部分。我将类test更改为抽象类,错误就消失了,但我不理解“或”部分的含义。

"or" 部分是从一个类扩展您的 test 类的角度来看的。它是双向的;要么将您的 test 类设为抽象类,要么将扩展 test 的任何其他类设为抽象类,因为它们没有实现任何继承的抽象声明。 - dbf
4个回答

9
如果你想要添加抽象方法,那么你需要将该类也声明为 abstract。这样,该类就不能被实例化,只有非抽象子类才能被实例化。
关于方法的可见性(请参考第二个小节方法的可见性),在子类中是不同的。根据你是否希望让代码外的子类调用这些方法,你可以在类test中声明(抽象)方法为public的可见性,或者也可以在子类方法中声明为protected的可见性。
此外,注意来自类抽象页面第二段说明:

从抽象类继承时,父类声明中标记为抽象的所有方法必须由子类定义;此外,这些方法必须使用相同的(或更少限制的)可见性进行定义。例如,如果抽象方法被定义为 protected,则函数实现必须被定义为 protected 或 public,但不能是 private。

<?php
abstract class test{
    // Force Extending class to define this method
    abstract protected function getValue();
    abstract protected function prefixValue($prefix);

    // Common method
    public function printOut() {
        print $this->getValue() . "\n";
    }
}
class testabs extends test{

    protected function getValue()
    {

    }
    /**
    *   this method can be called from other methods with this class 
    *   or sub-classes, but not called directly by code outside of this       class
    **/
    protected function prefixValue($f)
    {

    }
}
$obj = new testabs();
// this method cannot be called here because its visibility is protected
$obj->prefixValues();// Fatal Error
?>

好的,我更新了我的答案 - 请看新的第一段。 - Sᴀᴍ Onᴇᴌᴀ

3
抽象类和接口的主要技术区别如下:
  • 抽象类可以拥有常量、成员变量、方法存根(没有方法体的方法)和已定义的方法,而接口只能拥有常量和方法存根。
  • 抽象类的方法和成员变量可以使用任何访问修饰符进行定义,而接口的所有方法必须定义为public(默认情况下为public)。
  • 当继承一个抽象类时,具体子类必须定义抽象方法,而抽象类可以扩展另一个抽象类,并且不需要定义父类的抽象方法。
  • 同样地,扩展另一个接口的接口不需要实现父接口的方法。这是因为接口不能定义任何实现。
  • 子类只能扩展单个类(抽象或具体),而接口可以扩展多个其他接口或者被类实现。
  • 子类可以定义相同或者更少限制的可见性的抽象方法,而实现接口的类必须使用完全相同的可见性来定义方法(public)。

2
你的类有抽象函数但未声明为抽象类,所以你有两个选择。要么将类声明为abstract,要么提供抽象函数的实现。
第一个选项(你尝试过的)允许该类存在并被具体的子类使用,这些子类实现了这些函数。第二个选项意味着该类已经完全定义好,并可以直接使用。

0
当你的classabstract方法时,它也必须被声明为abstract。因此以下写法是正确的:
<?php
abstract class test
{
  // Force Extending class to define this method
  abstract protected function getValue();
  abstract protected function prefixValue($prefix);

  // Common method
  public function printOut() {
    print $this->getValue() . "\n";
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接