Hướng dẫn class in php

Vietnamese (Tiếng Việt) translation by Andrea Ho (you can also view the original English article)

Trong bài viết này, chúng ta sẽ tìm hiểu những điều cơ bản về lập trình hướng object trong PHP. Chúng ta sẽ bắt đầu với phần giới thiệu về các class và object và chúng ta sẽ thảo luận về một số khái niệm nâng cao như tính kế thừa và tính đa hình trong nửa sau của bài viết này.

Lập trình hướng đối tượng (OOP) là gì?

Lập trình hướng đối tượng, thường được gọi là OOP, một cách tiếp cận giúp bạn phát triển các ứng dụng phức tạp theo cách dễ dàng duy trì và có thể mở rộng trong thời gian dài. Trong thế giới của OOP, các thực thể trong thế giới thực như Person, Car hoặc Animal được coi là object (đối tượng). Trong lập trình hướng đối tượng, bạn tương tác với ứng dụng của mình bằng cách sử dụng các object. Điều này trái ngược với lập trình thủ tục (procedural), nơi bạn chủ yếu tương tác với các hàm và biến toàn cục.

Trong OOP, có khái niệm về "class", được sử dụng để mô hình hóa hoặc ánh xạ một thực thể trong thế giới thực sang một template dữ liệu (properties - các thuộc tính) và chức năng (methods - các phương thức). Một "object" là giá trị của một class và bạn có thể tạo nhiều giá trị của cùng một class. Ví dụ: có một class đơn lẻ Person, nhưng nhiều object person có thể là các giá trị của class này - dan, zainab, hector, v.v

Class định nghĩa các thuộc tính - property. Ví dụ: đối với class Person, chúng ta có thể có name, agephoneNumber. Sau đó, mỗi object person sẽ có giá trị riêng cho các thuộc tính đó.

Bạn cũng có thể định nghĩa các phương thức trong class cho phép bạn thao tác các giá trị của các thuộc tính object và thực hiện các thao tác trên các object. Ví dụ, bạn có thể định nghĩa một phương thức save để lưu thông tin object vào cơ sở dữ liệu.

Class trong PHP là gì?

Một class là một khuôn mẫu đại diện cho một thực thể trong thế giới thực và nó định nghĩa các thuộc tính và phương thức của thực thể. Trong phần này, chúng tôi sẽ thảo luận về khung cơ bản một class PHP điển hình.

Cách tốt nhất để hiểu các khái niệm mới là qua ví dụ. Vì vậy, hãy xem class Employee trong snippet sau, đại diện cho thực thể employee.

first_name = $first_name;
    $this->last_name = $last_name;
    $this->age = $age;
  }

  public function getFirstName()
  {
    return $this->first_name;
  }

  public function getLastName()
  {
    return $this->last_name;
  }

  public function getAge()
  {
    return $this->age;
  }
}
?>

Câu lệnh class Employee trong dòng đầu tiên định nghĩa class Employee. Sau đó, chúng ta tiếp tục khai báo các thuộc tính, hàm constructor và các phương thức class khác.

Thuộc tính class trong PHP

Bạn có thể nghĩ các thuộc tính của class là các biến được sử dụng để chứa thông tin về object. Trong ví dụ trên, chúng tôi đã xác định ba thuộc tính của - first_name, last_nameage. Trong đa số các trường hợp, các thuộc tính của class được truy xuất thông qua các object được khởi tạo.

Các thuộc tính này là private, có nghĩa là chúng chỉ có thể được truy xuất từ bên trong class. Đây là mức truy xuất an toàn nhất cho các thuộc tính. Chúng tôi sẽ thảo luận về các cấp truy xuất khác nhau cho các thuộc tính và phương thức của class sau trong bài viết này.

Constructor cho các class PHP

Hàm constructor là một phương thức class đặc biệt tự động được gọi khi bạn khởi tạo một object. Chúng ta sẽ xem xét cách khởi tạo các object trong vài phần tiếp theo, nhưng bây giờ bạn chỉ cần biết rằng một hàm constructor được sử dụng để khởi tạo các thuộc tính object khi object được tạo ra.

