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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2371490/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 06:13:39  来源:igfitidea点击:

How to declare abstract method in non-abstract class in PHP?

phpabstract-function

提问by user198729

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?

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

采纳答案by álvaro González

I presume that remaining methodsactually 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. It's probably an error message that could use a better wording: where it says remainingit should say abstract.

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

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

回答by Gordon

See the chapter on Class Abstraction in the PHP manual:

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

PHP 5 introduces abstract classes and methods. 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.

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

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
    };
}

回答by Shavais

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.

这工作得很好。

回答by Alex Yaroshevich

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. If a developer wants to create some basic Dog class for other developers or for himself to extend he declares the class as abstract. You can't instantiate the Dog class directly (nobody can), but you can extend Dog by your own class. SmartDog extends Dog etc.

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

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

回答by AakashM

You're being slightly led astray by this error message. In this case, since it is within this classthat fucis being defined, it wouldn't really make sense to implement it in this class. 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.

您被此错误消息稍微误导了。在这种情况下,因为它是在这个类fuc定义的,所以在这个类中实现它实际上没有意义。错误试图告诉您的是,非抽象类不能具有抽象方法。一旦将抽象方法放入类的定义中,您还必须将类本身标记为抽象。

回答by instanceof me

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.

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

回答by Brent Self

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() 文档