Lập trình hướng đối tượng trong PHP

Chúng ta có thể tưởng tượng vũ trụ của chúng ta được làm từ các vật thể khác nhau như mặt trời, trái đất, mặt trăng, v.v. Tương tự, chúng ta có thể tưởng tượng chiếc xe của chúng ta được làm từ các vật thể khác nhau như bánh xe, tay lái, bánh răng, v.v. Tương tự như vậy, có các khái niệm lập trình hướng đối tượng giả định mọi thứ như một đối tượng và triển khai một phần mềm sử dụng các đối tượng khác nhau.

Các khái niệm hướng đối tượng

Trước khi đi vào chi tiết, hãy xác định các thuật ngữ quan trọng liên quan đến Lập trình hướng đối tượng.

  • Class- Đây là kiểu dữ liệu do người lập trình xác định, bao gồm các hàm cục bộ cũng như dữ liệu cục bộ. Bạn có thể coi một lớp như một khuôn mẫu để tạo ra nhiều thể hiện của cùng một loại (hoặc lớp) đối tượng.

  • Object- Một thể hiện riêng lẻ của cấu trúc dữ liệu được xác định bởi một lớp. Bạn xác định một lớp một lần và sau đó tạo nhiều đối tượng thuộc về nó. Đối tượng còn được gọi là thể hiện.

  • Member Variable- Đây là các biến được định nghĩa bên trong một lớp. Dữ liệu này sẽ vô hình đối với bên ngoài lớp và có thể được truy cập thông qua các hàm thành viên. Các biến này được gọi là thuộc tính của đối tượng khi một đối tượng được tạo.

  • Member function - Đây là những hàm được định nghĩa bên trong một lớp và được sử dụng để truy cập dữ liệu đối tượng.

  • Inheritance- Khi một lớp được định nghĩa bằng cách kế thừa chức năng hiện có của một lớp cha thì nó được gọi là kế thừa. Ở đây lớp con sẽ kế thừa tất cả hoặc một vài hàm thành viên và các biến của một lớp cha.

  • Parent class- Một lớp được kế thừa từ lớp khác. Đây còn được gọi là lớp cơ sở hoặc siêu lớp.

  • Child Class- Một lớp kế thừa từ một lớp khác. Đây còn được gọi là lớp con hoặc lớp dẫn xuất.

  • Polymorphism- Đây là một khái niệm hướng đối tượng trong đó cùng một chức năng có thể được sử dụng cho các mục đích khác nhau. Ví dụ: tên hàm sẽ giữ nguyên nhưng nó có số lượng đối số khác nhau và có thể thực hiện các tác vụ khác nhau.

  • Overloading- một kiểu đa hình trong đó một số hoặc tất cả các toán tử có cách triển khai khác nhau tùy thuộc vào kiểu đối số của chúng. Tương tự, các chức năng cũng có thể được nạp chồng với các cách triển khai khác nhau.

  • Data Abstraction - Bất kỳ biểu diễn dữ liệu nào trong đó các chi tiết triển khai được ẩn (trừu tượng hóa).

  • Encapsulation - đề cập đến một khái niệm trong đó chúng ta đóng gói tất cả dữ liệu và các hàm thành viên lại với nhau để tạo thành một đối tượng.

  • Constructor - đề cập đến một loại hàm đặc biệt sẽ được gọi tự động bất cứ khi nào có sự hình thành đối tượng từ một lớp.

  • Destructor - đề cập đến một loại chức năng đặc biệt sẽ được gọi tự động bất cứ khi nào một đối tượng bị xóa hoặc ra khỏi phạm vi.

Định nghĩa các lớp PHP

Hình thức chung để xác định một lớp mới trong PHP như sau:

<?php
   class phpClass {
      var $var1;
      var $var2 = "constant string";
      
      function myfunc ($arg1, $arg2) {
         [..]
      }
      [..]
   }
?>

Đây là mô tả của từng dòng -

  • Hình thức đặc biệt class, theo sau là tên của lớp mà bạn muốn xác định.

  • Một tập hợp các dấu ngoặc nhọn bao quanh bất kỳ số lượng khai báo biến và định nghĩa hàm nào.

  • Khai báo biến bắt đầu bằng biểu mẫu đặc biệt var, theo sau là một tên biến $ thông thường; chúng cũng có thể có một phép gán ban đầu cho một giá trị không đổi.

  • Các định nghĩa hàm trông giống như các hàm PHP độc lập nhưng là cục bộ của lớp và sẽ được sử dụng để thiết lập và truy cập dữ liệu đối tượng.

Thí dụ

Đây là một ví dụ xác định một loại loại Sách -

<?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/>";
      }
   }
?>

Biến $thislà một biến đặc biệt và nó tham chiếu đến cùng một đối tượng tức là. chinh no.

Tạo các đối tượng trong PHP

Khi bạn đã xác định lớp của mình, thì bạn có thể tạo bao nhiêu đối tượng tùy thích của loại lớp đó. Sau đây là một ví dụ về cách tạo đối tượng bằng cách sử dụngnew nhà điều hành.

$physics = new Books;
$maths = new Books;
$chemistry = new Books;

Ở đây chúng ta đã tạo ra ba đối tượng và những đối tượng này độc lập với nhau và chúng sẽ có sự tồn tại riêng biệt. Tiếp theo chúng ta sẽ xem cách truy cập hàm thành viên và xử lý các biến thành viên.

Gọi cho các chức năng thành viên

Sau khi tạo các đối tượng của mình, bạn sẽ có thể gọi các hàm thành viên liên quan đến đối tượng đó. Một hàm thành viên sẽ chỉ có thể xử lý biến thành viên của đối tượng liên quan.

Ví dụ sau đây cho thấy cách đặt tiêu đề và giá cho ba cuốn sách bằng cách gọi các hàm thành viên.

$physics->setTitle( "Physics for High School" );
$chemistry->setTitle( "Advanced Chemistry" );
$maths->setTitle( "Algebra" );

$physics->setPrice( 10 );
$chemistry->setPrice( 15 );
$maths->setPrice( 7 );

Bây giờ bạn gọi các hàm thành viên khác để nhận các giá trị được đặt trong ví dụ trên -

$physics->getTitle();
$chemistry->getTitle();
$maths->getTitle();
$physics->getPrice();
$chemistry->getPrice();
$maths->getPrice();

Điều này sẽ tạo ra kết quả sau:

Physics for High School
Advanced Chemistry
Algebra
10
15
7

Hàm tạo

Hàm Constructor là loại hàm đặc biệt được gọi tự động bất cứ khi nào một đối tượng được tạo. Vì vậy, chúng tôi tận dụng tối đa hành vi này, bằng cách khởi tạo nhiều thứ thông qua các hàm khởi tạo.

PHP cung cấp một hàm đặc biệt được gọi là __construct()để xác định một phương thức khởi tạo. Bạn có thể truyền bao nhiêu đối số tùy thích vào hàm khởi tạo.

Ví dụ sau sẽ tạo một phương thức khởi tạo cho lớp Books và nó sẽ khởi tạo giá và tiêu đề cho sách tại thời điểm tạo đối tượng.

function __construct( $par1, $par2 ) {
   $this->title = $par1;
   $this->price = $par2;
}

Bây giờ chúng ta không cần gọi hàm set riêng để đặt giá và tiêu đề. Chúng ta chỉ có thể khởi tạo hai biến thành viên này tại thời điểm tạo đối tượng. Kiểm tra ví dụ sau dưới đây -

$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();

Điều này sẽ tạo ra kết quả sau:

Physics for High School
  Advanced Chemistry
  Algebra
  10
  15
  7

Kẻ hủy diệt

Giống như một hàm khởi tạo, bạn có thể xác định một hàm hủy bằng hàm __destruct(). Bạn có thể giải phóng tất cả các tài nguyên với một trình hủy.

Di sản

Các định nghĩa lớp trong PHP có thể thừa kế tùy chọn từ một định nghĩa lớp cha bằng cách sử dụng mệnh đề expand. Cú pháp như sau:

class Child extends Parent {
   <definition body>
}

Hiệu quả của kế thừa là lớp con (hoặc lớp con hoặc lớp dẫn xuất) có các đặc điểm sau:

  • Tự động có tất cả các khai báo biến thành viên của lớp cha.

  • Tự động có tất cả các hàm thành viên giống như hàm mẹ, (theo mặc định) sẽ hoạt động giống như các hàm đó hoạt động trong hàm mẹ.

Ví dụ sau kế thừa lớp Sách và thêm nhiều chức năng hơn dựa trên yêu cầu.

class Novel extends Books {
   var $publisher;
   
   function setPublisher($par){
      $this->publisher = $par;
   }
   
   function getPublisher(){
      echo $this->publisher. "<br />";
   }
}

Bây giờ ngoài các hàm kế thừa, Class Novel giữ hai hàm thành viên bổ sung.

Ghi đè chức năng

Các định nghĩa hàm trong các lớp con ghi đè các định nghĩa có cùng tên trong các lớp cha. Trong một lớp con, chúng ta có thể sửa đổi định nghĩa của một hàm được kế thừa từ lớp cha.

Trong ví dụ sau, các hàm getPrice và getTitle được ghi đè để trả về một số giá trị.

function getPrice() {
   echo $this->price . "<br/>";
   return $this->price;
}
   
function getTitle(){
   echo $this->title . "<br/>";
   return $this->title;
}

Thành viên công khai

Trừ khi bạn chỉ định khác, các thuộc tính và phương thức của một lớp là công khai. Có nghĩa là, chúng có thể được truy cập trong ba tình huống có thể xảy ra -

  • Từ bên ngoài lớp mà nó được khai báo

  • Từ bên trong lớp mà nó được khai báo

  • Từ bên trong một lớp khác triển khai lớp mà nó được khai báo

Cho đến bây giờ chúng tôi đã xem tất cả các thành viên là thành viên công khai. Nếu bạn muốn giới hạn khả năng truy cập của các thành viên của một lớp thì bạn xác định các thành viên của lớp làprivate hoặc là protected.

Thành viên tư nhân

Bằng cách chỉ định một thành viên là private, bạn giới hạn khả năng truy cập của nó đối với lớp mà nó được khai báo. Thành viên private không thể được tham chiếu đến từ các lớp kế thừa lớp mà nó được khai báo và không thể được truy cập từ bên ngoài lớp.

Một thành viên trong lớp có thể được đặt ở chế độ riêng tư bằng cách sử dụng private từ khóa trước của thành viên.

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!");
   }
}

Khi lớp MyClass được kế thừa bởi một lớp khác bằng cách sử dụng extension, myPublicFunction () sẽ hiển thị, cũng như $ driver. Lớp mở rộng sẽ không có bất kỳ nhận thức nào về hoặc quyền truy cập vào myPrivateFunction và $ car, vì chúng được khai báo là riêng tư.

Thành viên được bảo vệ

Một thuộc tính hoặc phương thức được bảo vệ có thể truy cập được trong lớp mà nó được khai báo, cũng như trong các lớp mở rộng lớp đó. Thành viên được bảo vệ không có sẵn bên ngoài hai loại lớp đó. Một thành viên trong lớp có thể được bảo vệ bằng cách sử dụngprotected từ khóa trước thành viên.

Đây là phiên bản MyClass khác -

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!");
   }
}

Giao diện

Các giao diện được định nghĩa để cung cấp tên hàm chung cho người triển khai. Các nhà triển khai khác nhau có thể triển khai các giao diện đó theo yêu cầu của họ. Bạn có thể nói, giao diện là bộ xương được thực hiện bởi các nhà phát triển.

