Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> Inheritance vs. interface dla takich samych metod., Klasy dziedziczące mają te same metody. Powinny dziedziczyć?
trzczy
post 12.12.2015, 13:32:56
Post #1





Grupa: Zarejestrowani
Postów: 460
Pomógł: 49
Dołączył: 5.06.2011

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


Kiedy klasy dziedziczące mają takie same metody, to lepiej by dziedziczyły te metody od klasy nadrzędnej, czy miały te metody "przykazane" przez interface i umieszczone w sobie? Takie 2 rozwiązania pokazuję poniżej. Które jest bardziej poprawne?
  1. //example 1
  2. interface Person {
  3. function getName();
  4. function setName($name);
  5. function getHobby();
  6. function setHobby($hobby);
  7. }
  8. class Person2 implements Person{
  9. private $name;
  10. private $hobby;
  11. public function getName()
  12. {
  13. return $this->name;
  14. }
  15. public function setName($name)
  16. {
  17. $this->name = $name;
  18. }
  19. public function getHobby()
  20. {
  21. return $this->hobby;
  22. }
  23. public function setHobby($hobby)
  24. {
  25. $this->hobby = $hobby;
  26. }
  27. }
  28. class Person3 implements Person{
  29. private $name;
  30. private $hobby;
  31. public function getName()
  32. {
  33. return $this->name;
  34. }
  35. public function setName($name)
  36. {
  37. $this->name = $name;
  38. }
  39. public function getHobby()
  40. {
  41. return $this->hobby;
  42. }
  43. public function setHobby($hobby)
  44. {
  45. $this->hobby = $hobby;
  46. }
  47. }
  48. //example 1 end
  49.  
  50. //example 2
  51. abstract class Human{
  52. protected $name;
  53. protected $hobby;
  54. public function getName()
  55. {
  56. return $this->name;
  57. }
  58. public function setName($name)
  59. {
  60. $this->name = $name;
  61. }
  62. public function getHobby()
  63. {
  64. return $this->hobby;
  65. }
  66. public function setHobby($hobby)
  67. {
  68. $this->hobby = $hobby;
  69. }
  70. }
  71. class Human1 extends Human{
  72. protected $name;
  73. protected $hobby;
  74. }
  75. class Human2 extends Human{
  76. protected $name;
  77. protected $hobby;
  78. }
  79. //example 2 end
  80.  
  81. //TESTING
  82. $Mark = new Person2();
  83. $Mark->setName('Mark');
  84. echo "{$Mark->getName()}<br>"; //Mark
  85. $Mark = new Human2();
  86. $Mark->setName('Mark');
  87. echo "{$Mark->getName()}<br>"; //Mark
  88.  


Z góry dziękuję
Go to the top of the page
+Quote Post
droslaw
post 12.12.2015, 14:43:14
Post #2





Grupa: Zarejestrowani
Postów: 98
Pomógł: 33
Dołączył: 10.05.2011
Skąd: Krak

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


W przykładzie, który podałeś klasy są identyczne dlatego nie ma sensu ich rozbijać na dwie. Jeśli część metod byłaby wspólna (dokładnie takie same metody łącznie z implementacją), wtedy te metody mogłyby być w klasie nadrzędnej, a w klasach pochodnych umieściłbyś różnice.

W twoim przypadku powinna to być jedna klasa. Czy interfejs byłby tam przydatny to zależy. Można by napisać więcej gdybyśmy znali szerszy kontekst, jaką aplikację piszesz i jak obiekty tej klasy są używane.
Go to the top of the page
+Quote Post
trzczy
post 12.12.2015, 15:32:26
Post #3





Grupa: Zarejestrowani
Postów: 460
Pomógł: 49
Dołączył: 5.06.2011

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


Cytat(droslaw @ 12.12.2015, 14:43:14 ) *
W przykładzie, który podałeś klasy są identyczne dlatego nie ma sensu ich rozbijać na dwie.

No rzeczywiście.

Kontekst mojego pytania jest taki, że czytam sobie tutorial o design patterns i tam napotkałem na takie "zażądanie" metod w klasie abstrakcyjnej, po czym w klasach dziedziczących zastosowane identyczne metody.

