1. Sự khác biệt giữa lập trình hướng đối tượng và hướng thủ tục
- Hướng thủ tục:
- Chia nhỏ vấn đề thành các quy trình đơn giản.
- Ưu điểm: Dễ hiểu, dễ thực hiện với vấn đề phức tạp.
- Nhược điểm: Khó mở rộng, bảo trì.
- Hướng đối tượng:
- Ưu điểm: Tính mở rộng cao, dễ tái sử dụng.
- Nhược điểm: Độ phức tạp cao hơn.
2. Lập trình hướng đối tượng là gì?
- Trọng tâm là đối tượng, một khái niệm từ nước ngoài.
- Đối tượng là một chứa đựng (container), lưu trữ cả dữ liệu và hàm.
- Tư tưởng lập trình hướng đối tượng: Tạo các đối tượng để tổ chức mã nguồn.
3. So sánh với ví dụ thực tế
- Hướng thủ tục giống như việc ghép các mảnh gỗ rời thành kệ sách, hay lắp ráp linh kiện thành tủ lạnh.
- Hướng đối tượng như việc phân loại sách, rau củ vào các vị trí phù hợp trong nhà.
- Một căn bếp có thể xem là một đối tượng chứa cả dữ liệu (hành, tỏi, trứng...) và chức năng (tủ lạnh, nồi cơm điện).
4. Đặc điểm của đối tượng
- Đối tượng chứa dữ liệu và chức năng.
- Ví dụ: Tủ lạnh chỉ là một hàm nếu chưa chứa dữ liệu, nhưng khi chứa thực phẩm thì trở thành đối tượng.
5. Ưu điểm và thách thức của hướng đối tượng
- Ưu điểm: Mở rộng tốt, dễ bảo trì.
- Nhược điểm: Ban đầu phức tạp hơn, đòi hỏi suy nghĩ kỹ lưỡng.
6. Minh họa qua ví dụ
# Dữ liệu và hàm rời nhau
name = "Nguyen Van A"
age = 20
gender = "Nam"
def show_info():
print(f"Tên: {name}, Tuổi: {age}, Giới tính: {gender}")
show_info()
# Gom dữ liệu vào một container
def show_info(student):
print(f"Tên: {student['name']}, Tuổi: {student['age']}, Giới tính: {student['gender']}")
student = {
"name": "Nguyen Van B",
"age": 22,
"gender": "Nam",
"show_info": show_info
}
student["show_info"](student)
# Gom cả hàm vào container
student = {
"name": "Nguyen Van C",
"age": 25,
"gender": "Nam",
"show_info": lambda s: print(f"Tên: {s['name']}, Tuổi: {s['age']}, Giới tính: {s['gender']}")
}
student["show_info"](student)
7. Khái niệm lớp và đối tượng
- Đối tượng là thực thể cụ thể (ví dụ: sinh viên A, sinh viên B).
- Lớp là khái niệm tổng quát cho một nhóm đối tượng có chung đặc điểm (ví dụ: lớp SinhViên).
8. Tạo lớp và khởi tạo đối tượng
class SinhVien:
truong = "Đại học FPT"
def __init__(self, ten, tuoi, gioi_tinh):
self.ten = ten
self.tuoi = tuoi
self.gioi_tinh = gioi_tinh
def hien_thi_thong_tin(self):
print(f"Tên: {self.ten}, Tuổi: {self.tuoi}, Giới tính: {self.gioi_tinh}")
# Tạo đối tượng
sv1 = SinhVien("Tran Van B", 21, "Nam")
sv1.hien_thi_thong_tin()
9. Nguyên tắc kế thừa và đóng gói
- Đóng gói: Đặt dữ liệu và chức năng vào cùng một lớp, giúp kiểm soát truy cập và tăng tính bảo mật.
- Kế thừa: Tạo lớp mới dựa trên lớp cũ, giúp tái sử dụng mã.
10. Che giấu thuộc tính
class Nguoi:
__quoc_gia = "Vietnam"
def __init__(self, ten, tuoi):
self.__ten = ten
self.__tuoi = tuoi
def __noi_chuyen(self):
print("Đang nói chuyện...")
# Truy cập thuộc tính bị che giấu
obj = Nguoi("Nguyen Van D", 25)
print(obj._Nguoi__ten)
11. Mục đích che giấu
- Bảo vệ dữ liệu khỏi truy cập không mong muốn.
- Cho phép kiểm soát cách truy cập và thay đổi dữ liệu.
12. Tổng kết
- Lớp là tập hợp các đối tượng có chung đặc điểm.
- Đối tượng là thực thể cụ thể được tạo từ lớp.
- Kế thừa giúp tái sử dụng mã nhưng tạo sự phụ thuộc chặt chẽ.
- Đóng gói giúp bảo vệ dữ liệu và chức năng.