Bạn có thể xác định hàm constructor bằng cách định nghĩa phương thức __construct.

Các phương thức cho các class PHP

Chúng ta có thể nghĩ về các phương thức của class là các hàm thực hiện các hành động cụ thể được liên kết với các object. Trong hầu hết các trường hợp, chúng được sử dụng để truy xuất và thao tác các thuộc tính object và thực hiện các hoạt động liên quan.

Trong ví dụ trên, chúng tôi đã xác định phương thức getLastName, nó trả về last name được liên kết với object.

Vì vậy, một giới thiệu ngắn gọn về cấu trúc class trong PHP. Trong phần tiếp theo, chúng tôi sẽ xem cách khởi tạo các object của class Employee.

Một object trong PHP là gì?

Trong phần trước, chúng ta đã thảo luận về cấu trúc cơ bản của một class trong PHP. Bây giờ, khi bạn muốn sử dụng một class, bạn cần khởi tạo nó và kết quả cuối cùng là một object. Vì vậy, chúng ta có thể nghĩ về một class như một bản thiết kế và một object là một thứ thực tế mà bạn có thể làm việc với.

Trong ngữ cảnh của class Employee mà chúng ta vừa tạo trong phần trước, hãy xem cách khởi tạo một object của class đó.

getFirstName(); // print 'Bob'
echo $objEmployee->getLastName(); // prints 'Smith'
echo $objEmployee->getAge(); // prints '30'
?>

Bạn cần sử dụng từ khóa new khi bạn muốn khởi tạo một object của bất kỳ class nào cùng với tên class của nó và bạn sẽ nhận lại một giá trị object mới của class đó.

Nếu một class đã định nghĩa phương thức __construct và nó yêu cầu các đối số, bạn cần truyền các đối số đó khi bạn khởi tạo một object. Trong trường hợp của chúng tôi, hàm constructor của class Employee yêu cầu ba đối số và do đó chúng tôi đã vượt qua những đối số này khi chúng tôi tạo object $objEmployee. Như chúng ta đã thảo luận trước đó, phương thức __construct được gọi tự động khi object được khởi tạo.

Tiếp theo, chúng tôi đã gọi các phương thức class trên object $objEmployee để in thông tin được khởi tạo trong quá trình tạo object. Tất nhiên, bạn có thể tạo nhiều object của cùng một class, như được hiển thị trong đoạn code sau.

getFirstName(); // prints 'Bob'
echo $objEmployeeOne->getLastName(); // prints 'Smith'
echo $objEmployeeOne->getAge(); // prints '30'

$objEmployeeTwo = new Employee('John', 'Smith', 34);

echo $objEmployeeTwo->getFirstName(); // prints 'John'
echo $objEmployeeTwo->getLastName(); // prints 'Smith'
echo $objEmployeeTwo->getAge(); // prints '34'
?>

Hình ảnh sau đây là biểu diễn hình ảnh của class Employee và một số trường hợp của nó.

Hướng dẫn class in php
Hướng dẫn class in php
Hướng dẫn class in php

Nói một cách đơn giản, một class là một bản thiết kế mà bạn có thể sử dụng để tạo các object có cấu trúc.

Encapsulation (tính đóng gói)

Trong phần trước, chúng ta đã thảo luận về cách khởi tạo các object của class Employee. Thật thú vị khi lưu ý rằng chính object $objEmployee kết hợp các thuộc tính và phương thức của class. Nói cách khác, object này ẩn đi những chi tiết đó từ phần còn lại của chương trình. Trong thế giới OOP, điều này được gọi là encapsulation (đóng gói dữ liệu).

Đóng gói là một khía cạnh quan trọng của OOP cho phép bạn hạn chế quyền truy xuất vào các thuộc tính hoặc phương thức nhất định của object. Và điều đó đưa chúng ta đến một chủ đề khác để thảo luận: access level - mức độ truy xuất.

Access Levels (mức độ truy xuất)

Khi bạn định nghĩa một thuộc tính hoặc một phương thức trong một class, bạn có thể khai báo nó có một trong ba cấp truy xuất này, public, private hoặc protected.

Public Access

Khi bạn khai báo một thuộc tính hoặc một phương thức là public, nó có thể được truy xuất từ bất cứ đâu bên ngoài class. Giá trị của một thuộc tính public có thể được sửa đổi từ bất cứ nơi nào trong code của bạn.

Hãy xem xét một ví dụ để hiểu mức độ truy xuất public.

name;
  }
}

$person = new Person();
$person->name = 'Bob Smith';
echo $person->getName(); // prints 'Bob Smith'
?>

Như bạn có thể thấy trong ví dụ trên, chúng tôi đã khai báo thuộc tính name là public. Do đó, bạn có thể đặt nó từ bất kỳ đâu ngoài class, như đã thực hiện ở đây.

Private Access

Khi bạn khai báo một thuộc tính hoặc một phương thức là private, nó chỉ có thể được truy xuất từ bên trong class. Điều này có nghĩa là bạn cần xác định các phương thức getter và setter để lấy và xét giá trị của thuộc tính đó.

Một lần nữa, hãy xem lại ví dụ trước để hiểu mức độ truy xuất riêng.

name;
  }

  public function setName($name)
  {
    $this->name = $name;
  }
}

$person = new Person();
$person->name = 'Bob Smith'; // Throws an error
$person->setName('Bob Smith');
echo $person->getName(); // prints 'Bob Smith'
?>

Nếu bạn thử truy xuất một tài sản private bên ngoài class, nó sẽ gây ra lỗi nghiêm trọng Cannot access private property Person::$name. Vì vậy, bạn cần xét giá trị của thuộc tính private bằng phương thức setter, như chúng ta đã sử dụng phương thức setName.

Có nhiều lý do giải thích bạn có thể muốn làm cho một tài sản private. Ví dụ, có lẽ nên thực hiện một số hành động (cập nhật cơ sở dữ liệu, giả sử hoặc hiển thị lại một template) nếu thuộc tính đó thay đổi. Trong trường hợp đó, bạn có thể định nghĩa một phương thức setter và xử lý bất kỳ logic đặc biệt nào khi thuộc tính được thay đổi.

Protected Access

Cuối cùng, khi bạn khai báo một thuộc tính hoặc một phương thức là protected, nó có thể được truy xuất bởi cùng một class đã định nghĩa nó và các class kế thừa class. Chúng ta sẽ thảo luận về kế thừa trong phần tiếp theo, vì vậy chúng ta sẽ quay lại cấp độ truy xuất protected sau đó.

Inheritance - kế thừa

Inheritance là một khía cạnh quan trọng của mô hình lập trình hướng đối tượng, cho phép bạn kế thừa các thuộc tính và phương thức của các class khác bằng cách mở rộng chúng. Lớp được kế thừa được gọi là parent class và class kế thừa class khác được gọi là child class. Khi bạn khởi tạo một object của child class, nó cũng thừa hưởng các thuộc tính và phương thức của parent class.

Chúng ta hãy nhìn vào ảnh chụp màn hình sau đây để hiểu khái niệm inheritance

Hướng dẫn class in php
Hướng dẫn class in php
Hướng dẫn class in php

Trong ví dụ trên, class Person là parent class và class Employee mở rộng hoặc kế thừa class Person và do đó được gọi là child class.

Chúng ta hãy thử xem xét một ví dụ thực tế để hiểu cách thức hoạt động của nó.

name;
  }

  public function setName($name)
  {
    $this->name = $name;
  }

  private function callToPrivateNameAndAge()
  {
    return "{$this->name} is {$this->age} years old.";
  }

  protected function callToProtectedNameAndAge()
  {
    return "{$this->name} is {$this->age} years old.";
  }
}

class Employee extends Person
{
  private $designation;
  private $salary;

  public function getAge()
  {
    return $this->age;
  }

  public function setAge($age)
  {
    $this->age = $age;
  }

  public function getDesignation()
  {
    return $this->designation;
  }

  public function setDesignation($designation)
  {
    $this->designation = $designation;
  }

  public function getSalary()
  {
    return $this->salary;
  }

  public function setSalary($salary)
  {
    $this->salary = $salary;
  }

  public function getNameAndAge()
  {
    return $this->callToProtectedNameAndAge();
  }
}

$employee = new Employee();

$employee->setName('Bob Smith');
$employee->setAge(30);
$employee->setDesignation('Software Engineer');
$employee->setSalary('30K');

echo $employee->getName(); // prints 'Bob Smith'
echo $employee->getAge(); // prints '30'
echo $employee->getDesignation(); // prints 'Software Engineer'
echo $employee->getSalary(); // prints '30K'
echo $employee->getNameAndAge(); // prints 'Bob Smith is 30 years old.'
echo $employee->callToPrivateNameAndAge(); // produces 'Fatal Error'
?>

Điều quan trọng cần lưu ý ở đây là class Employee đã sử dụng từ khóa extends để kế thừa class Person. Bây giờ, class Employee có thể truy xuất tất cả các thuộc tính và phương thức của class Person được khai báo là public hoặc protected. (Nó không thể truy xuất các thành viên được khai báo là private).

Trong ví dụ trên, object $employee có thể truy xuất các phương thức getNamesetName được định nghĩa trong class Person khi được khai báo là public.

Tiếp theo, chúng tôi đã truy xuất phương thức callToProtectedNameAndAge bằng phương thức getNameAndAge được xác định trong class Employee, vì nó được khai báo là protected. Cuối cùng, object $employee không thể truy xuất phương thức callToPrivateNameAndAge của class Person vì nó được khai báo là private.

Mặt khác, bạn có thể sử dụng object $employee để đặt thuộc tính age của class Person, như chúng ta đã làm trong phương thức setAge được định nghĩa trong class Employee, vì thuộc tính age được khai báo là được bảo vệ.

Vì vậy, đó là một giới thiệu ngắn gọn về thừa kế. Nó giúp bạn giảm trùng lặp code, và do đó khuyến khích khả năng sử dụng lại code.

Polymorphism

Polymorphism là một khái niệm quan trọng khác trong thế giới lập trình hướng đối tượng, đề cập đến khả năng xử lý các object khác nhau dựa trên các loại dữ liệu của chúng.

Ví dụ, trong tình hướng thừa kế, nếu child class muốn thay đổi hành vi của phương thức của parent class, nó có thể override phương thức đó. Đây được gọi là phương thức override. Hãy nhanh chóng xem qua một ví dụ thực tế để hiểu khái niệm về phương thức override.

%s", $message);
  }
}

class BoldMessage extends Message
{
  public function formatMessage($message)
  {
    return printf("%s", $message);
  }
}

$message = new Message();
$message->formatMessage('Hello World'); // prints 'Hello World'

$message = new BoldMessage();
$message->formatMessage('Hello World'); // prints 'Hello World'
?>

Như bạn có thể thấy, chúng tôi đã thay đổi hành vi của phương thức formatMessage bằng cách override nó trong class BoldMessage. Điều quan trọng là một thông điệp được định dạng khác nhau dựa trên loại object, cho dù đó là một giá trị của parent class hay child class.

(Một số ngôn ngữ hướng đối tượng cũng có một kiểu overload phương thức cho phép bạn định nghĩa nhiều phương thức của class có cùng tên nhưng số lượng đối số khác nhau. Điều này không được hỗ trợ trực tiếp trong PHP, nhưng có một số cách giải quyết để đạt được chức năng tương tự).

Tổng kết

Lập trình hướng đối tượng là một chủ đề lớn và chúng ta chỉ ra mặt nổi của sự phức tạp của nó. Tôi hy vọng rằng hướng dẫn này đã giúp bạn bắt đầu với những điều cơ bản của OOP và thúc đẩy bạn tiếp tục và tìm hiểu các chủ đề OOP nâng cao hơn.

Lập trình hướng đối hướng là một khía cạnh quan trọng trong phát triển ứng dụng, bất kể bạn đang làm việc với công nghệ nào. Hôm nay, trong ngữ cảnh của PHP, chúng ta đã thảo luận một vài khái niệm cơ bản về OOP và cũng nhân cơ hội này để giới thiệu vài ví dụ thực tế.

Hãy gửi câu hỏi của bạn thông qua feed bên dưới