2010-05-18 19 views
27

He configurado una clase principal abstracta, y una clase concreta que la amplía. ¿Por qué la clase padre no llama a la función abstracta?¿Por qué no puedes llamar funciones abstractas de clases abstractas en PHP?

//foo.php 
<?php 
    abstract class AbstractFoo{ 
     abstract public static function foo(); 
     public static function getFoo(){ 
      return self::foo();//line 5 
     } 
    } 

    class ConcreteFoo extends AbstractFoo{ 
     public static function foo(){ 
      return "bar"; 
     } 
    } 

    echo ConcreteFoo::getFoo(); 
?> 

error:

Fatal error: Cannot call abstract method AbstractFoo::foo() in foo.php on line 5

+3

LOL ... static abstract ...: D: pregunta cool – Simon

Respuesta

48

Esta es una implementación correcta; se debe utilizar estática, no auto, con el fin de utilizar late static bindings:

abstract class AbstractFoo{ 
    public static function foo() { 
     throw new RuntimeException("Unimplemented"); 
    } 
    public static function getFoo(){ 
     return static::foo(); 
    } 
} 

class ConcreteFoo extends AbstractFoo{ 
    public static function foo(){ 
     return "bar"; 
    } 
} 

echo ConcreteFoo::getFoo(); 

da la "barra" esperado.

Tenga en cuenta que esto no es realmente polimorfismo. La clave estática simplemente se resuelve en la clase a partir de la cual se llamó el método estático. Si declara un método estático abstracto, recibirá una advertencia estricta. PHP simplemente copia todos los métodos estáticos de la clase principal (super) si no existen en la clase secundaria (secundaria).

+2

Sick ... ¡Gracias! ¿Cuál es la diferencia entre uno mismo y la estática? Editar: aparentemente esa palabra clave no existe (podría ser una cosa de la versión). – Cam

+2

Lea la página del manual sobre enlaces estáticos finales que he vinculado. – Artefacto

+1

Sí, esto solo está disponible en PHP 5.3. – Artefacto

7

Se nota que la palabra self?

Esto apunta a AbstractClass. Por lo tanto, está llamando a AbstractClass :: foo(), no a ConcreteClass :: foo();

creo PHP 5.3 proporcionará fijaciones finales estáticas, pero si usted no está en esa versión, uno mismo no se referirá a una clase extendida, pero la clase que la función se encuentra en

Ver:. http://us.php.net/manual/en/function.get-called-class.php

+0

La palabra clave en lugar de 'self' para usar es' static' para hacer referencia a 'ConcreteClass' en 5.3+ – philfreo

0

Es una regla que las palabras clave abstract y static no se pueden usar en un método al mismo tiempo.

Un método con una palabra clave abstract significa que la subclase debe implementarlo. Agregar static a un método de una clase nos permite usar el método sin instanciarlo.

Por eso es que ocurre el error.

+0

¡¡no es una respuesta clara !! – Deepak

+0

Y, sin embargo, pueden ser utilizados. Un ejemplo sería el uso de setUpBeforeClass() estático de PHPUnit con valores que dependen de las subclases; necesitaría un resumen (para que las subclases lo implementen en primer lugar y también de manera diferente) estático (para que pueda llamarlo desde el método setUpBeforeClass()). – Buffalo

Cuestiones relacionadas