Lập trình hướng đối tượng
Nguyễn Dương 20-06-2024- Lập trình hướng đối tượng là mô hình lập
trình dựa trên khái niệm đối tượng. Mô hình lập trình sẽ quy định phong cách
code, cách viết và tổ chức code.
- Sử dụng mô hình đối tượng để mô hình hóa, mô
tả các khía cạnh trong thế giới thực
- Các object có thể chứa dữ liệu bao gồm thuộc
tính (properties) và phương thức - method (code).
- Bằng cách sử dụng object chúng ta đóng gói tất
cả dữ liệu và hành vi tương ứng thành một khối dễ dàng thao tác.
- Trong OOP, các đối tượng là các đoạn/khối mã
độc lập; Các đối tượng là các khối xây dựng của ứng dụng và tương tác với nhau.
- Tương tác xảy ra thông qua giao diện công
khai - public interface (API) - các
phương thức mà code bên ngoài đối tượng có thể truy cập và sử dụng để giao tiếp
với đối tượng.
- OOP tồn tại để đáp ứng mục tiêu cấu trúc, tổ
chức code linh hoạt hơn và dễ dàng bảo trì.
- Hiện nay OOP là mô hình lập trình được sử dụng
rộng rãi nhất trong kỹ thuật lập trình.
Class (lớp) và instance trong OOP truyền thống
- Chúng ta đã sử dụng object trong những buổi học
trước nhưng chúng ta mới có những object lỏng lẻo, chưa tương tác với nhau.
- Trong OOP chúng ta cần một cách thống nhất để
tạo ra các object mới từ code của mình.
- Class như một bản thiết kế chi tiết, sau đó tạo
ra object mới dựa trên các quy tắc được quy tắc trong class.
- Các object được tạo từ class được gọi là
instance của class, instance là một đối tượng thực có các giá trị thuộc tính và
hành vi thực.
4 nguyên lý cơ bản của OOP
- Trừu tượng: Sự trừu tượng cơ bản là bỏ đi hoặc
ẩn chi tiết không quan trọng. Nó cho phép ta có cái nhìn tổng quan về những gì
mà chúng ta triển khai.
- Đóng gói: Đóng gói là giữ một số thuộc tính
và các phương thức private bên trong class để chúng không truy cập được từ bên
ngoài class. Chúng ta luôn có mục tiêu là đóng gói hầu hết các trạng thái và
phương thức và chỉ công khai các phương thức thiết yếu.
- Kế thừa: Trong OOP chúng ta có hai class có
liên quan chặt chẽ với nhau, một class kế thừa class kia và chúng sẽ là class
cha và class con. Class con kế thừa các thuộc tính và phương thức của class
cha. Tính thừa kế làm cho tất cả các thuộc tính và phương thức của một class nhất
định có sẵn cho class con, nó tạo thành một hệ thống phân cấp.
- Đa hình (nhiều hình dạng): Một class con có
thể ghi đè một phương thức mà nó được thừa kế từ một class cha.
Prototype
Trong JS có một thứ gọi là Prototype, tất cả
các đối tượng trong JS được liên kết với một đối tượng prototype nhất định.
Prototype là cơ chế quan trọng trong việc thực thi mô hình OOP trong JavaScript. Tất cả các object trong javascript đều có một thuộc tính là prototype, và các object này kế thừa các thuộc tính (properties) cũng như phương thức (methods) từ prototype của mình.
- Mỗi đối tượng có một prototype.
- Đối tượng prototype chứa các phương thức và thuộc tính mà tất cả các đối tượng được
liên kết với prototype đó có thể truy cập và sử dụng => Hành vi này gọi là kế
thừa nguyên mẫu.
- Kế thừa nguyên mẫu là tất cả các đối tượng được
liên kết với một đối tượng prototype nhất định, đối tượng có thể sử dụng các
thuộc tính và phương thức của prototype đó.
- Kế thừa nguyên mẫu khác với kế thừa thông thường, đó là một instance kế thừa một class (có thể gọi là cơ chế ủy quyền).
Sử dụng thuộc tính prototype để khai báo phương thức thay cho phương pháp khai báo thẳng vào object
Trong ví dụ trên, bạn có thể thấy mình không hề khai báo hàm name trong class Person. Nhưng mình có thể thêm hàm đó ở ngoài class bằng prototype.
Thuộc tính đặc biệt
__proto__
Nếu chúng ta tạo một object từ User, object mới
tạo sẽ có một liên kết đến prototype của User. Các bạn có thể truy xuất bằng
cách sử dụng __proto__. Thuộc tính này nằm trong Object.prototype, vì vậy khi một
object dùng thuộc tính này, JavaScript sẽ tìm thấy thuộc tính __proto__ trong
chuỗi nguyên mẫu (prototype chain)
let u
= new User();
// sử dụng u.[[Prototype]] sẽ không
thành công
console.log(u.__proto__
=== User.prototype); //
true
console.log(u.__proto__.__proto__
=== Object.prototype); //
true
console.log(User.prototype.__proto__
=== Object.prototype); //
true
Các bạn không nên sử dụng __proto__
(Object.prototype.__proto__) vì tính năng này có thể sẽ bị xóa khỏi một số
trình duyệt. Thay vào đó chúng ta có thể sử dụng Object.getPrototypeOf().
constprototypeOf
=Object
.getPrototypeOf
;
letu
=new
User();
// prototypeOf(u) === User.prototype; // true
// prototypeOf(prototypeOf(u)) === Object.prototype // true
Khác biệt giữa someobj.__proto__ với SomeFunction.prototype
__proto__ trỏ vào prototype object của someObj, còn prototype ở prototype object sẽ được gán làm prototype cho các object được tạo dựa trên SomeFunction
Lưu ý: khi khởi tạo class con kết thừa từ class cha, hàm super() cần được gọi trước khi bạn dùng nó
trong class kế thừa (trong "sub-class")