Pomyślałem, że te identyczne metody mogłyby być jedynie dziedziczone z klasy abstrakcyjnej, a nie deklarowane w każdej klasie konkretnej. (Tu w przykładzie zastosowałem interface, a nie klasę abstrakcyjną, co w sumie byłoby chyba analogią). Link do tutoriala: https://wwphp-fb.github.io/faq/object-orien...stract-factory/

Definicja klasy abstrakcyjnej wygląda tak:
  1. abstract class AbstractBook {
  2. abstract function getAuthor();
  3. abstract function getTitle();
  4. }


Cały kod tak:
  1. <?php
  2.  
  3. /*
  4.  * BookFactory classes
  5.  */
  6. abstract class AbstractBookFactory {
  7. abstract function makePHPBook();
  8. abstract function makeMySQLBook();
  9. }
  10.  
  11. class OReillyBookFactory extends AbstractBookFactory {
  12. private $context = "OReilly";
  13. function makePHPBook() {
  14. return new OReillyPHPBook;
  15. }
  16. function makeMySQLBook() {
  17. return new OReillyMySQLBook;
  18. }
  19. }
  20.  
  21. class SamsBookFactory extends AbstractBookFactory {
  22. private $context = "Sams";
  23. function makePHPBook() {
  24. return new SamsPHPBook;
  25. }
  26. function makeMySQLBook() {
  27. return new SamsMySQLBook;
  28. }
  29. }
  30.  
  31. /*
  32.  * Book classes
  33.  */
  34. abstract class AbstractBook {
  35. abstract function getAuthor();
  36. abstract function getTitle();
  37. }
  38.  
  39. abstract class AbstractMySQLBook extends AbstractBook {
  40. private $subject = "MySQL";
  41. }
  42.  
  43. class OReillyMySQLBook extends AbstractMySQLBook {
  44. private $author;
  45. private $title;
  46. function __construct() {
  47. $this->author = 'George Reese, Randy Jay Yarger, and Tim King';
  48. $this->title = 'Managing and Using MySQL';
  49. }
  50. function getAuthor() {
  51. return $this->author;
  52. }
  53. function getTitle() {
  54. return $this->title;
  55. }
  56. }
  57.  
  58. class SamsMySQLBook extends AbstractMySQLBook {
  59. private $author;
  60. private $title;
  61. function __construct() {
  62. $this->author = 'Paul Dubois';
  63. $this->title = 'MySQL, 3rd Edition';
  64. }
  65. function getAuthor() {
  66. return $this->author;
  67. }
  68. function getTitle() {
  69. return $this->title;
  70. }
  71. }
  72.  
  73. abstract class AbstractPHPBook extends AbstractBook {
  74. private $subject = "PHP";
  75. }
  76.  
  77. class OReillyPHPBook extends AbstractPHPBook {
  78. private $author;
  79. private $title;
  80. private static $oddOrEven = 'odd';
  81. function __construct()
  82. {
  83. //alternate between 2 books
  84. if ('odd' == self::$oddOrEven) {
  85. $this->author = 'Rasmus Lerdorf and Kevin Tatroe';
  86. $this->title = 'Programming PHP';
  87. self::$oddOrEven = 'even';
  88. }
  89. else {
  90. $this->author = 'David Sklar and Adam Trachtenberg';
  91. $this->title = 'PHP Cookbook';
  92. self::$oddOrEven = 'odd';
  93. }
  94. }
  95. function getAuthor() {
  96. return $this->author;
  97. }
  98. function getTitle() {
  99. return $this->title;
  100. }
  101. }
  102.  
  103. class SamsPHPBook extends AbstractPHPBook {
  104. private $author;
  105. private $title;
  106. function __construct() {
  107. //alternate randomly between 2 books
  108. mt_srand((double)microtime() * 10000000);
  109. $rand_num = mt_rand(0, 1);
  110.  
  111. if (1 > $rand_num) {
  112. $this->author = 'George Schlossnagle';
  113. $this->title = 'Advanced PHP Programming';
  114. }
  115. else {
  116. $this->author = 'Christian Wenz';
  117. $this->title = 'PHP Phrasebook';
  118. }
  119. }
  120. function getAuthor() {
  121. return $this->author;
  122. }
  123. function getTitle() {
  124. return $this->title;
  125. }
  126. }


