tek4

Interface - Lớp Abstract trong C++

by - September. 26, 2021
Kiến thức
Học
<p style="text-align: justify;">Interface - Lớp Abstract trong C++ l&agrave; kh&aacute;i niệm quan trọng trong lập tr&igrave;nh hướng đối tượng. Do đ&oacute;, trong b&agrave;i viết n&agrave;y, ta sẽ c&ugrave;ng t&igrave;m hiểu về đơn vị kiến thức n&agrave;y.</p> <h1>Kh&aacute;i niệm</h1> <p style="text-align: justify;">Trong C ++, ch&uacute;ng t&ocirc;i sử dụng c&aacute;c thuật ngữ lớp Abstract hay trừu tượng v&agrave; Interface thay thế cho nhau. Một lớp c&oacute; h&agrave;m ảo thuần t&uacute;y được gọi l&agrave; lớp trừu tượng. V&iacute; dụ, h&agrave;m sau l&agrave; một h&agrave;m ảo thuần t&uacute;y:</p> <pre class="language-cpp"><code>virtual void fun() = 0;</code></pre> <p style="text-align: justify;">Một h&agrave;m ảo thuần t&uacute;y được k&yacute; hiệu bằng từ kh&oacute;a virtual v&agrave; được g&aacute;n = 0. Ta c&oacute; thể gọi h&agrave;m n&agrave;y l&agrave; một h&agrave;m trừu tượng v&igrave; n&oacute; kh&ocirc;ng c&oacute; phần nội dung b&ecirc;n trong. Lớp dẫn xuất phải cung cấp việc triển khai thực hiện cho tất cả c&aacute;c h&agrave;m thuần ảo của lớp cha, nếu kh&ocirc;ng, theo mặc định, n&oacute; sẽ trở th&agrave;nh lớp trừu tượng.</p> <p style="text-align: justify;">Một lớp được được gọi l&agrave; trừu tượng nếu khai b&aacute;o &iacute;t nhất một trong c&aacute;c h&agrave;m của l&agrave; h&agrave;m ảo thuần.</p> <h2>Tại sao cần một lớp trừu tượng?</h2> <p style="text-align: justify;">Giả sử ch&uacute;ng ta c&oacute; một lớp sinh vi&ecirc;n, sinh vi&ecirc;n trường luật v&agrave; sinh vi&ecirc;n trường y. Ta sẽ tạo một lớp sinh vi&ecirc;n với hai h&agrave;m mon_hoc().</p> <p style="text-align: justify;">Ta biết rằng sinh vi&ecirc;n của mỗi trường c&oacute; c&aacute;c m&ocirc;n học l&agrave; kh&aacute;c nhau. V&igrave; vậy, c&aacute;ch duy nhất v&agrave; ch&iacute;nh x&aacute;c c&oacute; thể l&agrave;m l&agrave; chuyển h&agrave;m n&agrave;y th&agrave;nh một h&agrave;m thuần t&uacute;y trừu tượng để kh&ocirc;ng cần phải cung cấp việc triển khai trong lớp sinh vi&ecirc;n n&oacute;i ch&uacute;ng nhưng tất cả c&aacute;c lớp kế thừa lớp sinh vi&ecirc;n n&agrave;y phải cung cấp th&ecirc;m việc triển khai cho h&agrave;m mon_hoc(). Bằng c&aacute;ch n&agrave;y, ta sẽ đảm bảo rằng tất cả sinh vi&ecirc;n đều c&oacute; c&aacute;c m&ocirc;n học nhưng sinh vi&ecirc;n của mỗi trường kh&aacute;c nhau sẽ học m&ocirc;n kh&aacute;c nhau.</p> <p>V&iacute; dụ:</p> <pre class="language-cpp"><code>#include&lt;iostream&gt; using namespace std; class sinh_vien{ public: virtual void mon_hoc() = 0; }; class sinh_vien_truong_y: public sinh_vien{ public: void mon_hoc() { cout&lt;&lt;"Mon sinh hoc"&lt;&lt;endl; } }; class sinh_vien_truong_luat: public sinh_vien{ public: void mon_hoc() { cout&lt;&lt;"Mon luat dan su"&lt;&lt;endl; } }; int main(){ sinh_vien_truong_y sv1; sinh_vien_truong_luat sv2; sv1.mon_hoc(); sv2.mon_hoc(); return 0; }</code></pre> <p>Kết quả:</p> <pre class="language-markup"><code>Mon sinh hoc Mon luat dan su</code></pre> <h2>Quy tắc của lớp trừu tượng</h2> <p style="text-align: justify;">Bất kỳ lớp n&agrave;o chứa một h&agrave;m thuần ảo l&agrave; một lớp trừu tượng. Kh&ocirc;ng thể tạo một đối tượng của lớp trừu tượng. V&iacute; dụ trong đoạn m&atilde; tr&ecirc;n, nếu ta khai b&aacute;o sinh_vien sv;, tr&igrave;nh bi&ecirc;n dịch sẽ b&aacute;o lỗi. Tuy kh&ocirc;ng thể tạo đối tượng của lớp trừu tượng một c&aacute;ch trực tiếp nhưng ta c&oacute; thể tạo con trỏ của lớp trừu tượng cơ sở v&agrave; trỏ tới c&aacute;c đối tượng của lớp con.</p> <p>V&iacute; dụ:</p> <pre class="language-cpp"><code>sinh_vien *sv = new sinh_vien_truong_y(); sv &rarr; mon_hoc();</code></pre> <p style="text-align: justify;">Lớp trừu tượng c&oacute; thể c&oacute; c&aacute;c h&agrave;m tạo. Nếu lớp dẫn xuất kh&ocirc;ng cung cấp việc triển khai thực hiện cho h&agrave;m thuần ảo của lớp cha th&igrave; lớp dẫn xuất trở th&agrave;nh lớp trừu tượng.</p> <p style="text-align: justify;">Một Interface sẽ m&ocirc; tả h&agrave;nh vi hoặc khả năng của một lớp trong C ++ m&agrave; kh&ocirc;ng thực hiện chi tiết cụ thể của lớp đ&oacute;. C&aacute;c Interface trong C ++ được thực hiện bằng c&aacute;ch sử dụng c&aacute;c lớp trừu tượng. Interface sẽ chỉ chứa c&aacute;c h&agrave;m thuần ảo.</p> <p style="text-align: justify;">Mục đ&iacute;ch của h&agrave;m ảo nhằm để cung cấp một lớp cơ sở ph&ugrave; hợp cho c&aacute;c lớp thừa kế v&agrave; hảm ảo được sử dụng l&agrave;m một Interface. Mỗi lớp interface n&ecirc;n c&oacute; một h&agrave;m hủy ảo.</p> <p>V&iacute; dụ:</p> <pre class="language-cpp"><code>class ỉnterface{ public: virtual ~interface(); virtual void mon_hoc() = 0; virtual void nganh_hoc() = 0; };</code></pre> <h1>Kh&aacute;c biệt giữa Interface v&agrave; lớp Abstract</h1> <ul> <li style="text-align: justify;">Interface kh&ocirc;ng c&oacute; sự triển khai cụ thể n&agrave;o, lớp trừu tượng th&igrave; c&oacute; thể c&oacute;.</li> <li style="text-align: justify;">Lớp trừu tượng c&oacute; thể c&oacute; dữ liệu th&agrave;nh vi&ecirc;n v&agrave; h&agrave;m th&agrave;nh vi&ecirc;n, Interface th&igrave; kh&ocirc;ng.</li> <li style="text-align: justify;">Lớp trừu tượng c&oacute; thể thực hiện triển khai cho một Interface bằng c&aacute;ch triển khai cho tất cả c&aacute;c phương thức của Interface đ&oacute;.</li> <li style="text-align: justify;">Interface c&oacute; thể t&iacute;nh đa kế thừa, lớp trừu tượng th&igrave; kh&ocirc;ng.</li> </ul> <p style="text-align: justify;">V&iacute; dụ về t&iacute;nh đa kế thừa: Giả sử c&oacute; 2 lớp sinh vi&ecirc;n A v&agrave; sinh vi&ecirc;n B. Một lớp sinh vi&ecirc;n C kh&aacute;c sẽ kế thừa lớp sinh vi&ecirc;n A v&agrave; sinh B.</p> <pre class="language-cpp"><code>#include&lt;iostream&gt; using namespace std; class sinh_vien_A { public: sinh_vien_A(){ cout &lt;&lt; "Sinh vien A" &lt;&lt; endl; } }; class sinh_vien_B { public: sinh_vien_B() { cout &lt;&lt; "Sinh vien B" &lt;&lt; endl; } }; class sinh_vien_C: public sinh_vien_B, public sinh_vien_A{ public: sinh_vien_C() { cout &lt;&lt; "Sinh vien C" &lt;&lt; endl; } }; int main(){ sinh_vien_C sv; return 0; }</code></pre> <p>Kết quả:</p> <pre class="language-markup"><code>Sinh vien B Sinh vien A Sinh vien C</code></pre> <p style="text-align: justify;">Trong đoạn m&atilde; tr&ecirc;n, c&aacute;c h&agrave;m tạo của lớp kế thừa sẽ được gọi theo thứ tự m&agrave; n&oacute; kế thừa theo c&aacute;c lớp cha. Do đ&oacute;, kết quả sẽ trả về theo thứ tự l&agrave; h&agrave;m tạo của lớp cha B được gọi trước h&agrave;m của lớp cha A của lớp C.</p> <p style="text-align: justify;">Tr&ecirc;n đ&acirc;y l&agrave; kh&aacute;i niệm v&agrave; v&iacute; dụ cơ bản về Interfaces &ndash; Lớp Abstract trong C++. Hy vọng mọi người c&oacute; thể &aacute;p dụng v&agrave;o trong chương tr&igrave;nh của m&igrave;nh. Mọi người h&atilde;y tiếp tục theo d&otilde;i c&aacute;c b&agrave;i tiếp theo v&agrave; cập nhật c&aacute;c b&agrave;i mới nhất tr&ecirc;n <a href="http://tek4.vn">tek4</a> nh&eacute;!</p>