Programowanie obiektowe w PHP
Możemy wyobrazić sobie nasz wszechświat złożony z różnych obiektów, takich jak słońce, ziemia, księżyc itp. Podobnie możemy wyobrazić sobie nasz samochód zbudowany z różnych obiektów, takich jak koło, kierownica, przekładnia itp. Tak samo istnieją koncepcje programowania obiektowego, które zakładają wszystko jako obiekt wdrożyć oprogramowanie przy użyciu różnych obiektów.
Koncepcje zorientowane obiektowo
Zanim przejdziemy do szczegółów, zdefiniujmy ważne terminy związane z programowaniem obiektowym.
Class- Jest to typ danych zdefiniowany przez programistę, który obejmuje funkcje lokalne oraz dane lokalne. Możesz myśleć o klasie jako o szablonie do tworzenia wielu instancji tego samego rodzaju (lub klasy) obiektu.
Object- Indywidualne wystąpienie struktury danych zdefiniowanej przez klasę. Definiujesz klasę raz, a następnie tworzysz wiele obiektów, które do niej należą. Obiekty są również nazywane instancjami.
Member Variable- To są zmienne zdefiniowane wewnątrz klasy. Te dane będą niewidoczne dla zewnątrz klasy i będą dostępne za pośrednictwem funkcji członkowskich. Po utworzeniu obiektu zmienne te nazywane są atrybutami obiektu.
Member function - Są to funkcje zdefiniowane w klasie i służą do uzyskiwania dostępu do danych obiektu.
Inheritance- Gdy klasa jest definiowana przez dziedziczenie istniejącej funkcji klasy nadrzędnej, wtedy nazywa się to dziedziczeniem. Tutaj klasa potomna odziedziczy wszystkie lub kilka funkcji składowych i zmiennych klasy nadrzędnej.
Parent class- Klasa dziedziczona po innej klasie. Nazywa się to również klasą podstawową lub superklasą.
Child Class- Klasa, która dziedziczy po innej klasie. Nazywa się to również podklasą lub klasą pochodną.
Polymorphism- Jest to koncepcja zorientowana obiektowo, w której ta sama funkcja może być używana do różnych celów. Na przykład nazwa funkcji pozostanie taka sama, ale pobierze inną liczbę argumentów i może wykonać inne zadanie.
Overloading- typ polimorfizmu, w którym niektóre lub wszystkie operatory mają różne implementacje w zależności od typów ich argumentów. Podobnie funkcje mogą być przeciążane przy różnych implementacjach.
Data Abstraction - Dowolna reprezentacja danych, w której szczegóły implementacji są ukryte (abstrakcyjne).
Encapsulation - odnosi się do koncepcji, w której łączymy wszystkie dane i funkcje składowe, aby utworzyć obiekt.
Constructor - odnosi się do specjalnego typu funkcji, która będzie wywoływana automatycznie, gdy wystąpi formacja obiektu z klasy.
Destructor - odnosi się do specjalnego typu funkcji, która będzie wywoływana automatycznie, gdy obiekt zostanie usunięty lub wyjdzie poza zakres.
Definiowanie klas PHP
Ogólny formularz definiowania nowej klasy w PHP jest następujący -
<?php
class phpClass {
var $var1;
var $var2 = "constant string";
function myfunc ($arg1, $arg2) {
[..]
}
[..]
}
?>
Oto opis każdej linii -
Specjalna forma class, po którym następuje nazwa klasy, którą chcesz zdefiniować.
Zestaw nawiasów klamrowych obejmujących dowolną liczbę deklaracji zmiennych i definicji funkcji.
Deklaracje zmiennych zaczynają się od specjalnego formularza var, po którym następuje konwencjonalna nazwa zmiennej $; mogą również mieć początkowe przypisanie do stałej wartości.
Definicje funkcji wyglądają podobnie do samodzielnych funkcji PHP, ale są lokalne dla klasy i będą używane do ustawiania i uzyskiwania dostępu do danych obiektu.
Przykład
Oto przykład, który definiuje klasę typu Książki -
<?php
class Books {
/* Member variables */
var $price;
var $title;
/* Member functions */
function setPrice($par){
$this->price = $par;
}
function getPrice(){
echo $this->price ."<br/>";
}
function setTitle($par){
$this->title = $par;
}
function getTitle(){
echo $this->title ." <br/>";
}
}
?>
Zmienna $thisjest zmienną specjalną i odnosi się do tego samego obiektu, tj. samo.
Tworzenie obiektów w PHP
Po zdefiniowaniu klasy możesz utworzyć dowolną liczbę obiektów tego typu. Poniżej znajduje się przykład tworzenia obiektu przy użyciunew operator.
$physics = new Books;
$maths = new Books;
$chemistry = new Books;
Tutaj stworzyliśmy trzy obiekty, które są od siebie niezależne i będą istnieć oddzielnie. Następnie zobaczymy, jak uzyskać dostęp do funkcji składowej i przetwarzać zmienne składowe.
Wywołanie funkcji członkowskich
Po utworzeniu obiektów będziesz mógł wywoływać funkcje składowe związane z tym obiektem. Jedna funkcja członkowska będzie mogła przetwarzać zmienną składową tylko powiązanego obiektu.
Poniższy przykład pokazuje, jak ustawić tytuł i ceny dla trzech książek, wywołując funkcje członkowskie.
$physics->setTitle( "Physics for High School" );
$chemistry->setTitle( "Advanced Chemistry" );
$maths->setTitle( "Algebra" );
$physics->setPrice( 10 );
$chemistry->setPrice( 15 );
$maths->setPrice( 7 );
Teraz wywołujesz inne funkcje składowe, aby uzyskać wartości ustawione w powyższym przykładzie -
$physics->getTitle();
$chemistry->getTitle();
$maths->getTitle();
$physics->getPrice();
$chemistry->getPrice();
$maths->getPrice();
To da następujący wynik -
Physics for High School
Advanced Chemistry
Algebra
10
15
7
Funkcje konstruktora
Funkcje konstruktora to specjalny typ funkcji, które są wywoływane automatycznie za każdym razem, gdy tworzony jest obiekt. Dlatego w pełni wykorzystujemy to zachowanie, inicjując wiele rzeczy za pomocą funkcji konstruktora.
PHP udostępnia specjalną funkcję o nazwie __construct()do zdefiniowania konstruktora. Możesz przekazać dowolną liczbę argumentów do funkcji konstruktora.
Poniższy przykład utworzy jeden konstruktor dla klasy Książki i zainicjuje cenę i tytuł książki w momencie tworzenia obiektu.
function __construct( $par1, $par2 ) {
$this->title = $par1;
$this->price = $par2;
}
Teraz nie musimy osobno wywoływać funkcji set, aby ustawić cenę i tytuł. Możemy zainicjować te dwie zmienne składowe tylko w momencie tworzenia obiektu. Sprawdź poniższy przykład -
$physics = new Books( "Physics for High School", 10 );
$maths = new Books ( "Advanced Chemistry", 15 );
$chemistry = new Books ("Algebra", 7 );
/* Get those set values */
$physics->getTitle();
$chemistry->getTitle();
$maths->getTitle();
$physics->getPrice();
$chemistry->getPrice();
$maths->getPrice();
To da następujący wynik -
Physics for High School
Advanced Chemistry
Algebra
10
15
7
Burzyciel
Podobnie jak funkcja konstruktora, możesz zdefiniować funkcję destruktora za pomocą funkcji __destruct(). Możesz zwolnić wszystkie zasoby za pomocą destruktora.
Dziedzictwo
Definicje klas PHP mogą opcjonalnie dziedziczyć z definicji klasy nadrzędnej przy użyciu klauzuli extends. Składnia jest następująca -
class Child extends Parent {
<definition body>
}
Efektem dziedziczenia jest to, że klasa potomna (lub podklasa lub klasa pochodna) ma następujące cechy -
Automatycznie zawiera wszystkie deklaracje zmiennych składowych klasy nadrzędnej.
Automatycznie ma wszystkie te same funkcje składowe co element nadrzędny, które (domyślnie) będą działać w taki sam sposób, jak te funkcje w rodzicu.
Poniższy przykład dziedziczy klasę Books i dodaje więcej funkcji w oparciu o wymagania.
class Novel extends Books {
var $publisher;
function setPublisher($par){
$this->publisher = $par;
}
function getPublisher(){
echo $this->publisher. "<br />";
}
}
Obecnie, oprócz funkcji dziedziczonych, klasa Novel zachowuje dwie dodatkowe funkcje składowe.
Funkcja zastępująca
Definicje funkcji w klasach podrzędnych zastępują definicje o tej samej nazwie w klasach nadrzędnych. W klasie potomnej możemy zmodyfikować definicję funkcji dziedziczonej z klasy nadrzędnej.
W poniższym przykładzie funkcje getPrice i getTitle są zastępowane w celu zwrócenia niektórych wartości.
function getPrice() {
echo $this->price . "<br/>";
return $this->price;
}
function getTitle(){
echo $this->title . "<br/>";
return $this->title;
}
Członkowie publiczni
O ile nie określisz inaczej, właściwości i metody klasy są publiczne. Oznacza to, że można uzyskać do nich dostęp w trzech możliwych sytuacjach -
Spoza klasy, w której jest zadeklarowany
Z klasy, w której jest zadeklarowany
Z innej klasy, która implementuje klasę, w której jest zadeklarowana
Do tej pory widzieliśmy wszystkich członków jako członków publicznych. Jeśli chcesz ograniczyć dostępność członków klasy, określ członków klasy jakoprivate lub protected.
Członkowie prywatni
Wyznaczając członka jako prywatny, ograniczasz jego dostępność do klasy, w której jest zadeklarowany. Do prywatnego elementu członkowskiego nie można odwoływać się z klas, które dziedziczą klasę, w której jest zadeklarowany, i nie można uzyskać do niego dostępu spoza klasy.
Członek klasy można ustawić jako prywatny przy użyciu private słowo kluczowe przed członkiem.
class MyClass {
private $car = "skoda";
$driver = "SRK";
function __construct($par) {
// Statements here run every time
// an instance of the class
// is created.
}
function myPublicFunction() {
return("I'm visible!");
}
private function myPrivateFunction() {
return("I'm not visible outside!");
}
}
Gdy klasa MyClass jest dziedziczona przez inną klasę przy użyciu extends, widoczna będzie myPublicFunction (), podobnie jak $ driver. Klasa rozszerzająca nie będzie miała żadnych informacji o myPrivateFunction i $ car ani dostępu do nich, ponieważ są one zadeklarowane jako prywatne.
Chronieni członkowie
Chroniona właściwość lub metoda jest dostępna w klasie, w której jest zadeklarowana, a także w klasach rozszerzających tę klasę. Chronieni członkowie nie są dostępni poza tymi dwoma rodzajami klas. Element klasy można zabezpieczyć za pomocąprotected słowo kluczowe przed członkiem.
Oto inna wersja MyClass -
class MyClass {
protected $car = "skoda";
$driver = "SRK";
function __construct($par) {
// Statements here run every time
// an instance of the class
// is created.
}
function myPublicFunction() {
return("I'm visible!");
}
protected function myPrivateFunction() {
return("I'm visible in child class!");
}
}
Interfejsy
Interfejsy są zdefiniowane, aby zapewnić implementującym wspólne nazwy funkcji. Różne firmy wdrażające mogą implementować te interfejsy zgodnie ze swoimi wymaganiami. Można powiedzieć, że interfejsy to szkielety zaimplementowane przez programistów.
Od PHP5 można zdefiniować interfejs, taki jak ten -
interface Mail {
public function sendMail();
}
Następnie, jeśli inna klasa zaimplementowała ten interfejs, taki jak ten -
class Report implements Mail {
// sendMail() Definition goes here
}
Stałe
Stała jest nieco podobna do zmiennej, ponieważ zawiera wartość, ale bardziej przypomina funkcję, ponieważ stała jest niezmienna. Kiedy zadeklarujesz stałą, to się nie zmienia.
Zadeklarowanie jednej stałej jest łatwe, tak jak w tej wersji MyClass -
class MyClass {
const requiredMargin = 1.7;
function __construct($incomingValue) {
// Statements here run every time
// an instance of the class
// is created.
}
}
W tej klasie requiredMargin jest stałą. Jest deklarowany za pomocą słowa kluczowego const i pod żadnym pozorem nie można go zmienić na cokolwiek innego niż 1.7. Zauważ, że nazwa stałej nie ma na początku znaku $, jak to ma miejsce w przypadku nazw zmiennych.
Klasy abstrakcyjne
Klasa abstrakcyjna to taka, której nie można utworzyć, a jedynie dziedziczyć. Deklarujesz klasę abstrakcyjną za pomocą słowa kluczowegoabstractw ten sposób -
Podczas dziedziczenia z klasy abstrakcyjnej wszystkie metody oznaczone jako abstrakcyjne w deklaracji klasy rodzica muszą być zdefiniowane przez dziecko; dodatkowo metody te muszą być zdefiniowane z taką samą widocznością.
abstract class MyAbstractClass {
abstract function myAbstractFunction() {
}
}
Należy zauważyć, że definicje funkcji wewnątrz klasy abstrakcyjnej również muszą być poprzedzone słowem kluczowym abstract. Niedozwolone jest posiadanie abstrakcyjnych definicji funkcji w klasie nieabstrakcyjnej.
Statyczne słowo kluczowe
Zadeklarowanie elementów członkowskich lub metod klas jako statycznych sprawia, że są one dostępne bez konieczności tworzenia wystąpienia klasy. Do elementu członkowskiego zadeklarowanego jako statyczny nie można uzyskać dostępu za pomocą utworzonego obiektu klasy (chociaż metoda statyczna może).
Wypróbuj następujący przykład -
<?php
class Foo {
public static $my_static = 'foo';
public function staticValue() {
return self::$my_static;
}
}
print Foo::$my_static . "\n";
$foo = new Foo();
print $foo->staticValue() . "\n";
?>
Ostatnie słowo kluczowe
PHP 5 wprowadza słowo kluczowe final, które zapobiega nadpisywaniu metody przez klasy potomne poprzez poprzedzanie definicji przedrostkiem final. Jeśli sama klasa jest definiowana jako ostateczna, nie można jej rozszerzyć.
Poniższy przykład powoduje błąd krytyczny: Nie można zastąpić ostatecznej metody BaseClass :: moreTesting ()
<?php
class BaseClass {
public function test() {
echo "BaseClass::test() called<br>";
}
final public function moreTesting() {
echo "BaseClass::moreTesting() called<br>";
}
}
class ChildClass extends BaseClass {
public function moreTesting() {
echo "ChildClass::moreTesting() called<br>";
}
}
?>
Wywołanie konstruktorów nadrzędnych
Zamiast pisać zupełnie nowy konstruktor dla podklasy, napiszmy go, jawnie wywołując konstruktor rodzica, a następnie robiąc wszystko, co jest konieczne do utworzenia instancji podklasy. Oto prosty przykład -
class Name {
var $_firstName;
var $_lastName;
function Name($first_name, $last_name) {
$this->_firstName = $first_name;
$this->_lastName = $last_name;
}
function toString() {
return($this->_lastName .", " .$this->_firstName);
}
}
class NameSub1 extends Name {
var $_middleInitial;
function NameSub1($first_name, $middle_initial, $last_name) {
Name::Name($first_name, $last_name);
$this->_middleInitial = $middle_initial;
}
function toString() {
return(Name::toString() . " " . $this->_middleInitial);
}
}
W tym przykładzie mamy klasę nadrzędną (Name), która ma konstruktor z dwoma argumentami i podklasę (NameSub1), która ma konstruktor z trzema argumentami. Konstruktor NameSub1 działa, wywołując konstruktor nadrzędny jawnie przy użyciu składni :: (przekazując dwa argumenty), a następnie ustawiając dodatkowe pole. Podobnie NameSub1 definiuje swoją funkcję niebędącą konstruktorem toString () w odniesieniu do funkcji nadrzędnej, którą zastępuje.
NOTE- Można zdefiniować konstruktora o takiej samej nazwie, jak nazwa klasy. Jest to zdefiniowane w powyższym przykładzie.