Ustalanie pozycji elementów w CSS cz. 2.

11 stycznia 2011

Pozycjonowanie absolutne

W pozycjonowaniu absolutnym określamy pozycje elementu względem kontenera. Kontenerem zazwyczaj jest element body, może też być nim inny element z właściwością position ustawioną na relative, absolute lub fixed. Elementy występujące po elemencie pozycjonowanym zajmują miejsce tego elementu. Pozycje tradycyjnie ustala się właściwościami left, right, top i bottom. W przypadku gdy ustalamy właściwość top, a kontenerem jest element body, pozycja jest liczona od dolnej krawędzi części widocznej po załadowaniu strony. Samo pozycjonowanie absolutne jest określane właściwością position: absolute;. Poniżej przedstawiłem element pozycjonowany absolutnie w czerwonym obramowaniu. Dla większej jasności po elemencie pozycjonowanym umieściłem element dodatkowy (zielone tło), a całość umieszczam w elemencie z szaro-niebieską ramką.

<div class="ramka">
	<div class="border" id="absolute1">Element w pierwotnym położeniu</div>
	<div class="dodatkowy">Element dodatkowy</div>
</div>
#absolute1
{
	position: absolute;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
	background-color: #ffffff;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
.dodatkowy
{
	margin: 8px;
	padding: 12px;
	background-color: #33ff99;
	color: #ffffff;
	font-weight: bold;
}
Element w pierwotnym położeniu
Element dodatkowy


<div class="ramka">
	<div class="border" id="absolute2">
	Element z właściwością left: 40px; - odsunięty od lewej krawędzi kontenera o 40 pikseli
	</div>
	<div class="dodatkowy">Element dodatkowy</div>
</div>
#absolute2
{
	position: absolute;
	left: 40px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
	background-color: #ffffff;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
.dodatkowy
{
	margin: 8px;
	padding: 12px;
	background-color: #33ff99;
	color: #ffffff;
	font-weight: bold;
}
Element z właściwością left: 40px; – odsunięty od lewej krawędzi kontenera o 40 pikseli
Element dodatkowy


<div class="ramka">
	<div class="border" id="absolute3">
	Element z właściwością right: 40px; - odsunięty od prawej krawędzi kontenera o 40 pikseli
	</div>
	<div class="dodatkowy">Element dodatkowy</div>
</div>
#absolute3
{
	position: absolute;
	right: 40px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
	background-color: #ffffff;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
.dodatkowy
{
	margin: 8px;
	padding: 12px;
	background-color: #33ff99;
	color: #ffffff;
	font-weight: bold;
}
Element z właściwością right: 40px; – odsunięty od prawej krawędzi kontenera o 40 pikseli
Element dodatkowy


<div class="ramka">
	<div class="border" id="absolute4">
	Element z właściwością bottom: 10px; - odsunięty od dolnej krawędzi kontenera o 10 pikseli
	</div>
	<div class="dodatkowy">Element dodatkowy</div>
</div>
#absolute4
{
	position: absolute;
	bottom: 10px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
	background-color: #ffffff;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
.dodatkowy
{
	margin: 8px;
	padding: 12px;
	background-color: #33ff99;
	color: #ffffff;
	font-weight: bold;
}
Element z właściwością bottom: 10px; – odsunięty od dolnej krawędzi kontenera o 10 pikseli
Element dodatkowy


<div class="ramka">
	<div class="border" id="absolute5">
	Element z właściwością top: 3500px; - odsunięty od górnej krawędzi kontenera o 3500 pikseli
	</div>
	<div class="dodatkowy">Element dodatkowy</div>
</div>
#absolute5
{
	position: absolute;
	top: 3500px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
	background-color: #ffffff;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
.dodatkowy
{
	margin: 8px;
	padding: 12px;
	background-color: #33ff99;
	color: #ffffff;
	font-weight: bold;
}
Element z właściwością top: 3500px; – odsunięty od górnej krawędzi kontenera o 3500 pikseli
Element dodatkowy


<div class="ramka">
	<div class="border" id="absolute6">
	Element z właściwościami left: 40px; i top: 4500px - odsunięty od lewej krawędzi kontenera o 40 pikseli oraz od górnej krawędzi o 4500 pikseli
	</div>
	<div class="dodatkowy">Element dodatkowy</div>
</div>
#absolute6
{
	position: absolute;
	left: 40px;
	top: 4500px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
	background-color: #ffffff;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
.dodatkowy
{
	margin: 8px;
	padding: 12px;
	background-color: #33ff99;
	color: #ffffff;
	font-weight: bold;
}
Element z właściwościami left: 40px; i top: 4500px – odsunięty od lewej krawędzi kontenera o 40 pikseli oraz od górnej krawędzi o 4500 pikseli
Element dodatkowy


<div class="ramka" id="relative">
	<div class="border" id="absolute7">
	Element z właściwościami left: 40px; i top: 50px - odsunięty od lewej krawędzi kontenera o 40 pikseli oraz od górnej krawędzi o 50 pikseli. W tym przypadku kontenerem jest element o identyfikatorze relative.
	</div>
	<div class="dodatkowy">Element dodatkowy</div>
</div>
#absolute6
{
	position: absolute;
	left: 40px;
	top: 50px;
}
#relative
{
	position: relative;
	left: -30px;
	top: 10px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
	background-color: #ffffff;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
.dodatkowy
{
	margin: 8px;
	padding: 12px;
	background-color: #33ff99;
	color: #ffffff;
	font-weight: bold;
}
Element z właściwościami left: 40px; i top: 50px – odsunięty od lewej krawędzi kontenera o 40 pikseli oraz od górnej krawędzi o 50 pikseli. W tym przypadku kontenerem jest element o identyfikatorze relative.
Element dodatkowy

Zachęcam do pozostawieni swoich uwag i komentarzy poniżej.

Ustalanie pozycji elementów w CSS cz. 1.

20 grudnia 2010

Pozycjonowanie względne

W pozycjonowaniu względnym możemy przesuwać element względem pierwotnego położenia. Służą do tego właściwości left, right, top i bottom. Samo pozycjonowanie względne jest określane właściwością position: relative;. Poniżej przedstawiłem element pozycjonowany względnie w czerwonym obramowaniu. Dla większej jasności elementy pozycjonowane umieszczam w elemencie z szaro-niebieską ramką.

<div class="ramka">
	<div class="border" id="relative1">Element w pierwotnym położeniu</div>
</div>
#relative1
{
	position: relative;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
Element w pierwotnym położeniu


<div class="ramka">
	<div class="border" id="relative2">
	Element z właściwością left: 40px; - odsunięty od lewej krawędzi pierwotnego położenia o 40 pikseli
	</div>
</div>
#relative2
{
	position: relative;
	left: 40px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
Element z właściwością left: 40px; – odsunięty od lewej krawędzi pierwotnego położenia o 40 pikseli


<div class="ramka">
	<div class="border" id="relative3">
	Element z właściwością right: 40px; - odsunięty od prawej krawędzi pierwotnego położenia o 40 pikseli
	</div>
</div>
#relative3
{
	position: relative;
	right: 40px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
Element z właściwością right: 40px; – odsunięty od prawej krawędzi pierwotnego położenia o 40 pikseli


<div class="ramka">
	<div class="border" id="relative4">
	Element z właściwością bottom: 10px; - odsunięty od dolnej krawędzi pierwotnego położenia o 10 pikseli
	</div>
</div>
#relative4
{
	position: relative;
	bottom: 10px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
Element z właściwością bottom: 10px; – odsunięty od dolnej krawędzi pierwotnego położenia o 10 pikseli


<div class="ramka">
	<div class="border" id="relative5">
	Element z właściwością top: 10px; - odsunięty od górnej krawędzi pierwotnego położenia o 10 pikseli
	</div>
</div>
#relative5
{
	position: relative;
	top: 10px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
Element z właściwością top: 10px; – odsunięty od górnej krawędzi pierwotnego położenia o 10 pikseli


<div class="ramka">
	<div class="border" id="relative6">
	Element z właściwościami left: 40px; i top: 15px - odsunięty od lewej krawędzi pierwotnego 
położenia o 40 pikseli oraz od górnej krawędzi o 15 pikseli
	</div>
</div>
#relative6
{
	position: relative;
	left: 40px;
	top: 15px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
Element z właściwościami left: 40px; i top: 15px – odsunięty od lewej krawędzi pierwotnego położenia o 40 pikseli oraz od górnej krawędzi o 15 pikseli

Zachęcam do pozostawieni swoich uwag i komentarzy poniżej.

Metoda, która nie istnieje…

13 grudnia 2010

Kilka lat temu, gdy nie znałem jeszcze wszystkich tajników programowania obiektowego, zlecono mi modyfikację pewnego skryptu napisanego właśnie obiektowo. Klasy, obiekty i metody nie były dla mnie zupełną nowością, więc zabrałem się do pracy z nastawieniem, że szybko wykonam zlecenie, wezmę kasę i… Już teraz nie pamiętam na co chciałem wydać te pieniądze ;) .

Zlecenie wydawało się dziecinnie proste. Przynajmniej do czasu, za nim nie wgłębiłem się w kod. Skrypt był podobny do tego poniżej: na początku definicje kilku klas, a później program, który ich używał. Klasy nie wzbudziły moich podejrzeń. Za to później trafiłem, na coś, czego zupełnie nie mogłem zrozumieć.

W poniższym kodzie, symulującym kilka kolejnych zakupów i sprzedaży złota przy zmieniającym się kursie, umieściłem coś podobnego. Chodzi mi o metody kup() i sprzedaj() wywoływane na obiekcie $zloto klasy Gold. Tyle że w klasie Gold nie ma definicji metod kup() i sprzedaj(). Klasa Gold nie rozszerza też żadnej innej klasy, po której mogłaby te metody odziedziczyć. O co więc chodzi?

Najdziwniejsze było to, że ten kod działał. Nie zgłaszał żadnych błędów. W pewnym momencie zacząłem podejrzewać mój komputer o magię i jak się okazało, w pewnym sensie trafiłem. Rozwiązaniem mojej zagadki była metoda _call() należąca do grupy tzw. metod magicznych, które odpowiadają za właśnie takie „niezwykłe” zachowanie programu.

Zajmijmy się jednak poniższym przykładem.

<?php
class Gold
{
	const NAZWA='zloto';
	private $cena=128.4;
 
	public function kurs()
	{
		return $this->cena;
	}
 
	public function __call($n, $p)
	{
		$this->zmien_kurs();
		return array('koszt' => $p[0]*$this->cena, 'towar' => array('nazwa' => self::NAZWA, 'ilosc' => $p[0]));
	}
 
	private function zmien_kurs()
	{
		$zmiana=rand(1, 200)/100;
 
		switch(rand(1, 2))
		{
			case '1': $this->cena+=$zmiana;
			break;
			case '2': $this->cena-=$zmiana;
			break;
		}
	}
}
 
class Portfel
{
	private $kasa=0;
	private $inwestycje=array();
 
	public function __construct($kasa)
	{
		$this->kasa=$kasa;
	}
 
	public function sprawdz()
	{
		return array_merge(array('pieniadze' => $this->kasa), $this->inwestycje);
	}
 
	public function transakcja($inwestycja)
	{
		$this->kasa-=$inwestycja['koszt'];
		$this->inwestycje[$inwestycja['towar']['nazwa']]+=$inwestycja['towar']['ilosc'];
	}
}
 
$portfel= new Portfel(10000);
$zloto= new Gold;
 
echo '<br />Sprawdzenie:<br />';
foreach($portfel->sprawdz() as $key => $value)
{
	echo $key.': '.$value.'<br />';
}
 
//kupuję 24 sztabki złota
$portfel->transakcja($zloto->kup(24));
echo '<br />Aktualny kurs: ';
echo $zloto->kurs();
 
echo '<br />Sprawdzenie:<br />';
foreach($portfel->sprawdz() as $key => $value)
{
	echo $key.': '.$value.'<br />';
}
 
//sprzedaję 32 sztabki złota
$portfel->transakcja($zloto->sprzedaj(-32));
echo '<br />Aktualny kurs: ';
echo $zloto->kurs();
 
echo '<br />Sprawdzenie:<br />';
foreach($portfel->sprawdz() as $key => $value)
{
	echo $key.': '.$value.'<br />';
}
 
$portfel->transakcja($zloto->kup(53));
echo '<br />Aktualny kurs: ';
echo $zloto->kurs();
 
echo '<br />Sprawdzenie:<br />';
foreach($portfel->sprawdz() as $key => $value)
{
	echo $key.': '.$value.'<br />';
}
 
$portfel->transakcja($zloto->sprzedaj(-20));
echo '<br />Aktualny kurs: ';
echo $zloto->kurs();
 
echo '<br />Sprawdzenie:<br />';
foreach($portfel->sprawdz() as $key => $value)
{
	echo $key.': '.$value.'<br />';
}
 
$portfel->transakcja($zloto->sprzedaj(-25));
echo '<br />Aktualny kurs: ';
echo $zloto->kurs();
 
echo '<br />Sprawdzenie:<br />';
foreach($portfel->sprawdz() as $key => $value)
{
	echo $key.': '.$value.'<br />';
}
?>

Metody sprzedaj() lub kup() są wywoływane na obiekcie $zloto z przekazanym do nich argumentem typu int. Dla metody kup() argument ma zawsze wartość dodatnią i oznacza ilość kupionego towaru (dodatnia wartość oznacza, że zyskaliśmy tyle sztuk tego towaru), natomiast dla metody sprzedaj() argument ma wartość ujemną (pozbywamy się towaru). Wynik działania tych metod przekazywany jest do metody transakcja() wywołanej na obiekcie $portfel klasy Portfel.

Ponieważ metody sprzedaj() i kup() nie zostały zdefiniowane w klasie Gold, obsługą tych wywołań zajmie się metoda magiczna __call() Metoda przyjmuje dwa argumenty $n i $p. W pierwszym argumencie, w tym akurat przypadku nieużywanym, jest dostępna nazwa wywoływanej metody. Natomiast drugi argument jest tablicą argumentów, z jakimi metoda została wywołana. Metody sprzedaj() i kup() są wywoływane tylko z jednym argumentem więc $p jest tablicą jednoelementową. Wywołując metody sprzedaj() lub kup() robimy praktycznie to samo – zmieniamy ilość pieniędzy i złota w portfelu. To czy ta zmiana jest na plus czy na minus zależy od wartości argumentu, więc nazwy metod są zbędne.

Na dobrą sprawę moglibyśmy metodę __call() zastąpić np. metodą kupno_sprzedaz(), którą wywoływalibyśmy zupełnie jawnie w kodzie i nie byłoby tego całego zamieszania. Jednak dzięki użyciu metod sprzedaj() i kup() kod jest bardziej intuicyjny (pod warunkiem, że zna się metody magiczne). Poza tym dzięki różnym nazwom moglibyśmy zmodyfikować metodę __call() w taki sposób, by przy transakcji sprzedaży doliczana byłaby marża, a przy kupnie nie. Wystarczyłoby sprawdzić wówczas wartość argumentu $n. Zresztą możliwości jest dużo więcej, a __call() to tylko jedna z metod magicznych. Warto znać je wszystkie.

Pisząc ten artykuł postawiłem sobie zadanie przybliżenia pojęcia metod magicznych na przykładzie metody __call(). Gdyby jednak inne elementy przykładowego programu były dla Ciebie nie do końca zrozumiałe, napisz o tym w komentarzu poniżej. Chętnie wszystko wyjaśnię.

Interfejs czy abstrakcja?

24 listopada 2010

Wielu programistów stawiających pierwsze kroki w programowaniu obiektowym ma problem z decyzją, kiedy stosować dziedziczenie po klasie abstrakcyjnej, a kiedy implementację interfejsu. Dodatkowo dużo zamieszania wprowadza często powtarzane twierdzenie, że mechanizm implementacji interfejsów jest receptą na brak możliwości bezpośredniego dziedziczenia po kilku klasach jednocześnie.

Załóżmy, że mamy dwie klasy abstrakcyjne:

abstract class Uzytkownik
{
  protected $imie='';
  protected $nazwisko='';
 
  public abstract function zapisz_imie($imie)
  {
    $this->imie=$imie;
  }
 
  public abstract function zapisz_nazwisko($nazwisko)
  {
    $this->nazwisko=$nazwisko;
  }
}
 
abstract class Uprawnienia
{
  protected $poziom=0;
  protected $zakres=array();
 
  public abstract function ustaw_poziom($poziom)
  {
    $this->poziom=$poziom;
  }
 
  public abstract function dodaj_zakres($zakres)
  {
    $this->zakres[]=$zakres;
  }
 
  public abstract function sprawdz_dostep($zakres)
  {
    return in_array($zakres, $this->zakres);
  }
}

Nie możemy utworzyć klas Administrator, Kierownik, Handlowiec itp. dziedziczących po tych klasach. Zapis: „class Admin extends Uzytkownik, Uprawnienia” spowoduje przerwanie programu i wyświetlenie odpowiedniego komunikatu błędu. Próba rozwiązania tego problemu przy pomocy interfejsów wyglądałaby tak:

interface Uzytkownik
{
  public function zapisz_imie($imie);
  public function zapisz_nazwisko($nazwisko);
}
 
interface Uprawnienia
{
  public function ustaw_poziom($poziom);
  public function dodaj_zakres($zakres);
  public function sprawdz_dostep($zakres);
}
 
class Administrator implements Uzytkownik, Uprawnienia
{
  protected $imie='';
  protected $nazwisko='';
  protected $poziom=0;
  protected $zakres=array();
 
  public function zapisz_imie($imie)
  {
    $this->imie=$imie;
  }
 
  public function zapisz_nazwisko($nazwisko)
  {
    $this->nazwisko=$nazwisko;
  }
 
  public function ustaw_poziom($poziom)
  {
    $this->poziom=$poziom;
  }
 
  public function dodaj_zakres($zakres)
  {
    $this->zakres[]=$zakres;
  }
 
  public function sprawdz_dostep($zakres)
  {
    return in_array($zakres, $this->zakres);
  }
}
 
class Kierownik implements Uzytkownik, Uprawnienia
{
  protected $imie='';
  protected $nazwisko='';
  protected $poziom=0;
  protected $zakres=array();
 
  public function zapisz_imie($imie)
  {
    $this->imie=$imie;
  }
 
  public function zapisz_nazwisko($nazwisko)
  {
    $this->nazwisko=$nazwisko;
  }
 
  public function ustaw_poziom($poziom)
  {
    $this->poziom=$poziom;
  }
 
  public function dodaj_zakres($zakres)
  {
    $this->zakres[]=$zakres;
  }
 
  public function sprawdz_dostep($zakres)
  {
    return in_array($zakres, $this->zakres);
  }
}

To co od razu rzuca się w oczy, to identyczne metody w klasach Administarator i Kierownik. Taki zapis jest rozwiązaniem fatalnym i niwelującym większość zalet programowania obiektowego. Na tym przykładzie wyraźnie widać, że interfejsy nie zastąpią dziedziczenia. Zaś na dziedziczenie bezpośrednio po kilku klasach programistom PHP przyjdzie poczekać pewnie jeszcze kilka lat. Są sposoby symulowania takiego dziedziczenia już dzisiaj przy pomocy metod magicznych. Jeden z takich sposobów omawiam w szkoleniu Programowanie Obiektowe w PHP. Nie to jednak jest tematem tego artykułu.

Na podstawie powyższych przykładów mogę stwierdzić, jakie są korzyści z dziedziczenia.

  • Metody zdefiniowane w jednej klasie mogę użyć w innych klasach.
  • Mogę podzielić kod całego elementu na małe części (klasy) zawierające dane i funkcje związane z konkretną częścią systemu lub aspektem działania systemu.

A jakie są zalety interfejsów? Wyjaśnię to na przykładzie poniżej.

interface Cache
{
  public function zapisz($klucz, $dane);
  public function odczytaj($klucz);
}
 
class Pliki implements Cache
{
  public function zapisz($klucz, $dane)
  {
    //zapis danych w plikach na dysku serwera
    //...
  }
 
  public function odczytaj($klucz)
  {
    //odczyt danych z plików serwera
    //...
  }
}
 
class Baza_danych implements Cache
{
  public function zapisz($klucz, $dane)
  {
    //zapis danych w bazie danych
    //...
  }
 
  public function odczytaj($klucz)
  {
    //odczyt danych z bazy danych
    //...
  }
}

Dzięki zastosowaniu interfejsu możemy tworzyć program, a na samym końcu zdecydować czy będziemy korzystać z cachowania w plikach czy bazie danych. Implementacja tego samego interfejsu przez klasy Pliki i Baza_danych wymusza na nich posiadanie metod o takich samych nazwach i tej samej liczbie argumentów. Korzyści prezentuję na poniższym przykładzie

//$cache = new Pliki;
$cache = new Baza_danych;
 
$cache->zapisz('czas', '11:20');
//...
$czas=$cache->odczytaj('czas');

Możemy dowolnie wybrać jakiej klasy ma być obiekt $cache bez wpływu na dalszy kod. Ponadto możemy zlecić innemu programiście napisanie klasy, która będzie implementowała interfejs Cache i ona również będzie pasowała do napisanego wcześniej kodu.

Zabezpieczony: Programowanie obiektowe w PHP – lekcje 8-9

17 listopada 2010

Ten wpis jest zabezpieczony hasłem. Aby go zobaczyć, proszę wprowadzić poniżej swoje hasło:

Zabezpieczony: Programowanie obiektowe w PHP – lekcje 6 i 7

16 listopada 2010

Ten wpis jest zabezpieczony hasłem. Aby go zobaczyć, proszę wprowadzić poniżej swoje hasło:

Programowanie obiektowe w PHP – lekcje 4 i 5.

15 listopada 2010

Poniżej prezentuję kolejne fragmenty szkolenia Programowanie obiektowe w PHP. Jutro następna część, a za kilka dni pełne szkolenie znajdzie się w ofercie Serwan.pl.

Słowniczek

pole klasy / właściwość klasy
zmienna dowolnego typu zawarta w klasie. Polem klasy może być również tablica lub obiekt.
metoda
funkcja zawarta w klasie
konstruktor
Metoda klasy uruchamiana automatycznie podczas tworzenia obiektu danej klasy. Do konstruktora można przekazywać argumenty. Ten temat poruszam w lekcjach 6-8.
destruktor
Metoda klasy uruchamiana automatycznie podczas usuwania obiektu danej klasy. Do destruktora nie przekazuje się argumentów. Destruktor omawiany jest w lekcji 9.

Dla większej wygody można powiększyć nagranie klikając ikonkę w prawym dolnym rogu filmu. Klip wymaga wtyczki Adobe Flash Player.

Ostatnia instrukcja powyższego przykładu jest trochę dziwna. Do metody „metoda1″ obiektu „obiekt” jest przekazywane pole tego samego obiektu, chociaż byłoby ono dostępne wewnątrz klasy poprzez referencję $this. Przekazanie tej wartości jawnie na liście argumentów jest spowodowane tym, by można było do tej metody przekazywać również inne wartości np. pola innych obiektów, wyniki działania dowolnej funkcji zwracającej liczbę, lub jawnie konkretną wartość. Ten ostatni przypadek realizowany jest w przykładzie poniżej.

Oczywiście wszelkie komentarze są mile widziane.

Programowanie obiektowe w PHP – lekcja 3.

14 listopada 2010

Poniżej prezentuję trzeci fragment szkolenia Programowanie obiektowe w PHP. Jutro kolejna część, a w przyszłym tygodniu pełne szkolenie znajdzie się w ofercie Serwan.pl.

Słowniczek

abstrakcja
klasa może być modelem abstrakcyjnym dla innych klas dziedziczących po niej. Pojęcie to jest blisko związane z dziedziczeniem w szczególności po klasach abstrakcyjnych. Klasy i metody abstrakcyjne omawiam w lekcjach 35-39. Czasami abstrakcją nazywane jest też odwzorowanie rzeczywistych modeli w strukturze klasy (abstrakcja danych i procesów). Klasa samochód byłaby abstrakcją rzeczywistego samochodu, zawarta w klasie właściwość silnik byłaby abstrakcją części samochodu, a metoda jedź – abstrakcją funkcji samochodu.
przesłanianie pól i metod
Jest to redefiniowanie / nadpisywanie pól i metod klasy bazowej w klasie pochodnej. Ten temat poruszam w lekcjach 11 i 12.
metody wirtualne
W PHP każda metoda, która została przesłonięta w klasie pochodnej staje się metodą wirtualną. W innych językach wymagałoby to zastosowania specjalnej techniki (np. poprzedzenie definicji metody słowem virtual) w PHP mamy to z automatu. Ten temat poruszam w lekcji 11.
polimorfizm (wielopostaciowość)
mechanizm który pozawala wywołanie metod o takiej samej nazwie zawartych w różnych obiektach w zależności od kontekstu wywołania metody. Przykład polimorficznego wywołania metody zawiera lekcja 11.

Dla większej wygody można powiększyć nagranie klikając ikonkę w prawym dolnym rogu filmu. Klip wymaga wtyczki Adobe Flash Player.

Oczywiście wszelkie komentarze są mile widziane.

Programowanie obiektowe w PHP – lekcja 2.

13 listopada 2010

Poniżej prezentuję drugi fragment szkolenia Programowanie obiektowe w PHP. Jutro kolejna część, a w przyszłym tygodniu pełne szkolenie znajdzie się w ofercie Serwan.pl.

W komentarzach pod wczorajszą lekcją pojawiły się pojęcia:

  • izolacja kodu
  • dziedziczenie
  • klonowanie

Te i wiele innych pojęć omawiam w kolejnych lekcjach choć nie zawsze muszą być tak nazwane. Dla większej przejrzystości i wygody będę umieszczał po kilka definicji przy każdej lekcji.

hermetyzacja/enkapsulacja (izolacja kodu, kapsułkowanie, ukrywanie informacji)
zamknięcie i ukrycie przed kodem zewnętrznym kodu i pól wewnątrz klas. Klasy udostępniają jedynie swój interfejs, za pośrednictwem którego możliwe jest wykorzystanie kodu zawartego w metodach klas i użycie pól tych klas. Technicznie służą temu omawiane w lekcji poniżej kwalifikatory dostępu. Hermetyzacja uodparnia program na błędne użycie obiektów oraz umożliwia podział procesów na prostsze czynności.
dziedziczenie
mechanizm który pozawala na tworzenie hierarchii klas od najbardziej ogólnych do szczegółowych. Wspólna funkcjonalność jest zawarta w klasach ogólnych. Klasy dziedziczące są wzbogacane o indywidualne pola i metody. Dzięki temu mechanizmowi zachodzi specjalizacja klas potomnych. Więcej na ten temat wyjaśniam w lekcji 10.
klonowanie
Ponieważ obiekty nie mogą być kopiowane w ten sam sposób co inne typy danych, stworzono mechanizm klonowania do tworzenia niezależnych kopii obiektu. Ten temat poruszam w lekcji 22.

Dla większej wygody można powiększyć nagranie klikając ikonkę w prawym dolnym rogu filmu. Klip wymaga wtyczki Adobe Flash Player.

Oczywiście wszelkie komentarze są mile widziane.

Programowanie obiektowe w PHP – lekcja 1.

12 listopada 2010

Poniżej prezentuję fragment szkolenia Programowanie obiektowe w PHP. Jutro kolejna część, a w przyszłym tygodniu pełne szkolenie znajdzie się w ofercie Serwan.pl.

Dla większej wygody można powiększyć nagranie klikając ikonkę w prawym dolnym rogu filmu. Klip wymaga wtyczki Adobe Flash Player.

Oczywiście wszelkie komentarze są mile widziane.