¿Cómo llamar a la función principal desde la instancia del niño?

6 minutos de lectura

tengo modelo

BaseUser.class.php
User.class.php
UserTable.class.php

En clase de usuario
He anulado la función de eliminación

class User extends BaseUser {
   function delete(){
    }
}

Ahora, si quiero llamar a la función de eliminación principal… ¿cómo?

Ejemplo

$user = new User();
$user->delete();  // will call the overridden delete
$user-> ??  ;     // want to call parent delete

  • Has probado $user->parent::delete();?

    – Mate

    6 de agosto de 2012 a las 12:52

  • sí, lo probé pero no funcionó… netbeans lo muestra como una semántica incorrecta

    usuario1435539

    6 de agosto de 2012 a las 12:54

  • ¿Qué pasa cuando ejecutas el código en tu navegador?

    – Mate

    6 de agosto de 2012 a las 12:55

  • No lo olvide: su IDE es solo una herramienta útil. No es el fin y el todo del “reconocimiento de código válido”. En otras palabras, a veces da falsos positivos.

    – Mate

    6 de agosto de 2012 a las 12:55


  • Eche un vistazo a la respuesta de @ j0k. Cubre prácticamente todo lo que preguntaste.

    – Mate

    6 de agosto de 2012 a las 13:01

avatar de usuario
hakré

Técnicamente, esto no es posible desde el “exterior” (la interfaz pública) por una buena razón.

Si ha entendido por qué (de lo contrario, lea a continuación) y realmente sabe lo que hace, no hay razón para no ofrecer la funcionalidad:

class User extends BaseUser {
   ... 
   function parentDelete(){
       parent::delete();
   }
   ...
}

user = new User();
$user->delete();  // will call the overridden delete
$user->parentDelete();     // want to call parent delete

Sin embargo, si alguna vez hace eso, debe saber que ha hecho un mal uso de la herencia de alguna manera. Esta debe ser una situación excepcional, ya que no puedo imaginar ninguna situación en la que realmente necesites hacer eso.

Así que trata de formular por qué necesitas esa funcionalidad para darte mejores sugerencias.

¿Por qué es eso malo?

Por una razón muy sencilla: En su software no necesita saber que $user tiene un padre o no. Ese es un detalle que no debería importarte en absoluto.

Eso le permitirá reemplazar cualquier objeto de usuario que tenga en su software con un objeto secundario de usuario más adelante. Esto es importante ya que desea cambiar su software con el tiempo.

Si hace que los detalles internos formen parte de la interfaz pública, se está privando de la posibilidad de mantener las cosas flexibles. No ser flexible es realmente una mala situación.

  • No estoy de acuerdo con la afirmación “mala”. Al igual que las interfaces describen la firma de los métodos de un objeto, y cuando implement esa interfaz, cuando extend un objeto principal, debe debería sabemos muy bien lo que ese padre implementa. Este es el quid de la extensión de objetos. No hay “malo” aquí. EXCEPTO: La idea de que es necesario llamar a dos métodos separados. solo tienes User:delete() llamar parent::delete() como parte de su método. 7 años… ¿Por qué me molesto… jajaja?

    – Miguel

    10 de abril de 2019 a las 0:47

  • Sí, el que se extiende necesita saberlo, pero el “usuario” de ese tipo no debe conocer ningún detalle interno (solo la interfaz pública). Lo más probable es que mi inglés no sea muy preciso, pero lo que comentas va en la dirección de lo que quería decir en esa parte “mala”, quizás debería haber proporcionado el buen ejemplo también, llamando a parent::delete() dentro del extendiendo el método delete () de la clase: err, esa es la respuesta, está allí en la parte superior.

    – hakré

    10 de abril de 2019 a las 18:46


  • Mi propio caso de uso es este: tengo una clase Mail() y ahora quiero una clase DelayedMail() para falso enviando correo, sino que en realidad pone en cola los correos electrónicos en una base de datos. La falsificación se realiza anulando el método send(). La forma más fácil de hacer cola es hibernar la instancia y almacenar su representación. No hay problemas allí! Pero luego, en un trabajo cron, descongelo esos objetos y ahora quiero De Verdad enviarlos, y en ese momento no puedo usar send(), porque eso los volvería a poner en cola. necesito usar el padres enviar (lo llamé “realSend()”). No veo esto como un abuso de la programación orientada a objetos, más bien al contrario.

    – LSerni

    20 oct 2020 a las 10:09

avatar de usuario
vudú417

tal vez intente esto

parent::delete();

  • tengo un objeto de usuario $ usuario ¿cómo llamar a este objeto?

    usuario1435539

    6 de agosto de 2012 a las 12:46

  • debe llamar al método principal en el método secundario

    – vudú417

    6 de agosto de 2012 a las 12:52

  • @HUGO: No puedes. Por fuera ambos son iguales. No hay dos, sino un objeto. Para eso está la herencia.

    – hakré

    6 de agosto de 2012 a las 12:52


avatar de usuario
Fluffeh

Creo que estás buscando el PHP padre funciones:

<?php
class A {
    function example() {
    echo "I am A::example() and provide basic functionality.<br />\n";
    }
}

class B extends A {
    function example() {
    echo "I am B::example() and provide additional functionality.<br />\n";
    parent::example();
    }
}

$b = new B;

// This will call B::example(), which will in turn call A::example().
$b->example();
?>

Si su clase no tiene una función llamada getMyFunction() llamando $b->getMyFuction() llamará a la función padre. Si lo hace, llamará a la función secundaria, a menos que la función secundaria llame a la función prent.

  • Creo que OP necesita saber si $b->parent::example(); trabajará.

    – Mate

    6 de agosto de 2012 a las 12:51


  • @HUGO $b>example() se ejecutará de la siguiente manera: Si no hay example() en la clase secundaria, el padre ejecutará. Si hay una función example() en el niño, se ejecutará en su lugar.

    – Fluffeh

    6 de agosto de 2012 a las 12:54

avatar de usuario
j0k

¿Por qué necesita extender delete si necesita llamar a los padres una vez?

¿Por qué no crear una eliminación personalizada?

Me gusta:

public function customDelete()
{
  parent::delete();

  // do extends delete here
}

Entonces puedes eliminar un objeto usando ->customDelete() y también puede llamar al método de eliminación desde el padre ya que no anuló el delete() método:

$user = new User();
$user->customDelete();  // will call the overridden delete
$user->delete(); // will call the parent (since you didn't override it)

Y si tu De Verdad necesita anular el delete() función, aún puede crear una especie de eliminación principal:

public function parentDelete()
{
  return parent::delete();
}

Después:

$user = new User();
$user->delete();  // will call the overridden delete
$user->parentDelete(); // will call the method that only call the parent

Se puede hacer usando call_user_func. Sí, es una mala práctica, pero es posible.

class BaseUser {
    public function delete()
    {
        echo 'BaseUser deleted';
    }
}

class User extends BaseUser{
    public function delete()
    {
        echo 'User deleted';
    }
}

$instance = new User();

call_user_func(array($instance, 'parent::delete'));

resultado:

BaseUser deleted

avatar de usuario
Mate

encontré este hilo en foros de codificación. Lo que dice (y tiendo a estar de acuerdo con ellos) es que si tiene una función/método anulado en una clase secundaria, una instancia de ese objeto SIEMPRE llamará al método secundario.

los parent palabra clave es similar a $this o self y solo se puede llamar desde dentro de la propia clase.

Si desea que un objeto secundario pueda llamar al método principal, simplemente cree otro método

function parentExample() { 
    parent::example(); 
}

que solo llama al método padre.

¿Ha sido útil esta solución?