Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Problem z implementacją interfejsu w klasie pochodnej
Forum PHP.pl > Forum > PHP > Object-oriented programming
bongdigibonbon
Mam taki oto interfejs:

  1. <?php
  2. interface iFnc {
  3. public __construct($param1);
  4. }
  5. ?>

Oraz klasę abstrakcyjną:

  1. <?php
  2. abstract class Fnc {
  3. __construct($param1) {
  4. // kod
  5. }
  6. }
  7. ?>

Kiedy dziedziczę po klasie Fnc oraz implementuje jednocześnie interfejs, mogę utworzyć klasę pochodną bez konstruktora!

  1. <?php
  2. class Pochodna extends Fnc implements iFnc {
  3.  
  4. }
  5.  
  6. $p=new Pochodna();
  7. ?>


Jak zmusić aby klasa Pochodna musiała zawierać konstruktor?

Gdy dodam jakąś funkcję do interfejsu też muszę ją zaimplementować w klasie Pochodna. Gdy klasa Pochodna nie dziedziczyłaby po Fnc, interfejs działa tak jak powinien i wymaga aby Pochodna miała konstruktor. Również kiedy usunę konstruktor z klasy Bazowej (Fnc) zgłaszany jest błąd, że nie ma konstruktora, co może sugerować, że konstruktor w klasie Pochodnej jest odziedziczony z klasy bazowej (exclamation.gif?)

Pozdrawiam
deirathe
Nie rozumiem idei konstruktora w interfejsie, moze mi sie wydaje ale takich rzeczy sie nie robi
phpion
Może dlatego, że konstruktor jest dziedziczony?
NuLL
Dokladnie - klasa abstrakcyjna go implementuje. Przeciez jest cialo funkcji czy jest ona zaiplementowana.
Cysiaczek
Oznacz konstruktor jako abstrakcyjny i implementuj w pochodnej.

Cytat
Nie rozumiem idei konstruktora w interfejsie, moze mi sie wydaje ale takich rzeczy sie nie robi

Wydaje Ci się :roll2: Można i nawet często się robi.

Pozdrawiam.
NuLL
Pozatym http://www.php.net/~derick/meeting-notes.h...truct-signature - a to dopiero PHP6 winksmiley.jpg
bongdigibonbon
Cytat(Cysiaczek @ 29.06.2007, 11:24:52 ) *
Oznacz konstruktor jako abstrakcyjny i implementuj w pochodnej.

Może to dziwne, ale akurat konstruktor w klasie bazowej (Fnc) zawiera potrzebny kod, nie mogę oznaczyć go jako abstrakcyjny.


Cytat(phpion.com @ 29.06.2007, 10:39:01 ) *
Może dlatego, że konstruktor jest dziedziczony?

Przecież od wersji 4.0 konstruktory nie podlegają dziedziczeniu. Choć z przytoczonego przeze mnie przykładu tak można wnioskować :/
Cysiaczek
Cytat
Przecież od wersji 4.0 konstruktory nie podlegają dziedziczeniu. Choć z przytoczonego przeze mnie przykładu tak można wnioskować :/


Oczywiście. Dlatego, skoro masz zaimplementowany konstruktor, to pochodna nie musi go implementować. Wymuszenie kontruktora za pomocą interfejsu objęło tylko klasę abstakcyjną - pochodna nie musi się stosować do interfejsu. Jeśli jednak w ciele konstruktora klasy pochodnej dodasz wywołanie parent::__construct(), to już musi uwzgledniać ono nagłówek wymuszany interfejsem.

Pozdrawiam.
bongdigibonbon
Cytat(Cysiaczek @ 29.06.2007, 12:20:08 ) *
Wymuszenie kontruktora za pomocą interfejsu objęło tylko klasę abstakcyjną

Przecież pisząc
  1. <?php
  2. class Pochodna extends Bazowa implements Interfejs {
  3. ?>

implementuje interfejs dla klasy Pochodna a nie Bazowa. Czemu wymuszenie konstruktora objęło klasę abstrakcyjną Bazowa?






Myślę, że wiele już zostało wyjaśnione więc mogę napisać tak:
Co mam zrobić aby konstruktor był obligatoryjny w klasie Pochodna?
phpion
Cytat(bongdigibonbon @ 29.06.2007, 12:02:25 ) *
Przecież od wersji 4.0 konstruktory nie podlegają dziedziczeniu. Choć z przytoczonego przeze mnie przykładu tak można wnioskować :/

hmmm w takim razie dlaczego to:
  1. <?php
  2. class Class1 {
  3. public function __construct() {
  4. echo 'Class1::__construct()';
  5. }
  6. }
  7.  
  8. class Class2 extends Class1 {
  9. }
  10.  
  11. $obj = new Class2();
  12. ?>

powoduje wypisanie na ekranie:
  1. Class1::__construct()

?

Cytat(bongdigibonbon @ 29.06.2007, 12:47:22 ) *
Co mam zrobić aby konstruktor był obligatoryjny w klasie Pochodna?

Jedynym (chyba) wyjściem będzie usunięcie go z klasy macierzystej i implementacja w klasie pochodnej wraz z implementacją interfejsu:
  1. <?php
  2. interface Interface1 {
  3. public function __construct();
  4. }
  5.  
  6. abstract class Class1 {
  7. }
  8.  
  9. class Class2 extends Class1 implements Interface1 {
  10. public function __construct() {
  11. echo 'Class2::__construct()';
  12. }
  13. }
  14.  
  15. $obj = new Class2();
  16. ?>

W sytuacji gdy w klasieClass2 nie będzie konstruktora zostanie zgłoszony błąd:
  1. Fatal error: Class Class2 contains 1 abstract method and must therefore be declared abstract or implement the remaining methods

Chyba do tego zmierzaliśmy smile.gif

PS: możesz również przenieść implementację interfejsu do klasy macierzystej (Class1) co chyba będzie wygodniejsze przy późniejszym rozroście hierarchii klas.
bongdigibonbon
Cytat(phpion.com @ 29.06.2007, 12:54:02 ) *
powoduje wypisanie na ekranie:
  1. Class1::__construct()

to wyjaśnia mój problem...
ale to aby interfejs zastosować w klasie bazowej go nie rozwiązuje. muszę wymagać konstruktora w Pochodnej. Dzięki!
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.