【发布时间】:2011-01-23 05:03:27
【问题描述】:
class absclass {
abstract public function fuc();
}
报告:
PHP 致命错误:类 absclass 包含 1 个抽象方法并且必须 因此被宣布为抽象的或 实现剩下的方法 (absclass::fuc)
我想知道实现剩下的方法是什么意思,怎么做?
【问题讨论】:
标签: php abstract-function
class absclass {
abstract public function fuc();
}
报告:
PHP 致命错误:类 absclass 包含 1 个抽象方法并且必须 因此被宣布为抽象的或 实现剩下的方法 (absclass::fuc)
我想知道实现剩下的方法是什么意思,怎么做?
【问题讨论】:
标签: php abstract-function
这意味着抽象类的属性至少有一个抽象方法。所以你的类要么实现方法(非抽象),要么被声明为抽象。
【讨论】:
此错误消息使您误入歧途。在这种情况下,由于在 this class 中定义了 fuc,因此在此类中实现它实际上没有意义。错误试图告诉您的是非抽象类不能有抽象方法。一旦您将抽象方法放入类的定义中,您还必须将类本身标记为抽象。
【讨论】:
我认为 remaining methods 实际上是指您尝试定义的抽象方法(在本例中为fuc()),因为无论如何可能存在的非抽象方法都可以。这可能是一条错误消息,可以使用更精确的措辞:它说 remaining 的地方可能是 abstract。
修复非常简单(错误消息的那部分很好):您需要更改:
abstract public function fuc();
...进入正确的实现:
public function fuc(){
// Code comes here
}
...或者,或者,根据您的需要,将整个类抽象化:
abstract class absclass {
abstract public function fuc();
}
【讨论】:
见Class Abstraction in the PHP manual的章节:
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
};
}
【讨论】:
抽象类不能直接实例化,但它可以包含抽象方法和非抽象方法。
如果你扩展一个抽象类,你必须要么实现它的所有抽象函数,要么让子类抽象。
您不能覆盖常规方法并使其抽象,但您必须(最终)覆盖所有抽象方法并使其非抽象。
<?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 个抽象方法并且必须 因此被宣布为抽象的或 实现剩下的方法 (狗::吠声)
如果注释掉 BadDog 类,则输出为:
name: Fred
gender: female
bowowwaoar
如果您尝试直接实例化 Dog 或 PassTheBuckDog,如下所示:
$wrong = new Dog('somma','it');
$bad = new PassTheBuckDog('phamous','monster');
..it 炸弹:
PHP 致命错误:无法实例化 抽象类狗
或(如果您注释掉 $ 错误的行)
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();
效果很好。
【讨论】:
public public function bark() ?
抽象关键字用于将类或方法标记为模式。它类似于接口,但可以包含变量和方法的实现。
关于抽象类有很多误解。这是一个抽象 Dog 类的示例。如果开发人员想为其他开发人员或自己创建一些基本的 Dog 类来扩展,他将类声明为抽象类。您不能直接实例化 Dog 类(没有人可以),但您可以通过自己的类扩展 Dog。 SmartDog 扩展了 Dog 等。
所有被 Dog 类声明为抽象的方法必须在每个扩展 Dog 的类中手动实现。
例如,抽象类 Dog 有一个抽象方法 Dog::Bark()。但是所有的狗叫声都不一样。因此,在每个 Dog 子类中,您必须具体描述狗如何吠叫,因此您必须定义例如 SmartDog::Bark()。
【讨论】:
我想在非抽象类(普通类?)中使用抽象方法,发现可以使用 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
【讨论】: