Chuyển tới nội dung chính

Dạng đề 1: Lý thuyết

Câu 1: Trình bày các đặc điểm quan trọng của lập trình hướng đối tượng.

  • Trừu tượng hóa – Abstraction: Trừu tượng là quá trình tạo ra các lớp trừu tượng để mô hình hóa các đối tượng trong thế giới thực. Nó giúp tập trung vào các khía cạnh quan trọng và ẩn đi các chi tiết không cần thiết.
  • Đóng gói – Encapsulation: Đóng gói là quá trình kết hợp dữ liệu và các phương thức hoạt động trên dữ liệu thành một đơn vị độc lập. Điều này giúp bảo vệ dữ liệu và ẩn thông tin chi tiết về cách hoạt động bên trong của đối tượng.
  • Thừa kế - Inheritance: Kế thừa cho phép lớp con kế thừa các thuộc tính và phương thức từ lớp cha. Điều này giúp tái sử dụng mã nguồn và xây dựng các mối quan hệ phân cấp giữa các lớp.
  • Đa hình – Polymorphism: Đa hình cho phép sử dụng các phương thức cùng tên nhưng với cách thức thực hiện khác nhau trong các lớp khác nhau. Điều này cho phép gọi cùng một phương thức và có kết quả khác nhau tuỳ thuộc vào đối tượng gọi phương thức đó.

Câu 2: Trình bày sự hiểu biết và cho ví dụ minh họa về khái niệm class (lớp) và object (đối tượng) trong lập trình hướng đối tượng.

  • Lớp là một khuôn mẫu và đối tượng là một thực thể được thể hiện dựa trên khuôn mẫu đó. Hay nói cách khác, lớp là một mô tả trừu tượng của một nhóm các đối tượng có cùng bản chất, ngược lại, mỗi đối tượng là một thể hiện cụ thể cho những mô tả trừu tượng đó.
  • Một lớp đối tượng bao gồm 2 thành phần chính:
    • Thành phần dữ liệu (data member), hay còn được gọi là thuộc tính (attribute). 
    • Hàm thành phần (member function), còn có tên gọi khác là phương thức (method), là các hành động mà đối tượng của lớp có thể thực hiện. 

Câu 3: Trình bày những đặc điểm của tính đóng gói (Encapsulation) trong lập trình hướng đối tượng. Trường hợp nào có thể vi phạm tính đóng gói? Cho ví dụ minh họa.

  • Các đặc điểm:
    • Giúp bảo vệ dữ liệu bên trong tránh khỏi các sai sót không đáng có từ người dùng.
    • Giúp thay đổi phần thực thi của lớp một cách linh hoạt (tức là thay đổi cách tổ chức dữ liệu, chi tiết thực hiện các phương thức) -> Dễ bảo trì, dễ kiểm thử, tăng khả năng tái sử dụng.
  • Trường hợp vi phạm tính đóng gói: cố gắng truy cập đến thuộc tính private/ gọi đến phương thức private của lớp khi đang nằm ngoài phạm vi truy cập của nó.
  • Ví dụ:
class Diem { 
private:
int x;
int y;
};

int main() {
Diem P;
P.x = 0; //Sai
return 1;
}

Câu 4: Cho biết ý nghĩa và mục đích của các hàm get/set trong một lớp.

  • Hàm getset là các hàm thành viên của một lớp được sử dụng để truy cậpthay đổi giá trị của các thuộc tính của lớp đó. Hàm get được sử dụng để truy xuất giá trị của một thuộc tính trong khi hàm set được sử dụng để gán giá trị cho thuộc tính đó.
  • Mục đích:
    • Đảm bảo rằng dữ liệu của lớp được bảo vệkiểm soát tốt hơn. Chúng cho phép lập trình viên kiểm soát cách thức truy cập và thay đổi dữ liệu của lớp, giúp ngăn chặn việc truy cập trực tiếp vào các thuộc tính của lớp từ bên ngoài lớp.
    • Tăng tính linh hoạt và tái sử dụng của mã nguồn. Nếu bạn muốn thay đổi cách thức tính toán giá trị của một thuộc tính, bạn chỉ cần thay đổi mã nguồn trong hàm set tương ứng mà không cần thay đổi mã nguồn ở những nơi khác trong chương trình.

