- vừa được xem lúc

[Object-Oriented + Ada] Bài 4 - Abstraction & Inteface

0 0 11

Người đăng: Semi Dev

Theo Viblo Asia

Tính Trừu Tượng Abstraction được Ada 95 hỗ trợ với khái niệm Interface - được hiểu là giao diện lập trình. Khái niệm này cũng xuất phát từ cuộc sống hàng ngày khi mà chúng ta có các đồ vật có thể được thiết kế với một hoặc nhiều nhóm tính năng. Ví dụ như một chiếc USB lưu trữ được thiết kế kiêm một chiếc card-wifi thì sẽ có hai giao diện sử dụng là duyệt tệp lưu trữ và bảng điều khiển chức năng kết nối.

Interface

Một object bất kỳ trong môi trường phần mềm cũng có thể được thiết kế như vậy, và nhiều object khác nhau có thể sẽ có cùng giao diện chức năng. Khái niệm Interface được sử dụng để tạo ra một bản khai báo ở dạng thiết kế trừu tượng về một giao diện chức năng. Sau đó, các kiểu dữ liệu khác nhau có thể chọn khai báo để triển khai Interface này bằng một cú pháp lệnh ngắn gọn.

Và kết quả là trình biên dịch sẽ không dừng nhắc nhở cho đến khi các kiểu dữ liệu có khai báo Interface này đã được viết đầy đủ code triển khai chi tiết cho các sub-program có tên được liệt kê trong định nghĩa của Interface.

package Being is type Entity is interface; type Class is access all Entity'Class; procedure Meditate (Self: in Entity) is abstract; end Being;

Ở đây chúng ta đang định nghĩa kiểu Being.Entity là một interface và không có mô tả chi tiết. Vì vậy nên các primitive hay các sub-program khác có sử dụng các tham số kiểu này sẽ không thể viết logic xử lý chi tiêt được và đều phải dừng lại ở cấp độ khai báo trừu tượng is abstract.

Khi chúng ta sử dụng kiểu Being.Entity trong thao tác kế thừa của một kiểu tagged record nào đó thì chúng ta sẽ có thể nhờ trình biên dịch nhắc nhở cho đến khi các sub-program này được triển khai đầy đủ code chi tiết ở kiểu kế thừa.

Bây giờ chúng ta sẽ thử khai báo kiểu Coder có áp dụng interface này và chạy code trước khi bổ sung thêm procedure Meditate.

with Person; use Person;
with Being; use Being; package Person.Coder is -- ... type Entity is new Person.Entity and Being.Entity with record Intellect : Bit; end record; -- ... end Person.Coder;
alr run error: type must be declared abstract or "Meditate" overridden
error: "Meditate" has been inherited from subprogram at being.ads
compilation of main.adb failed

Thông báo này nhắc nhở chúng ta là kiểu Coder.Entity đang kế thừa kiểu Being.Entity là một interface và cần phải override phương thức Meditate, hoặc chuyển thành định nghĩa kiểu trừu tượng abstract.

with Ada.Text_IO; use Ada.Text_IO;
with Person; use Person; package body Person.Coder is -- ... overriding procedure Meditate (Self: in Entity) is -- local begin Put_Line ("Meditating..."); end Meditate; end Person.Coder;

Bây giờ chúng ta sẽ thử tham chiếu tới một object Coder.Entity bằng con trỏ Being.Class và truy xuất thuộc tính Name.

with Ada.Text_IO; use Ada.Text_IO;
with Person; use Person;
with Person.Coder; use Person.Coder;
with Being; use Being; procedure Main is Me : Being.Class;
begin Me := new Coder.Entity' ( Name => "Semi Dev_ " , Intellect => 0 ); Put_Line ("My name: " & Me.Name);
end Main;
alr run error: no selector "Name" for type "Entity'Class" defined at being.ads

Do chúng ta đang sử dụng một con trỏ kiểu access all Being.Entity'Class, lúc này tất cả những gì mà con trỏ này có thể nhìn thấy là các thành phần trong giao diện interface Being. Tất cả các khía cạnh khác của object Coder.Entity vẫn ở đó nhưng chỉ đơn giản là chúng ta không thể nhìn thấy từ góc nhìn của Being.Entity.

Ở đây chúng ta lưu ý là Ada chỉ hỗ trợ kế thừa từ duy nhất một kiểu record có định nghĩa chi tiết, và cho phép áp dụng nhiều interface bằng các từ khóa and.

type Coder is new Person and Being and Living and Thinking and ...
with record -- fields ...
end record;

Tính năng này cũng hoàn toàn tương tự với các ngôn ngữ lập trình OOP phổ biến hiện tại.

Abstract record

Oh.. như vậy là chúng ta còn có thêm một yếu tố nữa xuất hiện trong thông báo lỗi của trình biên dịch; Đó là chúng ta có thể định nghĩa một kiểu record trừu tượng abstract. Khái niệm này tương đương với abstract class trong các ngôn ngữ lập trình OOP phổ biến.

