【问题标题】:Abstract class method declaration抽象类方法声明
【发布时间】:2016-10-02 05:21:12
【问题描述】:

我刚刚写了这样的代码:

<?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 中声明为抽象或实现其余方法(test::getValue, test::prefixValue) \abstract.php 第 12 行

我了解此错误的第一部分。我将类测试更改为抽象并且错误消失了,但or 部分我无法理解。

【问题讨论】:

  • or 部分是从类扩展您的test 类的角度来看的。它是双向的;要么使您的test 类抽象使任何其他扩展test 的类抽象,因为它们不实现任何继承的抽象声明。

标签: php oop


【解决方案1】:

如果您要添加抽象方法,那么您还需要创建类abstract。这样,类就不能被实例化——只有非抽象的子类可以。

方法visibility(参考第二小节Method Visiblilty)在子类中不一样。根据您是否希望方法被子类之外的代码调用,您可以在类test 中声明(抽象)方法,可见性public,或者声明子类方法也可见性@987654327 @。

注意Class Abstraction page 的第二段,它解释了这一点:

从抽象类继承时,所有在父类声明中标记为抽象的方法都必须由子类定义;此外,这些方法必须定义为具有相同(或较少限制)的可见性。例如,如果抽象方法定义为受保护,则函数实现必须定义为受保护或公共,但不能定义为私有

<?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
?>

【讨论】:

  • 好的,我更新了我的答案 - 请参阅新的第一段。
【解决方案2】:

抽象类接口之间的主要技术区别是:

  • 抽象类可以有常量、成员、方法存根(没有主体的方法)和定义的方法,而接口只能有常量和方法存根。
  • 抽象类的方法和成员可以定义为任何可见性,而接口的所有方法都必须定义为公共(默认情况下它们被定义为公共)。
  • 继承抽象类时,具体的子类必须定义抽象方法,而抽象类可以扩展另一个抽象类,而不必定义父类的抽象方法。
  • 类似地,扩展另一个接口的接口不负责从父接口实现方法。这是因为接口不能定义任何实现。
  • 子类只能扩展一个类(抽象或具体),而一个接口可以扩展或一个类可以实现多个其他接口。
  • 子类可以定义具有相同或较少限制可见性的抽象方法,而实现接口的类必须定义具有完全相同可见性(公共)的方法。

【讨论】:

    【解决方案3】:

    您的类具有抽象函数但未声明为抽象,因此您有两种选择。要么将类声明为abstract,要么提供抽象函数的实现。

    第一个选项(您尝试过)允许该类存在并由实现这些功能的具体子类使用。第二个选项表示该类已完全定义,可以按原样使用。

    【讨论】:

      【解决方案4】:

      当您的class 具有abstract 方法时,它也必须声明为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";
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2016-05-10
        • 2015-02-28
        • 2011-07-18
        • 2011-01-23
        • 2015-06-29
        • 2012-10-31
        • 2016-12-09
        • 1970-01-01
        相关资源
        最近更新 更多