Câu 5: Nêu khái niệm constructordestructor. Phân biệt các kiểu constructor.

  • Constructor: Phương thức thiết lập - có nhiệm vụ thiết lập thông tin ban đầu cho các đối tượng thuộc về lớp ngay khi đối tượng được khai báo.
  • Destructor: Phương thức phá hủy - có nhiệm vụ thu hồi lại tất cả các tài nguyên đã cấp phát cho đối tượng khi đối tượng hết phạm vi hoạt động (scope).
  • Phân biệt: Ta có thể chia các phương thức thiết lập của một lớp thành 3 nhóm như sau:
    • Phương thức thiết lập mặc định (default constructor): thiết lập các thông tin ban đầu cho đối tượng thuộc về lớp bằng những giá trị mặc định (do người lập trình quyết định). Phương thức thiết lập mặc định không có tham số đầu vào.
    • Phương thức thiết lập sao chép(copy constructor): nhận tham số đầu vào là một đối tượng cùng thuộc về lớp. Các thông tin ban đầu của đối tượng sẽ hoàn toàn giống thông tin của đối tượng tham số đầu vào.
    • Phương thức thiết lập nhận tham số đầu vào (user defined constructor – parameterized constructors): không phải là phương thức thiết lập mặc định và phương thức thiết lập sao chép.

Câu 6: Trình bày những ưu điểm của kế thừa trong lập trình hướng đối tượng và cho ví dụ minh họa?

  • Các ưu điểm:
    • Kế thừa cho phép xây dựng lớp mới từ lớp đã có. 
    • Kế thừa cho phép tổ chức các lớp chia sẻ mã chương trình chung, nhờ vậy có thể dễ dàng sửa chữa, nâng cấp hệ thống. 
    • Định nghĩa sự tương thích giữa các lớp, nhờ đó ta có thể chuyển kiểu tự động. 
    • Kế thừa cho phép chuyển kiểu tự động, một đối tượng của lớp con có thể được gán bởi tham chiếu hoặc con trỏ của lớp cha, giúp quản lý một mảng các đối tượng một cách dễ dàng
  • Ví dụ:
class HocSinh { 
// ...
};
// lớp HocSinhGioi kế thừa các thành viên từ lớp HocSinh mà
// không cần phải khai báo.

class HocSinhGioi : public HocSinh {
// ...
};

Câu 7: Phân biệt các kiểu kế thừa private, public, protected.

Từ khóa dẫn xuất \ Phạm vi truy cậpprivateprotectedpublic
privateXprivateprivate
protectedXprotectedprotected
publicXprotectedpublic
  • Thành phần private ở lớp cha thì không truy xuất được ở lớp con.
  • Kế thừa public: Lớp con kế thừa public từ lớp cha thì các thành phần protected của lớp cha trở thành protected của lớp con, các thành phần public của lớp cha trở thành public của lớp con.
  • Kế thừa private: Lớp con kế thừa private từ lớp cha thì các thành phần protectedpublic của lớp cha trở thành private của lớp con.
  • Kế thừa protected: Lớp con kế thừa protected từ lớp cha thì các thành phần protectedpublic của lớp cha trở thành protected của lớp con.

Câu 8: Phân biệt các phạm vi truy cập private, public, protected.

  • Phạm vi truy cập public: có thể được truy cập ở tất cả các phần của chương trình. Các thành phần public tạo nên giao diện của một Lớp.
  • Phạm vi truy cập private: chỉ có thể được truy cập bên trong phạm vi của lớp, bởi các hàm thành viên (phương thức) của một lớp và không thể được truy cập từ bên ngoài lớp. Phần private ẩn đi (đóng gói) phần thực thi.
  • Phạm vi truy cập protected: Là sự kết hợp giữa publicprivate, có thể được truy cập ở lớp dẫn xuất trong khi vẫn giới hạn quyền truy cập từ người dùng.

Câu 9: Phân biệt khái niệm overload (nạp chồng) và override (ghi đè).

  • Overload (nạp chồng): Là một kĩ thuật cho phép trong cùng một class có thể có nhiều phương thức cùng tên nhưng khác nhau về số lượng tham số hoặc kiểu dữ liệu tham số.

  • Overriding (ghi đè): Được sử dụng trong trường hợp lớp con kế thừa từ lớp cha và muốn định nghĩa lại một phương thức đã có mặt ở lớp cha. Một lớp cha thông thường có thể có nhiều lớp con kế thừa, tuy nhiên phương thức ở lớp cha có thể phù hợp với lớp con này nhưng không phù hợp với lớp con khác, do đó lớp con cần ghi đè lại phương thức đó cho phù hợp. Các phương thức được ghi đè giống nhau hoàn toàn về tên, danh sách tham số, kiểu dữ liệu trả về.

Câu 10: Hàm thuần ảo là gì? Lớp trừu tượng là gì? Cho ví dụ minh họa.

  • Hàm thuần ảo: Một hàm được tạo ra mà không được định nghĩa để phục vụ cho các lớp dẫn xuất kế thừa từ lớp cơ sở ghi đè lại.
  • Lớp trừu tượng: Một lớp có ít nhất một hàm thuần ảo được gọi là lớp trừu tượng. Mục đích lớp trừu tượng được tạo ra là để các lớp dẫn xuất kế thừa lại.
  • Ví dụ:
// Shape là lớp trừu tượng 
class Shape {
public:
virtual int DienTich() = 0; // Lớp thuần ảo
virtual int ChuVi() = 0; // Lớp thuần ảo
};