60
class absclass {
    abstract public function fuc();
}

报告:

PHP 致命错误:absclass 类包含 1 个抽象方法,因此必须声明为抽象方法或实现其余方法(absclass::fuc)

我想知道实现其余方法意味着什么,如何?

4

7 回答 7

82

请参阅PHP 手册中关于类抽象的章节:

PHP 5 引入了抽象类和方法。定义为抽象的类不能被实例化,任何包含至少一个抽象方法的类也必须是抽象的。定义为抽象的方法只是声明方法的签名——它们不能定义实现。

这意味着你要么必须

abstract class absclass { // mark the entire class as abstract
    abstract public function fuc();
}

或者

class absclass {
    public function fuc() { // implement the method body
        // which means it won't be abstract anymore
    };
}
于 2010-03-03T13:29:58.827 回答
36

我认为剩余的方法实际上是指您尝试定义的抽象方法(在本例中为fuc()),因为可能存在的非抽象方法无论如何都是可以的。这可能是一条错误消息,可以使用更精确的措辞:它说剩余的地方可以说是abstract

修复非常简单(错误消息的那部分很好):您需要更改此:

abstract public function fuc();

...进入适当的实施:

public function fuc(){
    // Code comes here
}

...或者,或者,根据您的需要,使整个类抽象:

abstract class absclass {
    abstract public function fuc();
}
于 2010-03-03T13:29:08.483 回答
30

抽象类不能直接实例化,但它可以包含抽象方法和非抽象方法。

如果你扩展一个抽象类,你必须要么实现它的所有抽象函数,要么使子类抽象。

您不能覆盖常规方法并使其抽象,但您必须(最终)覆盖所有抽象方法并使它们非抽象。

<?php

abstract class Dog {

    private $name = null;
    private $gender = null;

    public function __construct($name, $gender) {
        $this->name = $name;
        $this->gender = $gender;
    }

    public function getName() {return $this->name;}
    public function setName($name) {$this->name = $name;}
    public function getGender() {return $this->gender;}
    public function setGender($gender) {$this->gender = $gender;}

    abstract public function bark();

}

// non-abstract class inheritting from an abstract class - this one has to implement all inherited abstract methods.
class Daschund extends Dog {
    public function bark() {
        print "bowowwaoar" . PHP_EOL;
    }
}

// this class causes a compilation error, because it fails to implement bark().
class BadDog extends Dog {
    // boom!  where's bark() ?
}

// this one succeeds in compiling, 
// it's passing the buck of implementing it's inheritted abstract methods on to sub classes.
abstract class PassTheBuckDog extends Dog {
    // no boom. only non-abstract subclasses have to bark(). 
}

$dog = new Daschund('Fred', 'male');
$dog->setGender('female');

print "name: " . $dog->getName() . PHP_EOL;
print "gender: ". $dog->getGender() . PHP_EOL;

$dog->bark();

?>

该程序炸弹:

PHP 致命错误:BadDog 类包含 1 个抽象方法,因此必须声明为抽象方法或实现其余方法(Dog::bark)

如果您注释掉 BadDog 类,则输出为:

name: Fred
gender: female
bowowwaoar

如果您尝试直接实例化 Dog 或 PassTheBuckDog,如下所示:

$wrong = new Dog('somma','it');
$bad = new PassTheBuckDog('phamous','monster');

..它炸弹:

PHP致命错误:无法实例化抽象类Dog

或(如果您注释掉 $wrong 行)

PHP 致命错误:无法实例化抽象类 PassTheBuckDog

但是,您可以调用抽象类的静态函数:

abstract class Dog {
    ..
    public static function getBarker($classname, $name, $gender) {
        return new $classname($name, $gender);
    }
    ..
}

..

$other_dog = Dog::getBarker('Daschund', 'Wilma', 'female');
$other_dog->bark();

这工作得很好。

于 2011-03-29T23:58:09.603 回答
4

此错误消息使您误入歧途。在这种情况下,由于它是在这个类fuc定义的,所以在这个类中实现它真的没有意义。该错误试图告诉您的是非抽象类不能有抽象方法。一旦将抽象方法放入类的定义中,您还必须将类本身标记为抽象。

于 2010-03-03T13:19:45.743 回答
4

抽象关键字用于将类或方法标记为模式。它类似于接口,但可以包含变量和方法的实现。

关于抽象类有很多误解。这是一个抽象 Dog 类的示例。如果开发人员想为其他开发人员创建一些基本的 Dog 类或为自己扩展,他将类声明为抽象类。您不能直接实例化 Dog 类(没有人可以),但您可以通过自己的类扩展 Dog。SmartDog 扩展了 Dog 等。

所有被 Dog 类声明为抽象的方法都必须在每个扩展 Dog 的类中手动实现。

例如,抽象类 Dog 有一个抽象方法 Dog::Bark()。但是所有的狗叫声都不一样。因此,在每个 Dog 子类中,您必须具体描述狗如何吠叫,因此您必须定义例如 SmartDog::Bark()。

于 2011-06-23T19:35:33.187 回答
3

这意味着抽象类的本质是具有至少一个抽象方法。所以你的类要么实现方法(非抽象),要么被声明为抽象的。

于 2010-03-03T13:18:39.287 回答
1

我想在非抽象类(普通类?)中使用抽象方法,并发现我可以使用 get_parent_class() 将方法的内容包装在“if”语句中,如下所示:

if (get_parent_class($this) !== false) {

或者,在行动中(在 cmd 行的文件中测试:php -f "abstract_method_normal_class_test.php"):

<?php
    class dad {
        function dad() {
            if (get_parent_class($this) !== false) {
                // implements some logic
                echo "I'm " , get_class($this) , "\n";
            } else {
                echo "I'm " , get_class($this) , "\n";
            }
        }
    }

    class child extends dad {
        function child() {
            parent::dad();
        }
    }

    $foo = new dad();
    $bar = new child();
?>

Output:
I'm dad
I'm child

PHP get_parent_class() 文档

于 2013-08-29T23:14:24.923 回答