Đối với PHP5, có thể xác định một giao diện, như thế này -

interface Mail {
   public function sendMail();
}

Sau đó, nếu một lớp khác triển khai giao diện đó, như thế này -

class Report implements Mail {
   // sendMail() Definition goes here
}

Hằng số

Một hằng số hơi giống một biến, ở chỗ nó giữ một giá trị, nhưng thực sự giống một hàm hơn vì một hằng số là bất biến. Khi bạn khai báo một hằng số, nó không thay đổi.

Khai báo một hằng số rất dễ dàng, như được thực hiện trong phiên bản MyClass này -

class MyClass {
   const requiredMargin = 1.7;
   
   function __construct($incomingValue) {
      // Statements here run every time
      // an instance of the class
      // is created.
   }
}

Trong lớp này, RequiredMargin là một hằng số. Nó được khai báo với từ khóa const, và trong mọi trường hợp, nó không thể được thay đổi thành bất kỳ thứ gì khác ngoài 1.7. Lưu ý rằng tên của hằng không có $ đứng đầu, như tên biến.

Các lớp trừu tượng

Một lớp trừu tượng là một lớp không thể được khởi tạo, chỉ được kế thừa. Bạn khai báo một lớp trừu tượng với từ khóaabstract, như thế này -

Khi kế thừa từ một lớp trừu tượng, tất cả các phương thức được đánh dấu là trừu tượng trong khai báo lớp của cha phải được định nghĩa bởi con; ngoài ra, các phương thức này phải được xác định với cùng một khả năng hiển thị.

abstract class MyAbstractClass {
   abstract function myAbstractFunction() {
   }
}

Lưu ý rằng các định nghĩa hàm bên trong một lớp trừu tượng cũng phải được đặt trước từ khóa trừu tượng. Không hợp pháp khi có các định nghĩa hàm trừu tượng bên trong một lớp không trừu tượng.

Từ khóa tĩnh

Khai báo các thành viên hoặc phương thức của lớp dưới dạng tĩnh làm cho chúng có thể truy cập được mà không cần khởi tạo lớp. Một thành viên được khai báo là tĩnh không thể được truy cập bằng một đối tượng lớp khởi tạo (mặc dù một phương thức tĩnh có thể).

Hãy thử ví dụ sau -

<?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";
?>

Từ khóa cuối cùng

PHP 5 giới thiệu từ khóa cuối cùng, từ khóa này ngăn các lớp con ghi đè một phương thức bằng cách đặt tiền tố định nghĩa bằng final. Nếu bản thân lớp đang được định nghĩa cuối cùng thì nó không thể được mở rộng.

Ví dụ sau dẫn đến lỗi nghiêm trọng: Không thể ghi đè phương thức cuối cùng 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>";
      }
   }
?>

Gọi hàm tạo cha

Thay vì viết một phương thức khởi tạo hoàn toàn mới cho lớp con, hãy viết nó bằng cách gọi phương thức khởi tạo cha một cách rõ ràng và sau đó thực hiện bất cứ điều gì cần thiết để bổ sung cho lớp con. Đây là một ví dụ đơn giản -

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);
   }
}

Trong ví dụ này, chúng ta có một lớp cha (Name), có một hàm tạo hai đối số và một lớp con (NameSub1), có một hàm tạo ba đối số. Hàm tạo của NameSub1 hoạt động bằng cách gọi hàm tạo mẹ của nó một cách rõ ràng bằng cú pháp :: (truyền hai đối số của nó dọc theo) và sau đó thiết lập một trường bổ sung. Tương tự, NameSub1 định nghĩa hàm toString () không phải là phương thức khởi tạo của nó về mặt hàm cha mà nó ghi đè.

NOTE- Một hàm tạo có thể được định nghĩa trùng tên với tên của một lớp. Nó được định nghĩa trong ví dụ trên.