Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Odczytanie prywatnej składowej w klasie pochodnej
Forum PHP.pl > Forum > PHP > Object-oriented programming
amii
Mam taki fragment kodu pochodzący z tutoriala na tej stronie -> http://www.phpfreaks.com/tutorial/design-p...tegy-and-bridge
Klasy SubscriptionMail i NotifiactionMail dziedziczą po abstrakcyjnej klasie Mail, która ma prywatną składową $_transport dlaczego te klasy wywołują prywatną składową rodzica w metodach send ?


  1. /**
  2.  * Interface for mailer implementations
  3.  *
  4.  */
  5. interface MailTransport
  6. {
  7. /**
  8.   * Send email
  9.   *
  10.   */
  11. public function send($from, $to, $body);
  12. }
  13.  
  14. class SendMailTransport implements MailTransport
  15. {
  16. public function send($from, $to, $body)
  17. {
  18. //send email using sendmail
  19. }
  20. }
  21. class SmtpTransport implements MailTransport
  22. {
  23. public function send($from, $to, $body)
  24. {
  25. //send email using SMTP
  26. }
  27. }
  28.  
  29. /**
  30.  * Objects representing an email
  31.  *
  32.  */
  33. abstract class Mail
  34. {
  35. /**
  36.   * Mail transport implementation
  37.   *
  38.   * @var MailerTransport
  39.   */
  40. private $_transport;
  41.  
  42. /**
  43.   * Email body
  44.   *
  45.   * @var string
  46.   */
  47. private $_body;
  48.  
  49. /**
  50.   * Recipient
  51.   *
  52.   * @var string
  53.   */
  54. private $_to;
  55.  
  56. /**
  57.   * Constructor
  58.   *
  59.   * @param MailerTransport $imp
  60.   */
  61. public function __construct(MailerTransport $imp)
  62. {
  63. $this->_transport = $imp;
  64. }
  65.  
  66. /**
  67.   * Get the email body
  68.   *
  69.   * @param string $string
  70.   */
  71. public function getBody()
  72. {
  73. return $this->_body;
  74. }
  75.  
  76. /**
  77.   * Set the email body
  78.   *
  79.   * @param string $string
  80.   */
  81. public function setBody($string)
  82. {
  83. $this->_body = $string;
  84. }
  85.  
  86. /**
  87.   * Set the email recipient
  88.   *
  89.   * @param string $address
  90.   */
  91. public function getTo()
  92. {
  93. return $this->_to;
  94. }
  95.  
  96. /**
  97.   * Set the email recipient
  98.   *
  99.   * @param string $address
  100.   */
  101. public function setTo($address)
  102. {
  103. $this->_to = $address;
  104. }
  105.  
  106. /**
  107.   * Get the sender address
  108.   *
  109.   * @return string
  110.   */
  111. public function getFrom()
  112. {
  113. return $this->_from;
  114. }
  115.  
  116. /**
  117.   * Set the sender address
  118.   *
  119.   * @param string $address
  120.   */
  121. public function setFrom($address)
  122. {
  123. return $this->_from;
  124. }
  125.  
  126. }
  127. class NotificationMail extends Mail
  128. {
  129. /**
  130.   * Check if the value is valid
  131.   *
  132.   * @param mixed $mixed
  133.   * @return bool
  134.   */
  135. public function send()
  136. {
  137. if(!$this->_transport->send($this->getFrom(), $this->getTo(), $this->getBody())) //wywołanie prywatnej składowej _transport z klasy rodzica Mail ?
  138.  
  139. {
  140. //a failed notice is not that much of isssue
  141. trigger_error('Failed to send notice', E_USER_NOTICE);
  142. }
  143. }
  144.  
  145. /**
  146.   * Format the body as a notice
  147.   *
  148.   * @return string
  149.   */
  150. public function getBody()
  151. {
  152. return "Notice: " . parent::getBody();
  153. }
  154.  
  155. }
  156. class SubscriptionMail extends Mail
  157. {
  158. /**
  159.   * Check if the value is valid
  160.   *
  161.   * @param mixed $mixed
  162.   * @return bool
  163.   */
  164. public function send()
  165. {
  166. if(!$this->_transport->send($this->getFrom(), $this->getTo(), $this->getBody())) //wywołanie prywatnej składowej _transport z klasy rodzica Mail ?
  167. {
  168. //if it fails, we should handle that
  169. throw new Exception('Failed to send subscription email');
  170. }
  171. }
  172. }
  173.  
  174. $mail = new SubscriptionMail(new SmtpTransport());
kaem
Hmm nie jestem pewien więc proszę o zweryfikowanie, ale wydaje mi się, że działa to tak:
tutaj
  1. $mail = new SubscriptionMail(new SmtpTransport());

wywoływany jest konstruktor zdefiniowany w klasie abstrakcyjnej, który w ten sposób: $this->_transport = $imp; przypisuje do właściwości $_transport obiekt typu MailerTransport, ale ponieważ klasa NotificationMail nie ma tej właściwości, to jest tworzona 'w locie'.
rocktech.pl
Witam.

Trochę przerobiony przykład do zabawy.

  1. <?php
  2. header("Content-Type: text/plain");
  3. /**
  4.  * Define MyClass
  5.  */
  6. class MyClass
  7. {
  8. public $public = 'Public';
  9. protected $protected = 'Protected';
  10. private $private = 'Private';
  11. }
  12. /**
  13.  * Define MyClass2
  14.  */
  15. class MyClass2 extends MyClass
  16. {
  17. // We can redeclare the public and protected method, but not private
  18. protected $protected = 'Protected2';
  19. }
  20.  
  21. $obj2 = new MyClass2();
  22. var_dump($obj2->private);
  23. echo PHP_EOL;
  24. //zobacz tu
  25. print_r($obj2);
  26. ?>
amii
Nie kapuje teraz jak wywołam metodę show() wyświetla, że nie odnajduje zmiennej private i nie wyświetla nic, po var_dump dostaje NULL, print_r wyświetla zmienną prywatną. Więc jakim cudem kod z poprzedniego posta operuje na zmiennej prywatnej skoro tutaj jest NULL?

  1. header("Content-Type: text/plain");
  2. /**
  3.  * Define MyClass
  4.  */
  5. class MyClass
  6. {
  7. public $public = 'Public';
  8. protected $protected = 'Protected';
  9. private $private = 'Private';
  10. }
  11. /**
  12.  * Define MyClass2
  13.  */
  14. class MyClass2 extends MyClass
  15. {
  16. // We can redeclare the public and protected method, but not private
  17. protected $protected = 'Protected2';
  18. //private $private = 'Private22';
  19.  
  20. public function show()
  21. {
  22. echo 'Zmienna prywatna wewnatrz klasy ' . __CLASS__ . ' wynosi: '. $this->private;
  23. }
  24. }
  25.  
  26. $obj2 = new MyClass2();
  27. var_dump($obj2->private);
  28. echo PHP_EOL;
  29. //zobacz tu
  30. print_r($obj2);
  31. $obj2->show();
erix
Zwróć uwagę na słowo-klucz abstract.

Klasa Mail sama w sobie nie może istnieć i pole jest prywatne dla pierwszej w hierarchii klasą ją rozszerzającą, z tego co pamiętam.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.