Ten post edytował trzczy 12.12.2015, 15:33:46
Go to the top of the page
+Quote Post
Fred1485
post 12.12.2015, 15:41:38
Post #4





Grupa: Zarejestrowani
Postów: 361
Pomógł: 22
Dołączył: 10.02.2015

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


Tak moimi słowami, klasę abstrakcyjną czy interfejs piszę często po to, aby mieć pewność, że dany obiekt posiada implementację danej metody.
Przykładowo masz np. klasę abstrakcyjną Storage obsługującą zapisywanie danych, po której dziedziczą np. klasy Database, Session, File itp. Każda z nich musi mieć metodę odczytującą i zapisującą. Więc w klasie nadrzędnej Storage umieszczam dwie metody write i read. Potem gdy, inna klasa będzie musiała przyjąć obiekt danych, to w metodzie rzutuję
  1. function przyjmij(Storage $storage) {//}
I mam pewność że będę mógł odczytać i zapisać dane. Przykład taki z rękawa, może wiesz co mam na myśli.

Ten post edytował Fred1485 12.12.2015, 15:42:37


--------------------
  1. echo 'I was trying';
  2. die ();
Go to the top of the page
+Quote Post
Comandeer
post 12.12.2015, 19:00:55
Post #5





Grupa: Zarejestrowani
Postów: 1 268
Pomógł: 254
Dołączył: 11.06.2009
Skąd: Świętochłowice

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


Osobiście spotkałem się z podejściem, gdzie interfejsy służyły do zdefiniowania publicznego API konkretnej klasy obiektów (np Storage), natomiast klasa abstrakcyjna była podstawową implementacją tego interfejsu, zawężając jego zakres do podklasy tych obiektów (np DBStorage). Po tej klasie dziedziczyły już konkretne klasy, zmieniając jedynie to, co trzeba (np MySQLStorage).


--------------------
Go to the top of the page
+Quote Post
trzczy
post 12.12.2015, 22:37:35
Post #6





Grupa: Zarejestrowani
Postów: 460
Pomógł: 49
Dołączył: 5.06.2011

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


Dzięki za odpowiedzi. Dla mnie wynika z tego, że nie ma "lepszego" sposobu, i wybór należy do programisty. Albo pokazuje on w klasie nadrzędnej lub interfejsie, jakie metody będą wymagane w kasach dziedziczących względnie implementujących interfejs, albo kieruje się rozsądkiem i stosuje dziedziczenie identycznych metod zamiast je powielać.
Oczywiście metoda 1. ma też swoje zalety, bo kod jest wtedy czytelniejszy.
Go to the top of the page
+Quote Post
Damonsson
post 13.12.2015, 00:36:28
Post #7





Grupa: Zarejestrowani
Postów: 2 355
Pomógł: 533
Dołączył: 15.01.2010
Skąd: Bydgoszcz

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


To nie jest kwestia żadnego wyboru. Do czego innego służy interfejs, a do czego innego klasa abstrakcyjna. I nie masz tu żadnego wyboru, czy jeszcze lepiej "lepszego rozwiązania".

W interfejsach umieszczasz informację o tym jakie metody muszą być zawarte w klasie, która go implementuje i tyle, mogą to być zupełnie nie powiązane ze sobą klasy, które implementują ten sam interfejs. Na dodatek interfejs nie może zawierać żadnej funkcjonalności.

Klasa abstrakcyjna, może mieć jakąś funkcjonalność w sobie, a resztę zostawia klasom dziedziczącym po niej. Na dodatek każda klasa dziedzicząca, musi mieć z nią dość ścisły związek.

Podsumowując implementacja i dziedziczenie są od siebie niezależne i nic nie stoi na przeszkodzie, implementować interfejs i dziedziczyć po danej klasie jednocześnie. Czy też tylko implementować interfejs, czy też tylko dziedziczyć po klasie abstrakcyjnej.

Twój abstrakcyjny przykład jest bez sensu i nie rozumiesz idei obiektowości. Przykład z tutoriala jest sensowny, mógłbyś sobie do niego jeszcze napisać interfejsy i byłoby też dobrze, niektórzy powiedzą, że nawet lepiej.
Go to the top of the page
+Quote Post
trzczy
post 13.12.2015, 01:07:19
Post #8





Grupa: Zarejestrowani
Postów: 460
Pomógł: 49
Dołączył: 5.06.2011

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


Damonsson, nie rozumiesz pytania. Chodzi o dublowanie metod. W tutorialu metody są dublowane, a można tego tego uniknąć przez dziedziczenie tych metod z klasy nadrzędnej. Nie chodzi mi o róznice między abstract class a interface, bo jest mi dobrze znana. Z dyskusji powyżej wynika, że programista sam decyduje, czy lepiej będzie uzyskać czytelność kodu przez zastosowanie abstract class lub interface, czy zastosować dziedziczenie metod i uniknąć dublowania.
Go to the top of the page
+Quote Post
viking
post 13.12.2015, 10:42:44
Post #9





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

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


Ale Damansson dobrze Ci odpowiedział i według mnie nie zrozumialeś do końca jego wypowiedzi. Nijak się ma dublowanie metod bo w interface jest tylko ich czysta definicja. Klasa abstrakcyjna może zawierać część funkcjonalności wspólną dla wszystkich klas potomnych ale to do klas poszczególnych zależy jak te specyficzne metody (abstrakcyjne) obsłużą. Masz jeszcze cechy (traits) o których tu nic nie mówisz a które możesz dołączyć do kodu również eliminując powielanie.

Zobacz też interface w takim kontekście: https://github.com/RalfEggert/zend-expressi...eateFactory.php


--------------------
Go to the top of the page
+Quote Post
trzczy
post 13.12.2015, 18:42:16
Post #10





Grupa: Zarejestrowani
Postów: 460
Pomógł: 49
Dołączył: 5.06.2011

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


Cytat(viking @ 13.12.2015, 10:42:44 ) *
Ale Damansson dobrze Ci odpowiedział i według mnie nie zrozumialeś do końca jego wypowiedzi.
Nie odpowiedział na moje pytanie. Jego wypowiedź zrozumiałem, aleta wypowiedź nie uczyniła mnie bogatszym w wiedzę, ani nie odpowiedziała na problem.

Cytat(viking @ 13.12.2015, 10:42:44 ) *
Nijak się ma dublowanie metod bo w interface jest tylko ich czysta definicja.

W interface nie ma definicji metod. Są nazwy metod.

Cytat(viking @ 13.12.2015, 10:42:44 ) *
Klasa abstrakcyjna może zawierać część funkcjonalności wspólną dla wszystkich klas potomnych ale to do klas poszczególnych zależy jak te specyficzne metody (abstrakcyjne) obsłużą.
Nie pytam o to, co to jest klasa abstrakcyjna, bo wiem jak ona działa.

Słuchajcie, ja nie pytam, co mogę jeszcze zrobić, jak ten tutorial pozmieniać itp. Powtarzam pytanie. Czy powielanie definicji metod w klasach podrzędnych, we wskazanym tutorialu, można uznać za wadę tego kodu, w świetle tego, że można takie identyczne definicje metod dziedziczyć z klasy nadrzędnej.

Po prostu, wydaje mi się, że w informatyce jednak nie powinno się powielać tego samego kodu.
Go to the top of the page
+Quote Post
Comandeer
post 13.12.2015, 18:53:29
Post #11





Grupa: Zarejestrowani
Postów: 1 268
Pomógł: 254
Dołączył: 11.06.2009
Skąd: Świętochłowice

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


Cytat
W interface nie ma definicji metod. Są nazwy metod.

Czyli są definicje… To, co jest w klasie abstrakcyjnej (oczywiście jeśli metody mają ciało), to już implementacja, nie definicja.

Co do kodu w tutorialu: osobiście zamieniłbym tę klasę abstrakcyjną na interfejs, jeśli i tak nie podaję podstawowej implementacji tych metod.


--------------------
Go to the top of the page
+Quote Post
Pyton_000
post 13.12.2015, 19:08:52
Post #12





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


O jakim dublowaniu mówisz. Bo tutaj jedynie dublowanie gettery.

Jeśli jednak pisząc ogólnie to:

klasa nadrzędna zawsze powinna zawierać zestaw metod wspólnych.
Czy to będzie klasa abstract czy zwyczajna to już zależy od preferencji.
Czy paretn ma być implements Intreface to też zależy.

Inny przypadek to jak ktoś wcześniej napisał Interface jako definicja metod (Przytoczony przykład z Storage).
Go to the top of the page
+Quote Post
droslaw
post 13.12.2015, 22:18:07
Post #13





Grupa: Zarejestrowani
Postów: 98
Pomógł: 33
Dołączył: 10.05.2011
Skąd: Krak

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


trzczy, Damansson ma rację, w tutorialu żadne metody nie są dublowane. Wydaje się, że rzeczywiście nie zrozumiałeś jeszcze dobrze programowanie obiektowego.

AbstractFactory jest interfejsem czyli nie posiada implementacji. Zawiera tylko deklarację metod (deklarację nie definicję bo definicja to implementacja metody).
Każda klasa implementująca interfejs AbstractFactory definiuje metody zadeklarowane w tym interfejsie, ale nie jest to duplikacja. Dzięki temu masz dwie różne implementacje tego samego interfejsu. To znaczy możesz używać obiektu dowolnej z klas pochodnych w dokładnie ten sam sposób, chociaż każda klasa będzie zachowywać się trochę inaczej (czyli korzystasz z polimorfizmu).

Zaleta tego jest taka, że kod który używa obiektu dowolnej z klas implementujących ten interfejs nie musi brać pod uwagę, z jaką klasą konkretnie ma do czynienia. Kod przez to będzie prostszy w zrozumieniu, rozbudowie i testowaniu.

Ktoś u góry podawał już przykład z klasą Storage. Powiedzmy że tworzysz aplikację, która zapisuje jakieś wiadomości do plików lub bazy.

Kod nie był testowany i może zawierać błędy.
  1. <?php
  2.  
  3. interface StorageInterface
  4. {
  5. public function save($message);
  6. }
  7.  
  8. class FileStorage implements StorageInterface
  9. {
  10. private $dirPath;
  11.  
  12. public function __construct($dirPath)
  13. {
  14. $this->dirPath = $dirPath; // ustawiasz katalog(folder) w jakim zapisywać pliki
  15. }
  16. public function save($message)
  17. {
  18. // tu masz kod zapisujący do pliku
  19. }
  20. }
  21.  
  22. class DbStorage implements StorageInterface
  23. {
  24. public function __construct($dbName, $userName, $passwd, $host)
  25. {
  26. // tu łączymy się z bazą
  27. $this->conn = connect_some_db($dbName, $userName, $passwd, $host);
  28. }
  29.  
  30. public function save($message)
  31. {
  32. // tu zapisujemy do bazy
  33. }
  34. }
  35.  
  36. abstract class AbstractRequestHandler
  37. {
  38. protected $storage;
  39.  
  40. public function __construct(StorageInterface storage)
  41. {
  42. $this->storage = storage;
  43. }
  44.  
  45. abstract public function handleRequest(Request $request);
  46. }
  47.  
  48. class ARequestHandler extends AbstractRequestHandler
  49. {
  50. public function handleRequest(Request $request)
  51. {
  52. // tu pobieramy dane z requesta, generujemy wiadomość
  53. // i zapisujemy
  54. $this->storage->save($message);
  55. }
  56. }
  57.  
  58. class BRequestHandler extends AbstractRequestHandler
  59. {
  60. public function handleRequest(Request $request)
  61. {
  62. // tu pobieramy dane z requesta
  63. // generujemy wiadomość w zupełnie inny sposób niż w klasie ARequestHandler
  64. // i zapisujemy
  65. $this->storage->save($message);
  66. }
  67. }
  68.  


  1. <?php
  2.  
  3. // ... tu mamy trochę kodu, tworzymy obiekt Request itp.
  4. $storage = FileStorage('messages/');
  5. $requestHandler = ARequestHandler($storage);
  6. $requestHandler->handleRequest($request);
  7.  


Ten przykład pokazuje, jak łatwo można zmieniać sposób zapisu wiadomości w aplikacji. Wystarczy zmienić jedną linijkę (stworzyć obiekt klasy DbStorage zamiast FileStorage), a obiekty RequestHandler będą zapisywać wiadomości do bazy danych zamiast do plików. Chcesz zmienić sposób generowania wiadomości? Znowu zmieniasz jedną linijkę ARequestHandler na BRequestHandler.

Obiekty StorageInterface i AbstractRequestHandler możesz tworzyć np. na podstawie pliku konfiguracyjnego przy stracie aplikacji i dalej nie obchodzi Cie z jakiej implementacji korzystasz. Przez to możesz zmieniać zachowanie aplikacji w pliku konfiguracyjnym.

Klasa zajmująca się zapisem do bazy jest interfejsem, ponieważ jedyną wspólną rzeczą dla wszystkich klas zapisujących wiadomości jest to, że aby zapisać wiadomość trzeba wywołać metodą save z jednym argumentem(php 5.x niestety nie pozwala ograniczyć typu argumentu do stringa w deklaracji metody). AbstractRequestHandler jest klasą abstrakcyjną, ponieważ jej klasy pochodne mają wspólny kod (konstruktor).

Zauważ że sposób zapisu i sposób generowania wiadomości zmieniasz niezależnie, dzięki temu że wydzieliliśmy te dwie odpowiedzialności od siebie. Gorszym rozwiązaniem byłoby definiowanie sposobu generowania wiadomości i zapisu w jednej klasie, wtedy moglibyśmy mieć klasy ARequestHandlerFileStorage, ARequestHandlerDbStorage, BRequestHandlerFileStorage itd.

Zanim zacznie się uczyć wzorców projektowych, warto dowiedzieć się trochę na temat ogólnych zasad programowania obiektowego albo kupić dobrą książkę na temat wzorców. W internecie nigdy nie trafiłem na źródła z dobrym wprowadzeniem do programowanie obiektowego, nigdy też nie widziałem w internecie dobrych przykładów.

Jeszcze co do interfejsów: to pokazuje gdzie mają przewagę nad klasami abstrakcyjnymi przykłady są w javie ale każdy powinien zrozumieć.

Ten post edytował droslaw 13.12.2015, 23:24:01
Go to the top of the page
+Quote Post
trzczy
post 14.12.2015, 08:28:08
Post #14





Grupa: Zarejestrowani
Postów: 460
Pomógł: 49
Dołączył: 5.06.2011

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


Cytat(Pyton_000 @ 13.12.2015, 19:08:52 ) *
O jakim dublowaniu mówisz. Bo tutaj jedynie dublowanie gettery.

Mówię konkretnie o tym właśnie dublowaniu.

Cytat(droslaw @ 13.12.2015, 22:18:07 ) *
Damansson ma rację, w tutorialu żadne metody nie są dublowane.

Zdaje się, że 2 osoby zauważyły, że są dublowane.

I pojawia się nam problem, co to znaczy definicja metody. Dla mnie definicja metody to jest to samo co deklaracja metody. I z tego co widzę, to sugerujecie, że definicją metody jest na przykład samo coś takiego:
  1. public function save($message);


Zatem mielibyśmy definicję metody, która nie określa, jak działa metoda, czyli nie definiuje metody w sensie matematycznym. Jest to dla mnie trudne do przyjęcia, i w sumie nie wiem co z tym zrobić. Pamiętam, że kiedyś coś kodowałem w jakimś języku programowania, gdzie było słowo kluczowe 'defun nazwafunkcji' i dalej następowało body funkcji. Ale jeśli w oop rzeczywiście definicja nie musi definiować, to może niepotrzebnie poprawiałem Kolegę powyżej w jednym z postów.

Nie będę się szczegółowo odnosił do wszystkiego w tym wątku, ale ogólnie pojawia mi się obraz i wnioski, za co Wam dziękuję.

Ten post edytował trzczy 14.12.2015, 08:31:54
Go to the top of the page
+Quote Post
Pyton_000
post 14.12.2015, 08:33:13
Post #15





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


Settery i gettery to nie problem. O ile nie mają std. zadania to prawie każde IDE wygeneruje Ci taką listę.

Ad. definicji w programowaniu jest definicja/deklaracja i implementacja.

Go to the top of the page
+Quote Post
droslaw
post 14.12.2015, 12:16:07
Post #16





Grupa: Zarejestrowani
Postów: 98
Pomógł: 33
Dołączył: 10.05.2011
Skąd: Krak

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


Cytat(trzczy @ 14.12.2015, 08:28:08 ) *
I pojawia się nam problem, co to znaczy definicja metody. Dla mnie definicja metody to jest to samo co deklaracja metody. I z tego co widzę, to sugerujecie, że definicją metody jest na przykład samo coś takiego:
  1. public function save($message);

Kiedyś bawiłem się w C++, tam rozróżnienie miedzy definicją i deklaracją jest wyraźne: What is the difference between a definition and a declaration?. Java: What is the difference between declaration and definition in Java? (PHP jest pod tym względem podobny do Javy). Dlatego dla mnie deklaracja to nie koniecznie definicja. A może lepiej używać pojęć interfejs i implementacja. Warto byłoby ustalić wspólne nazewnictwo bo wtedy będzie mniej nieporozumień i chętnie dowiem się co jeszcze inni na ten temat myślą.

Cytat(trzczy @ 14.12.2015, 08:28:08 ) *
Zatem mielibyśmy definicję metody, która nie określa, jak działa metoda, czyli nie definiuje metody w sensie matematycznym. Jest to dla mnie trudne do przyjęcia, i w sumie nie wiem co z tym zrobić. Pamiętam, że kiedyś coś kodowałem w jakimś języku programowania, gdzie było słowo kluczowe 'defun nazwafunkcji' i dalej następowało body funkcji. Ale jeśli w oop rzeczywiście definicja nie musi definiować, to może niepotrzebnie poprawiałem Kolegę powyżej w jednym z postów.

Czyli w interfejsie masz metody bez implementacji a implementację dajesz dopiero klasach implementujących ten interfejs. Jest to jedna z najważniejszych cech programowania obiektowego. Dobrze że uczysz się wzorców ale lepiej byłoby gdybyś najpierw dobrze zrozumiał ogólne zasady dotyczące programowania obiektowego.
Go to the top of the page
+Quote Post
Matrix12
post 15.12.2015, 08:00:27
Post #17





Grupa: Zarejestrowani
Postów: 144
Pomógł: 0
Dołączył: 22.03.2015

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


W przykładzie gdzie implementujesz interfejs chodzi o to, że w interfejsie masz określone jakie metody musza być implementowane w danym obiekcie. W Twoim przykładzie pokazałeś dwa obiekty implementujące ten interfejs, a te obiekty są różne to że one zawierają te metody to nie oznacza że są identyczne, bo poniżej mogą zawierać inne metody które coś tam robią. Interfejs określa Ci czego potrzebujesz aby stworzyć dany obiekt który np. będzie wstrzykiwany do innej metody lub obiektu i wtedy będziesz miał wpisane na przykład tak :


public function example(TwojInterfejs $service){ .. }

Go to the top of the page
+Quote Post
trzczy
post 17.12.2015, 01:13:47
Post #18





Grupa: Zarejestrowani
Postów: 460
Pomógł: 49
Dołączył: 5.06.2011

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


Jeszcze się gubię w tym branżowym słownictwie...
Cytat(Matrix12 @ 15.12.2015, 08:00:27 ) *
public function example(TwojInterfejs $service){ .. }


TwojInterfejs to jest type hinting i jednocześnie nazwa wymaganej klasy? Słowa 'Interfejs' używacie w znaczeniu 'interface', czyli słowa kluczowego php czy może w znaczeniu API? Sorka pewnie kaleczę zwyczajowy żargon. sciana.gif

Ten post edytował trzczy 17.12.2015, 01:15:17
Go to the top of the page
+Quote Post
Pyton_000
post 17.12.2015, 10:06:18
Post #19





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


Możesz nazwać jak chcesz np:

StorageInterface
StorageI
IStorage
InterfaceStorage

Dowolność, chodzi o to żeby wiedzieć że Obiekt docelowy wkładany do metody musi być typu lub implementować interface.
Go to the top of the page
+Quote Post
trzczy
post 17.12.2015, 12:35:52
Post #20





Grupa: Zarejestrowani
Postów: 460
Pomógł: 49
Dołączył: 5.06.2011

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


Cytat(Pyton_000 @ 17.12.2015, 10:06:18 ) *
Dowolność, chodzi o to żeby wiedzieć że Obiekt docelowy wkładany do metody musi być typu lub implementować interface.

Zatem przykładowo taki type hint 'InterfaceStorage' musi być wcześniej zadeklarowany w ten sposób:

class InterfaceStorage {
//some code here
}

lub

interface InterfaceStorage {
//some code here
}

tak łopatologicznie?
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
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: 28.04.2024 - 13:18