Định nghĩa abstract record có thể có code triển khai chi tiết, tuy nhiên chúng ta sẽ không thể tạo ra object từ cú pháp new như với các kiểu record thông thường. Thêm vào đó là bởi vì các abstract record có thể được định nghĩa chi tiết hoặc chỉ khai báo đơn giản giống như interface nên các sub-program liên quan cũng có thể có code triển khai chi tiết hoặc là phải khai báo abstract.

Trong trường hợp cần tạo ra một bản mẫu cho nhiều kiểu record mô phỏng các thực thể có nhiều điểm chung, chúng ta có thể nghĩ tới việc sử dụng abstract record để giảm thiểu lượng code định nghĩa lặp, và hiển nhiên là cả các sub-program xoay quanh abstract record cũng vậy.

Bây giờ chúng ta sẽ chuyển kiểu Person.Entity thành abstract record và khai báo thêm một procedure Learn ở dạng abstract chưa có code triển khai.

package Person is type Entity is abstract tagged record Name : String (1 .. 12); end record; procedure Learn (Self: in Entity) is abstract; end Person;

Code sử dụng tại main sẽ chỉ đơn giản là cố gắng tạo ra object từ abstract record này.

with Ada.Text_IO; use Ada.Text_IO;
with Person; use Person; procedure Main is Me : Person.Class;
begin Me := new Person.Entity' (Name => "Semi Dev_ "); Put_Line ("My name: " & Me.Name);
end Main;
alr run main.adb: error: cannot allocate abstract object
person-coder.ads: error: type must be declared abstract or "Learn" overridden
person-coder.ads: error: "Learn" has been inherited from subprogram at person.ads

Thông báo lỗi đầu tiên là ở code sử dụng tại main, thao tác tạo object từ kiểu abstract là không hợp lệ; Và các thông báo lỗi tiếp theo là ở package Person.Coder chúng ta đang có kiểu Coder.Entity kế thừa từ abstract Person.Entity nhưng chưa triển khai đủ các sub-program abstract liên quan, cụ thể là procedure Learn vừa định nghĩa.

Bổ sung khai báo procedure Learn và code triển khai cho package Person.Coder.

with Person; use Person;
with Being; use Being; package Person.Coder is -- ... type Entity is new Person.Entity and Being.Entity with record Intellect : Bit; end record; overriding procedure Learn (Self: in Entity); -- ... end Person.Coder;
with Ada.Text_IO; use Ada.Text_IO;
with Person; use Person; package body Person.Coder is -- ... overriding procedure Learn (Self: in Entity) is -- local begin Put_Line ("Learning..."); end Learn; end Person.Coder;

Ở code sử dụng tại main chúng ta sẽ sửa lại thao tác khởi tạo object từ kiểu Coder.Entity và gọi phương thức Learn vừa định nghĩa bổ sung.

with Ada.Text_IO; use Ada.Text_IO;
with Person; use Person;
with Person.Coder; use Person.Coder; procedure Main is Me : Person.Class;
begin Me := new Coder.Entity' ( Name => "Semi Dev_ " , Intellect => 0 ); Me.Learn;
end Main;
alr run Learning...

[Object-Oriented + Ada] Bài 5 - Encapsulation & Package Privacy

Bình luận

Bài viết tương tự

- vừa được xem lúc

Closure trong Javascript - Phần 2: Định nghĩa và cách dùng

Các bạn có thể đọc qua phần 1 ở đây. Để mọi người không quên, mình xin tóm tắt gọn lại khái niệm lexical environment:.

0 0 51

- vừa được xem lúc

Var vs let vs const? Các cách khai báo biến và hằng trong Javascript

Dạo này mình tập tành học Javascript, thấy có 2 cách khai báo biến khác nhau nên đã tìm tòi sự khác biệt. Nay xin đăng lên đây để mọi người đọc xong hy vọng phân biệt được giữa let và var, và sau đó là khai báo hằng bằng const.

0 0 31

- vừa được xem lúc

VueJS: Tính năng Mixins

Chào mọi người, hôm nay mình sẽ viết về Mixins và 1 số vấn đề trong sử dụng Mixins hay ho mà mình gặp trong dự án thực. Trích dẫn từ trang chủ của VueJS:.

0 0 27

- vừa được xem lúc

Asset Pipeline là cái chi chi?

Asset Pipeline. Asset pipeline là cái chi chi. . Giải thích:.

0 0 47

- vừa được xem lúc

Tạo data table web app lấy dữ liệu từ Google Sheets sử dụng Apps Script

Google Sheets là công cụ tuyệt vời để lưu trữ bảng tính trực tuyến, bạn có thể truy cập bảng tính bất kỳ lúc nào ở bất kỳ đâu và luôn sẵn sàng để chia sẻ với người khác. Bài này gồm 2 phần.

0 0 266

- vừa được xem lúc

Học Deep Learning trên Coursera miễn phí

Bạn muốn bắt đầu với Deep Learning nhưng không biết bắt đầu từ đâu? Bạn muốn có một công việc ở mức fresher về Deep Learning? Bạn muốn khoe bạn bè về kiến thức Deep Learning của mình. Bắt đầu từ đâu.

0 0 35