Witaj, Gościu O nas | Kontakt | Mapa
Wortal Forum PHPEdia.pl Planeta Kubek IRC Przetestuj się!

Klasy abstrakcyjne w PHP 4

Implementacja klas abstrakcyjnych w PHP 4.

Aby zaimplementować kalsę abstrakcyjną musimy przypomnieć sobię podstawowe założenia klas abstrakcyjnych:

  • Klasa abstrakcyjna nie może posiadać instancji.
  • Klasa abstrakcyjna może (i powinna) zawierać metody abstrkacyjne(bez implementacji)

Jeśli klasa zawiera metody abstrakcyjne jest klasą abstrakcyjną. Klasy dziedziczące musza zaimplemtować te metody lub również być klasą abstrakcyjną samą w sobie. PHP w wersji czwartej nie posiada żadnej z wyżej wymienionych możliwości. Więc nasuwa się pytanie - w jaki sposób zaimpelmetujemy klasę abstrakcyjną w PHP 4 ? To proste. Potrzebne jest Nam trochę ludzkiej pomysłowości oraz dobrze dokumentowany kod. Pierwszą rzeczą jaką musimy opracować to to w jaki sposób zapobiec stworzeniu instancji klasy. Dla przykładu zaimplmentujemy klasę bazową ("Base") wraz z pustym konstruktorem. Tak więc...

<?php
class Base
{
	function Base()
	{	
		//nie dopuszczamy do stworzenia instancji klasy bazowej
		if(strcasecmp(get_class($this),"Base")==0)
		{
			trigger_error("Instancja klasy bazowej jest zabroniona",E_USER_ERROR);
			return NULL;
		}
	}
}
?>

No dobra - dodaliśmy kilka linii ekstra do naszego konstruktora. Tak, nie wygląda to może zbyt ładnie i elegancko jak dodanie słowa abstract(możliwe od wersji piątej), ale działa i zapewnia nam funkcjonalność klasy abstrakcyjnej. Podczas wywoływania konstruktora pobieramy nazwę klasy z jej aktualnej instancji i porównujemy z nazwą klasy bazowej ("Base"). Jeśli nazwy się zgadzają wywołujemy błąd powodujący zatrzymanie wykonywania skryptu.Skończyliśmy ? Nie do końca. Owszem próba stworzenia instancji naszej klasy bazowej kończy się wywołaniem błędu, ale nic nie broni aby wywolać konstrktor statycznie, Base::Base(). Każda klasa może wywołać nasz konstruktor korzystając ze statycznego wywołania. Tak więc w praktyce w dowolnym miejscu możemy wywołać nasz konstruktor statycznie. PHP 4 nie dostrzega różnicy pomiędzy instancją oraz metodami statycznymi(wyłączając dostępność $this podczas działania klasy), tak więc my dodamy do klasy coś od siebie.

<?php
class Base
{
	function Base()
	{	
		//nie dopuszczamy do stworzenia instancji klasy bazowej
		if(strcasecmp(get_class($this),"Base")==0)
		{
			trigger_error("Instancja klasy bazowej jest zabroniona.",E_USER_ERROR);
			return NULL;
		}
		//nie dopuszczamy do wywołania konstruktora przez podklasę
		if(!is_subclass_if($this,"Base"))
		{
			trigger_error("Instancja klasy bazowej jest zabroniona dla klas dziedziczących.",E_USER_ERROR);
			return NULL;
		}
	}
}
?>

Tak więc teraz nasza klasa bazowa nie może posiadać instancji oraz jej konstrktor nie może być wywałany statycznie przez podklasy. Próba uruchomienia którejś z poniższych linijek w naszym skrypcie spowoduje wywołanie błędu.

<?php
$bae=new Base();
Base::Base();
?>

Aby zakończyć sprzątnijmy trochę nasz kod. Drugi warunek if() służy Nam do dwóch celów. Po pierwsze zapobiega wywolaniu statycznemu konstruktora oraz o dziwo zapewnia Nam funkcjonalność zapobiegającą utworzeniu instancji naszego obiektu. Aby się przekonać możemy wykomentować pierwszy warunek zawarty w if()-ie. i teraz wywołania dwóch powyższych linii kodu spowoduje wywołanie błędu oraz zatrzymanie wykonywania skryptu. Tak więc poza usunięciem pierwszego warunku if() zmienimy trochę treść komunikatu. Kod który uzyskaliśmy w prosty sposób będzie nam symulował posiadanie klasy abstrakcyjnej.

<?php
class Base
{
	function Base()
	{
		/*
		*nie dopuszczamy do stworzenia instancji klasy bazowej
		*nie dopuszczamy do wywołania konstruktora przez podklasę
		*/
		if(!is_subclass_if($this,"Base"))
		{
			trigger_error("Instancja klasy bazowej jest zabroniona.",E_USER_ERROR);
			return NULL;
		}
	}
}
?>

Aby zapamiętać charakterystykę klasy abstrkacyjnej w PHP 4 musimy bardzo dbać o komentarze w naszym kodzie. Większość wcześniej wspomnianych cech charakterystycznych klasy abstrakcyjnej(np. zmuszenie klas dziedziczących do zaimpletowania odziedziczonych metod abstrakcyjnych) jest wyagana przez języki takie jak Java i sprawdzane podczas kompilacji programu. My możemy użyć funkcji method_exists() aby się upewnić, że podklasa posiada takie same metody jak klasa bazowa. Oczywiście ta klasa za każdym razem zwróci Nam prawdę, ponieważ te metody istnieją jakoże zostały odziedziczone po klasie bazowej. W PHP 4 nie ma różnicy pomiędzy metodą abstrakcyjną oraz nieabstrakcyjną. Niestety w PHP 4 nie ma sensowanej metody aby sprawdzić czy metoda posiada implementację. Tak więc My musimy sobie radzić dzięki komentarzom, które poinformują osobę implementująca jakie metody dana klasa musi zawierać.

Informacje na podobny temat:
Wasze opinie
Wszystkie opinie użytkowników: (4)
Literówka c.d.
Środa 21 Marzec 2007 3:24:56 pm - skyfly <przemekkus_at_interia.pl>

listingach :)

Literówka
Środa 21 Marzec 2007 3:23:49 pm - skyfly <przemekkus_at_interia.pl>

We wszystkich listningach zamiast "is_subclass_if" ma być oczywiście "is_subclass_of".

abstrakcja
Sobota 28 Styczeń 2006 6:18:42 pm - emp

Abstrakcja jest ale nie ma dziedziczenia wielorakiego.. tylko interfejsy a to jest kapa w prownaniu z mozliwosciami jakie daje welorakie dziedziczenie... jak mozna usuwac jakies udogodnienia tylko dlatego ba sa programisci ktorzy nie umieja z nich skorzystac... przyklad javy rezygnacia z wiekszosci udogodnien jest spowodowana tym by programisci popelniali mniej bledow .. chory pomysl tak offtopik ;)

Brak danych
Piątek 13 Styczeń 2006 10:45:21 pm - ..:: pingu ::.. <pingu_at_interia.pl>

literowka w podstronie:
Implementacja klas abstrakcyjnych w PHP 4.
na samym koncu (tzn koncowy akapit)
W PHP 4 nie ma różnicuy pomiędzy metodą abstrakcyjną oraz nieabstrakcyjną

Mentax.pl    NQ.pl- serwery z dodatkiem świętego spokoju...   
O nas | Kontakt | Mapa serwisu
Copyright (c) 2003-2022 php.pl    Wszystkie prawa zastrzeżone    Powered by eZ publish Content Management System eZ publish Content Management System