Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Ciekawostka - static w abstract calss
markuz
post 28.01.2017, 19:07:02
Post #1





Grupa: Zarejestrowani
Postów: 1 240
Pomógł: 278
Dołączył: 11.03.2008

Ostrzeżenie: (0%)
-----


Ostatnio spotkałem się z ciekawym "bugiem" który podobno nim nie jest. Ciekawy jestem jakie jest Wasze zdanie na ten temat.

Mam kod:

  1. <?php
  2.  
  3. interface A
  4. {
  5. static function create();
  6. }
  7.  
  8. abstract class B implements A
  9. {
  10.  
  11. protected static $instance;
  12.  
  13. protected function __construct()
  14. {
  15. }
  16.  
  17. public static function getInstance()
  18. {
  19. if (static::$instance === null) {
  20. static::$instance = static::create();
  21. }
  22.  
  23. return static::$instance;
  24. }
  25. }
  26.  
  27. class C {
  28.  
  29. private $number;
  30.  
  31. public function __construct($number) {
  32. $this->number = $number;
  33. }
  34.  
  35. public function getNumber() {
  36. return $this->number;
  37. }
  38.  
  39. }
  40.  
  41. class D extends B {
  42.  
  43. static function create() {
  44. return new C(1);
  45. }
  46.  
  47. }
  48.  
  49. class G extends B {
  50.  
  51. static function create() {
  52. return new C(2);
  53. }
  54.  
  55. }
  56.  
  57. echo "a = " . D::getInstance()->getNumber() . PHP_EOL;
  58. echo "b = " . G::getInstance()->getNumber() . PHP_EOL;


Jakie Twoim zdaniem wartości powinno mieć a i b? (fajnie jakbyś nie wykonywał tego kodu przed odpowiedzią)

Następnie do powyższego kodu dodamy 3 nowe klasy:

  1. abstract class F implements A
  2. {
  3.  
  4. protected static $instance;
  5.  
  6. protected function __construct()
  7. {
  8. }
  9.  
  10. public static function getInstance()
  11. {
  12. if (static::$instance === null) {
  13. $t = '';
  14. static::$instance =& $t;
  15. static::$instance = static::create();
  16. }
  17.  
  18. return static::$instance;
  19. }
  20. }
  21.  
  22. class E extends F {
  23.  
  24. static function create() {
  25. return new C(3);
  26. }
  27.  
  28. }
  29.  
  30. class H extends F {
  31.  
  32. static function create() {
  33. return new C(4);
  34. }
  35.  
  36. }
  37.  
  38. echo "c = " . E::getInstance()->getNumber() . PHP_EOL;
  39. echo "d = " . H::getInstance()->getNumber() . PHP_EOL;


Jakie wartości będzie mieć c i d?

Jak wiadomo static użyte w klasie powinno kierować do "ostatniej" w hierarchii klasy. Jednak static w klasach abstrakcyjnych wydaje się być jakimś innym tworem - być może dlatego, że self w takich klasach nie może istnieć. Jeżeli zrobimy jednak zabieg z klasy F w getInstance static znowu jest tym "normalnym" static. Przez normalnym mam na myśli zachowanie które uważam za prawidłowe - obiekt klasy abstrakcyjnej nie może istnieć dlaczego więc static klasy abstrakcyjniej może?

Tym sposobem możemy też sprawić aby static nie był static w zwykłych klasach:

  1. <?php
  2.  
  3. class B {
  4.  
  5. static $number;
  6.  
  7. }
  8.  
  9. class C extends B {
  10.  
  11. }
  12.  
  13. class G extends B {
  14.  
  15. }
  16.  
  17. B::$number = 5;
  18. echo C::$number . PHP_EOL;
  19. echo G::$number . PHP_EOL;
  20. C::$number = 2;
  21. echo C::$number . PHP_EOL;
  22. echo G::$number . PHP_EOL;
  23. $t = 11;
  24. C::$number =& $t;
  25. echo C::$number . PHP_EOL;
  26. echo G::$number . PHP_EOL;


Ten post edytował markuz 28.01.2017, 19:44:49


--------------------
Go to the top of the page
+Quote Post
adbacz
post 6.02.2017, 14:38:31
Post #2





Grupa: Zarejestrowani
Postów: 532
Pomógł: 24
Dołączył: 15.04.2011
Skąd: Kalisz

Ostrzeżenie: (0%)
-----


Static odnosi się do klasy jako kontenera, a nie do obiektu tej klasy. Klasa abstrakcyjna daje możliwość utworzenia "tak jakby" interfejsu, już z predefiniowanymi metodami, które klasa dziedzicząca wspóldzieli. Odwołania statyczne do klasy mają się nijak do tworzenia obiektów. Dlatego static::$zmienna działa dla klasy abstrakcyjnej. A to, do której ona klasy należy, to już zależy od dziedziczenia. Powinno się używać static od klasy w której jest to zdefiniowane.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 19.03.2024 - 03:02