简体   繁体   English

如何在PHP的非抽象类中声明抽象方法?

[英]How to declare abstract method in non-abstract class in PHP?

class absclass {
    abstract public function fuc();
}

reports:报告:

PHP Fatal error: Class absclass contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (absclass::fuc) PHP 致命错误:类 absclass 包含 1 个抽象方法,因此必须声明为抽象方法或实现其余方法 (absclass::fuc)

I want to know what it means by implement the remaining methods ,how?我想知道实现其余方法意味着什么,如何?

See the chapter on Class Abstraction in the PHP manual :请参阅PHP 手册中关于类抽象的章节:

PHP 5 introduces abstract classes and methods. PHP 5 引入了抽象类和方法。 Classes defined as abstract may not be instantiated, and any class that contains at least one abstract method must also be abstract.定义为抽象的类不能被实例化,任何包含至少一个抽象方法的类也必须是抽象的。 Methods defined as abstract simply declare the method's signature - they cannot define the implementation.定义为抽象的方法只是声明方法的签名——它们不能定义实现。

It means you either have to这意味着你要么必须

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

or或者

class absclass {
    public function fuc() { // implement the method body
        // which means it won't be abstract anymore
    };
}

I presume that remaining methods actually refers to the abstract methods you're trying to define (in this case, fuc() ), since the non-abstract methods that might exist are okay anyway.我认为剩余的方法实际上是指您尝试定义的抽象方法(在本例中为fuc() ),因为无论如何可能存在的非抽象方法都可以。 It's probably an error message that could use a more precise wording: where it says remaining it could have said abstract .这可能是一条错误消息,可以使用更精确的措辞:它说剩余的地方可以说是abstract

The fix is pretty straightforward (that part of the error message is fine): you need to change this:修复非常简单(错误消息的那部分很好):您需要更改它:

abstract public function fuc();

... into a proper implementation: ...进入正确的实现:

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

... or, alternatively and depending your needs, make the whole class abstract: ...或者,或者,根据您的需要,使整个类抽象:

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

An abstract class cannot be directly instantiated, but it can contain both abstract and non-abstract methods.抽象类不能直接实例化,但它可以包含抽象和非抽象方法。

If you extend an abstract class, you have to either implement all its abstract functions, or make the subclass abstract.如果你扩展一个抽象类,你要么实现它的所有抽象函数,要么使子类抽象。

You cannot override a regular method and make it abstract, but you must (eventually) override all abstract methods and make them non-abstract.您不能覆盖常规方法并使其抽象,但您必须(最终)覆盖所有抽象方法并使它们非抽象。

<?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();

?>

That program bombs with:该程序轰炸:

PHP Fatal error: Class BadDog contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Dog::bark) PHP 致命错误:BadDog 类包含 1 个抽象方法,因此必须声明为抽象方法或实现其余方法 (Dog::bark)

If you comment out the BadDog class, then the output is:如果您注释掉 BadDog 类,则输出为:

name: Fred
gender: female
bowowwaoar

If you try to instantiate a Dog or a PassTheBuckDog directly, like this:如果您尝试直接实例化 Dog 或 PassTheBuckDog,如下所示:

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

..it bombs with: ..它轰炸:

PHP Fatal error: Cannot instantiate abstract class Dog PHP 致命错误:无法实例化抽象类 Dog

or (if you comment out the $wrong line)或(如果您注释掉 $wrong 行)

PHP Fatal error: Cannot instantiate abstract class PassTheBuckDog PHP 致命错误:无法实例化抽象类 PassTheBuckDog

You can, however, call a static function of an abstract class:但是,您可以调用抽象类的静态函数:

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();

That works just fine.这工作得很好。

You're being slightly led astray by this error message.您被此错误消息稍微误导了。 In this case, since it is within this class that fuc is being defined, it wouldn't really make sense to implement it in this class.在这种情况下,因为fuc是在这个类中定义的,所以在这个类中实现它实际上没有意义。 What the error is trying to tell you is that a non-abstract class cannot have abstract methods.错误试图告诉您的是,非抽象类不能具有抽象方法。 As soon as you put an abstract method in the definition of a class, you must also mark the class itself as abstract.一旦将抽象方法放入类的定义中,您还必须将类本身标记为抽象。

Abstract keywords are used to label classes or methods as patterns.抽象关键字用于将类或方法标记为模式。 It's similar to interfaces but can contain variables and implementations of methods.它类似于接口,但可以包含变量和方法的实现。

There are a lot of misunderstandings concerning abstract classes.关于抽象类有很多误解。 Here is an example of an abstract Dog class.这是一个抽象 Dog 类的示例。 If a developer wants to create some basic Dog class for other developers or for himself to extend he declares the class as abstract.如果开发人员想为其他开发人员或为自己扩展创建一些基本的 Dog 类,他可以将该类声明为抽象类。 You can't instantiate the Dog class directly (nobody can), but you can extend Dog by your own class.您不能直接实例化 Dog 类(没有人可以),但您可以通过您自己的类来扩展 Dog。 SmartDog extends Dog etc. SmartDog 扩展了 Dog 等。

All methods that are declared to be abstract by the Dog class must be implemented manually in each class that extends Dog. Dog 类声明为抽象的所有方法都必须在扩展 Dog 的每个类中手动实现。

For example, the abstract class Dog has an abstract method Dog::Bark().例如,抽象类 Dog 有一个抽象方法 Dog::Bark()。 But all Dogs bark differently.但所有的狗吠不同。 So in each Dog-subclasses you must describe HOW that dog barks concretely, so you must define eg SmartDog::Bark().所以在每个狗子类中你必须具体描述狗是如何吠叫的,所以你必须定义例如 SmartDog::Bark()。

It means that the proper of an abstract class is having at least one abstract method.这意味着抽象类的特性是至少有一个抽象方法。 So your class has either to implement the method (non abstract), or to be declared abstract.所以你的类要么实现方法(非抽象),要么声明为抽象。

I wanted to use an abstract method within a non-abstract class (normal class?) and found that I could wrap the method's contents in an 'if' statement with get_parent_class() like so:我想在非抽象类(普通类?)中使用抽象方法,发现我可以使用 get_parent_class() 将方法的内容包装在“if”语句中,如下所示:

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

Or, in action (tested in a file on cmd line: php -f "abstract_method_normal_class_test.php"):或者,在行动中(在 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() Documentation PHP get_parent_class() 文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM