Series Lập trình hướng đối tượng trong PHP – Phần 2

14:24 14/06/2021

Tiếp nối series PHP hướng đối tượng ở phần 1, ở phần 2, chúng ta sẽ tìm hiểu về ba khái niệm thú vị trong PHP hướng đối tượng đó là Static, Self và Parent.

1.Static keyword

1.1 Static

  • Static trong lập trình hướng đối tượng là một thành phần tĩnh (có thể là thuộc tính hoặc phương thức) mà nó hoạt động như một biến toàn cục, dù cho nó có được xử lý ở trong bất kỳ một file nào đi nữa (trong cùng một chương trình) thì nó đều lưu lại giá trị cuối cùng mà nó được thực hiện vào trong lớp.
  • Việc khai báo các thuộc tính hoặc phương thức của lớp với từ khóa static làm cho chúng có thể truy cập được mà không cần khởi tạo lớp. Chúng cũng có thể được truy cập trong một đối tượng được khởi tạo.
  • Thuộc tính và phương static được truy cập bằng và không thể truy cập thông qua toán tử đối tượng ( -> ).
  • Từ khóa $this không sử dụng với thuộc tính và phương thức static

1.2 Static properties

Có thể truy xuất tới các thuộc tính static thông qua tên class.

1.3 Static method

Vì các phương thức static có thể gọi được mà không cần khởi tạo 1 đối tượng tượng nên từ khóa $this không sử dụng được bên trong các phương thức được khai báo là static.

1.4 Example

Ví dụ:

  • Mình tạo object $con_vit và thiết lập tên cho nó là ‘Con Vịt’.
  • Tiếp theo tạo một object $con_heo và không có thiết lập tên cho nó
  • khi xuất tên ra màn hình thì Phần 1 xuất hiện chữ ‘Con Vịt’ còn Phần 2 thì xuất hiện chữ ‘Chưa có tên’. Như vậy rõ ràng các thao tác trên object $con_vit không ảnh hưởng qua object $con_heo.

Ví dụ với static:

  • Ở cả Phần 1 và Phần 2 đều xuất ra màn hình là ‘Con Vịt’, lý do là mình sử dụng static và khi có thao tác thay đổi dữ liệu thì nó đều lưu vào trong class Animal nên khi khởi tạo thêm biến nó đều bị ảnh hưởng theo

2. Self keyword

Ta không truy cập được vào thuộc tính static với $this. Vậy làm thế nào để tiếp cận (sử dụng) các thuộc tính static trong lớp? lúc này ta cần sử dụng staticself.

Ví dụ:

selfstatic có thể gọi các phương thức không phải là static (non-static) và các hằng số const. Nó không thể truy cập tới Thuộc tính không phải là static.

3. Khác nhau giữa static và self

Ví dụ sau:

  • Mình sử dụng staticself trong cùng 1 class thì kết quả đều cho giá trị giống nhau là ConNguoi. Chúng đều truy cập được vào thuộc tính static. Phải chẳng 2 keyword này có ý nghĩa như nhau?

Ví dụ dưới đây theo mình xin sử dụng 1 chút về tính chất Kế Thừa trong OOP để các bạn thấy rõ hơn sự khác nhau của staticself.

Các bạn thấy khác nhau rồi chứ?

  • Ta thấy function getName trong class ConNguoi thực hiện hiển thị ra màn hình giá trị thuộc tính static $name.
  • Tiếp theo mình tạo ra class NguoiLon kế thừa từ class ConNguoi nên mình có thể sử dụng được các thuộc tínhphương thức từ class ConNguoi
  • Sau đó khởi tạo đối tượng person từ class NguoiLon và gọi phương thức getName().
  • Kết quả in ra ta có thể biết
    • self truy cập tới các thuộc tínhphương thức bên trong class định nghĩa ra nó
    • static truy cập tới các thuộc tínhphương thức bên trong class hiện tại của nó (cách hoạt động giống như từ khóa $this)
  • Thuộc tính và Phương thức static có thể gọi trực tiếp không cần khởi tạo đối tượng từ 1 lớp.
  • $this không sử dụng được trong các phương thức static
  • Static: Truy cập (tham chiếu) tới class hiện tại (có thể hiểu như $this)
  • Self: Truy cập tới class khai báo (định nghĩa) ra nó

3.1 New static and new self

  • new self() là tạo ra đối tượng từ class định nghĩa ra nó (hay chứa nó)
  • new static() tạo ra chính đối tượng chứa hàm static được gọi.

Ví dụ sau:

Giải thích:

  • ta thấy ChildClass kế thừa cả hai phương thức từ ParentClass.
  • ChildClass gọi tới get_self() và trả về new self(), mà new self() là tạo ra đối tượng mới từ class chứa nó là ParentClass nên nó sẽ in ra màn hình là: ParentClass
  • Khi ChildClass gọi tới get_static() và trả về new static() chính là tạo ra đối tượng từ class gọi tới nó là ChildClass nên kết quả in ra ChildClass
  • new staticnew self nếu ở trong cùng 1 class thì nó tạo ra đối tượng chính là class chứa nó

Tiếp tục với ví dụ dưới đây xem chúng khác nhau như nào nhé?

  • Phần 1 ta thấy phương thức self_fn() trả về biến $model được gán giá trị là 1 đối tượng tạo ra từ new self(), như thế nó chính là đối tượng tạo ra từ class ParentClass, mà trong class ParentClass không có thuộc tính hay phương thức nào nên nó sẽ in ra kết quả như trên.
  • Còn phần 2 ta dùng new static() nên nó chính là đối tượng tạo từ class Child nên nó sẽ chứa cả thuộc tính $table, cho nên sẽ có kết quả như trên.

4. Parent keyword

  • $this đại diện cho của lớp hiện tại
  • self:: đại diện cho chính lớp tạo ra nó.

Bạn không thể sử dụng toán tử $this bên ngoài lớp và cả trong lớp mở rộng để nhận các giá trị của lớp cha.

Giải thích:

  • đầu tiên ta khởi tạo 1 object từ ChildClass nên function construct trong class ChildClass thực thi đầu tiên
  • Trong construct ta sử dụng parent::__construct nên construct của ParentClass được thực thi và echo ra “Tôi là Constructor Parent” (vì sử dụng self::CLSPARENT)
  • sau đó nó thực thi tiếp 4 echo dưới và có kết quả như trên.

*Để truy cập một thuộc tính hoặc phương thức trong lớp cha đã bị ghi đè trong lớp con bằng cách sử dụng từ khóa parent::.

Mình có ví dụ cụ thể hơn dưới đây:

5. Khác nhau giữa từ khóa $this – self và parent

  • $this
    • $this đề cập (truy cập) đến đối tượng
    • $this không trỏ đến bất kỳ đối tượng hoặc lớp nào khác.
  • self::
    • self:: tham chiếu đến chính lớp tạo ra nó, không trỏ đến bất kỳ đối tượng nào.
    • self:: bạn có thể truy cập các thuộc tính tĩnh và phương thức tĩnh của lớp hiện tại.
  • parent::
    • parent:: là tham chiếu đến lớp cha.
    • parent:: giúp bạn có thể truy cập các thuộc tính tĩnh và phương thức tĩnh của lớp cha.

*Với việc sử dụng self và parent, bạn cho phép tránh tham chiếu rõ ràng lớp theo tên.

*Hãy thử chạy lại từng ví dụ trên và thay thế các từ khóa static hay self hay parent cho nhau thì bạn sẽ hiểu kĩ hơn.

Tài liệu tham khảo:

Cùng chuyên mục

Đăng Kí học Fpoly 2023

Bình Luận