Bài giảng Lập trình hướng đối tượng - Võ Đức Lân
Chương 1 trình bày những vấn đề sau:
Thảo luận về cách tiếp cận hướng đối tượng.
Các khái niệm cơ sở của phương pháp hướng đối tượng.
Các bước cần thiết để thiết kế chương trình theo hướng đối tượng.
Các ưu điểm của lập trình hướng đối tượng.
Các ngôn ngữ hướng đối tượng.
Một số ứng dụng của lập trình hướng đối tượng.
1.1. Giới thiệu
Lập trình hướng đối tượng (Object-Oriented Programming, viết tắt là OOP) là
một phương pháp mới trên bước đường tiến hóa của việc lập trình máy tính, nhằm làm
cho chương trình trở nên linh hoạt, tin cậy và dễ phát triển. Tuy nhiên để hiểu được
OOP là gì, chúng ta hãy bắt đầu từ lịch sử của quá trình lập trình – xem xét OOP đã
tiến hóa như thế nào.
1.1.1. Lập trình tuyến tính
Máy tính đầu tiên được lập trình bằng mã nhị phân, sử dụng các công tắt cơ
khí để nạp chương trình. Cùng với sự xuất hiện của các thiết bị lưu trữ lớn và bộ nhớ
máy tính có dung lượng lớn nên các ngôn ngữ lập trình cấp cao đầu tiên được đưa vào
sử dụng . Thay vì phải suy nghĩ trên một dãy các bit và byte, lập trình viên có thể viết
một loạt lệnh gần với tiếng Anh và sau đó chương trình dịch thành ngôn ngữ máy. Các
ngôn ngữ lập trình cấp cao đầu tiên được thiết kế để lập các chương trình làm các công
việc tương đối đơn giản như tính toán. Các chương trình ban đầu chủ yếu liên quan đến
tính toán và không đòi hỏi gì nhiều ở ngôn ngữ lập trình. Hơn nữa phần lớn các chương
trình này tương đối ngắn, thường ít hơn 100 dòng. Khi khả năng của máy tính tăng lên
thì khả năng để triển khai các chương trình phức tạp hơn cũng tăng lên. Các ngôn ngữ
lập trình ngày trước không còn thích hợp đối với việc lập trình đòi hỏi cao hơn. Các
phương tiện cần thiết để sử dụng lại các phần mã chương trình đã viết hầu như khôngTrang 2
có trong ngôn ngữ lập trình tuyến tính. Thật ra, một đoạn lệnh thường phải được chép
lặp lại mỗi khi chúng ta dùng trong nhiều chương trình do đó chương trình dài dòng,
logic của chương trình khó hiểu. Chương trình được điều khiển để nhảy đến nhiều chỗ
mà thường không có sự giải thích rõ ràng, làm thế nào để chương trình đến chỗ cần
thiết hoặc tại sao như vậy. Ngôn ngữ lập trình tuyến tính không có khả năng kiểm soát
phạm vi nhìn thấy của các dữ liệu. Mọi dữ liệu trong chương trình đều là dữ liệu toàn
cục nghĩa là chúng có thể bị sửa đổi ở bất kỳ phần nào của chương trình. Việc dò tìm
các thay đổi không mong muốn đó của các phần tử dữ liệu trong một dãy mã lệnh dài
và vòng vèo đã từng làm cho các lập trình viên rất mất thời gian.
Tóm tắt nội dung tài liệu: Bài giảng Lập trình hướng đối tượng - Võ Đức Lân
TRƯỜNG ĐẠI HỌC PHẠM VĂN ĐỒNG KHOA CÔNG NGHỆ THÔNG TIN VÕ ĐỨC LÂN BÀI GIẢNG LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG (Dùng cho sinh viên các lớp đại học Công nghệ thông tin, Sư phạm tin) Quảng Ngãi, 06 - 2017 TRƯỜNG ĐẠI HỌC PHẠM VĂN ĐỒNG KHOA CÔNG NGHỆ THÔNG TIN VÕ ĐỨC LÂN BÀI GIẢNG LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG (Dùng cho sinh viên các lớp đại học Công nghệ thông tin, Sư phạm tin) Lư hành nội bộ LỜI NÓI ĐẦU Lập trình cấu trúc là phương pháp tổ chức, phân chia chương trình thành các hàm, thủ tục, chúng được dùng để xử lý dữ liệu nhưng lại tách rời các cấu trúc dữ liệu. Thông qua các ngôn ngữ Foxpro, Pascal, C đa số những người làm Tin học đã khá quen biết với phương pháp lập trình này. Lập trình hướng đối tượng dựa trên việc tổ chức chương trình thành các lớp. Khác với hàm và thủ tục, lớp là một đơn vị bao gồm cả dữ liệu và các phương thức xử lý. Vì vậy lớp có thể mô tả các thực thể một cách chân thực, đầy đủ cả phần dữ liệu và yêu cầu quản lý. Tư tưởng lập trình hướng đối tượng được áp dụng cho hầu hết các ngôn ngữ mới chạy trên môi trường Windows như Microsoft Access, Visual Basic, Visual C. Vì vậy việc nghiên cứu phương pháp lập trình mới này là rất cần thiết đối với tất cả những người quan tâm, yêu thích Tin học. Bài giảng này sẽ trình bày một cách hệ thống các khái niệm của lập trình hướng đối tượng được cài đặt trong C++ như lớp, đối tượng, sự thừa kế, tính tương ứng bội và các khả năng mới trong xây dựng, sử dụng hàm như: đối tham chiếu, đối mặc định, hàm trùng tên, hàm toán tử, hàm bạn. Các ví dụ và bài tập thực hành được viết code trên môi trường Dev-C++. Bài giảng được thiết kế dành cho sinh viên đại học các ngành Công nghệ thông tin và Sư phạm tin học. Nội dung được xây dựng theo đúng chương trình chi tiết của học phần môn Lập trình hướng đối tượng đã được ban hành. Hy vọng bài giảng này sẽ là tài liệu bổ ích dành cho sinh viên ngành Công nghệ thông tin và Sư phạm tin học của trường Đại học Phạm Văn Đồng. Tuy nhiên do hạn chế về thời gian nên bài giảng chắc chắn còn nhiều thiếu sót. Mong nhận được nhiều ý kiến đóng góp từ các bạn đọc, đồng nghiệp và sinh viên. Tác giả Võ Đức Lân Trang 1 CHƯƠNG 1: CÁC KHÁI NIỆM CƠ SỞ LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG Chương 1 trình bày những vấn đề sau: Thảo luận về cách tiếp cận hướng đối tượng. Các khái niệm cơ sở của phương pháp hướng đối tượng. Các bước cần thiết để thiết kế chương trình theo hướng đối tượng. Các ưu điểm của lập trình hướng đối tượng. Các ngôn ngữ hướng đối tượng. Một số ứng dụng của lập trình hướng đối tượng. 1.1. Giới thiệu Lập trình hướng đối tượng (Object-Oriented Programming, viết tắt là OOP) là một phương pháp mới trên bước đường tiến hóa của việc lập trình máy tính, nhằm làm cho chương trình trở nên linh hoạt, tin cậy và dễ phát triển. Tuy nhiên để hiểu được OOP là gì, chúng ta hãy bắt đầu từ lịch sử của quá trình lập trình – xem xét OOP đã tiến hóa như thế nào. 1.1.1. Lập trình tuyến tính Máy tính đầu tiên được lập trình bằng mã nhị phân, sử dụng các công tắt cơ khí để nạp chương trình. Cùng với sự xuất hiện của các thiết bị lưu trữ lớn và bộ nhớ máy tính có dung lượng lớn nên các ngôn ngữ lập trình cấp cao đầu tiên được đưa vào sử dụng . Thay vì phải suy nghĩ trên một dãy các bit và byte, lập trình viên có thể viết một loạt lệnh gần với tiếng Anh và sau đó chương trình dịch thành ngôn ngữ máy. Các ngôn ngữ lập trình cấp cao đầu tiên được thiết kế để lập các chương trình làm các công việc tương đối đơn giản như tính toán. Các chương trình ban đầu chủ yếu liên quan đến tính toán và không đòi hỏi gì nhiều ở ngôn ngữ lập trình. Hơn nữa phần lớn các chương trình này tương đối ngắn, thường ít hơn 100 dòng. Khi khả năng của máy tính tăng lên thì khả năng để triển khai các chương trình phức tạp hơn cũng tăng lên. Các ngôn ngữ lập trình ngày trước không còn thích hợp đối với việc lập trình đòi hỏi cao hơn. Các phương tiện cần thiết để sử dụng lại các phần mã chương trình đã viết hầu như không Trang 2 có trong ngôn ngữ lập trình tuyến tính. Thật ra, một đoạn lệnh thường phải được chép lặp lại mỗi khi chúng ta dùng trong nhiều chương trình do đó chương trình dài dòng, logic của chương trình khó hiểu. Chương trình được điều khiển để nhảy đến nhiều chỗ mà thường không có sự giải thích rõ ràng, làm thế nào để chương trình đến chỗ cần thiết hoặc tại sao như vậy. Ngôn ngữ lập trình tuyến tính không có khả năng kiểm soát phạm vi nhìn thấy của các dữ liệu. Mọi dữ liệu trong chương trình đều là dữ liệu toàn cục nghĩa là chúng có thể bị sửa đổi ở bất kỳ phần nào của chương trình. Việc dò tìm các thay đổi không mong muốn đó của các phần tử dữ liệu trong một dãy mã lệnh dài và vòng vèo đã từng làm cho các lập trình viên rất mất thời gian. 1.1.2. Lập trình cấu trúc Rõ ràng là các ngôn ngữ mới với các tính năng mới cần phải được phát triển để có thể tạo ra các ứng dụng tinh vi hơn. Vào cuối các năm trong 1960 và 1970, ngôn ngữ lập trình có cấu trúc ra đời. Các chương trình có cấu trúc được tổ chức theo các công việc mà chúng thực hiện. Về bản chất, chương trình chia nhỏ thành các chương trình con riêng rẽ (còn gọi là hàm hay thủ tục) thực hiện các công việc rời rạc trong quá trình lớn hơn, phức tạp hơn. Các hàm này được giữ càng độc lập với nhau càng nhiều càng tốt, mỗi hàm có dữ liệu và logic riêng.Thông tin được chuyển giao giữa các hàm thông qua các tham số, các hàm có thể có các biến cục bộ mà không một ai nằm bên ngoài phạm vi của hàm lại có thể truy xuất được chúng. Như vậy, các hàm có thể được xem là các chương trình con được đặt chung với nhau để xây dựng nên một ứng dụng. Mục tiêu là làm sao cho việc triển khai các phần mềm dễ dàng hơn đối với các lập trình viên mà vẫn cải thiện được tính tin cậy và dễ bảo quản chương trình. Một chương trình có cấu trúc được hình thành bằng cách bẻ gãy các chức năng cơ bản của chương trình thành các mảnh nhỏ mà sau đó trở thành các hàm. Bằng cách cô lập các công việc vào trong các hàm, chương trình có cấu trúc có thể làm giảm khả năng của một hàm này ảnh hưởng đến một hàm khác. Việc này cũng làm cho việc tách các vấn đề trở nên dễ dàng hơn. Sự gói gọn này cho phép chúng ta có thể viết các chương trình sáng sủa hơn và giữ được điều khiển trên từng hàm. Các biến toàn cục không còn nữa và được thay Trang 3 thế bằng các tham số và biến cục bộ có phạm vi nhỏ hơn và dễ kiểm soát hơn. Cách tổ chức tốt hơn này nói lên rằng chúng ta có khả năng quản lý logic của cấu trúc chương trình, làm cho việc triển khai và bảo dưỡng chương trình nhanh hơn và hữu hiện hơn và hiệu quả hơn. Một khái niệm lớn đã được đưa ra trong lập trình có cấu trúc là sự trừu tượng hóa (Abstraction). Sự trừu tượng hóa có thể xem như khả năng quan sát một sự việc mà không cần xem xét đến các chi tiết bên trong của nó. Trong một chương trình có cấu trúc, chúng ta chỉ cần biết một hàm đã cho có thể làm được một công việc cụ thể gì là đủ. Còn làm thế nào mà công việc đó lại thực hiện được là không quan trọng, chừng nào hàm còn tin cậy được thì còn có thể dùng nó mà không cần phải biết nó thực hiện đúng đắn chức năng của mình như thế nào. Điều này gọi là sự trừu tượng hóa theo chức năng (Functional abstraction) và là nền tảng của lập trình có cấu trúc. Ngày nay, các kỹ thuật thiết kế và lập trình có cấu trúc được sử rộng rãi. Gần như mọi ngôn ngữ lập trình đều có các phương tiện cần thiết để cho phép lập trình có cấu trúc. Chương trình có cấu trúc dễ viết, dễ bảo dưỡng hơn các chương trình không cấu trúc. Sự nâng cấp như vậy cho các kiểu dữ liệu trong các ứng dụng mà các lập trình viên đang viết cũng đang tiếp tục diễn ra. Khi độ phức tạp của một chương trình tăng lên, sự phụ thuộc của nó vào các kiểu dữ liệu cơ bản mà nó xử lý cũng tăng theo. Vấn đề trở rõ ràng là cấu trúc dữ liệu trong chương trình quan trọng chẳng kém gì các phép toán thực hiện trên chúng. Điều này càng trở rõ ràng hơn khi kích thước của chương trình càng tăng. Các kiểu dữ liệu được xử lý trong nhiều hàm khác nhau bên trong một chương trình có cấu trúc. Khi có sự thay đổi trong các dữ liệu này thì cũng cần phải thực hiện cả các thay đổi ở mọi nơi có các thao tác tác động trên chúng. Đây có thể là một công việc tốn thời gian và kém hiệu quả đối với các chương trình có hàng ngàn dòng lệnh và hàng trăm hàm trở lên. Một yếu điểm nữa của việc lập trình có cấu trúc là khi có nhiều lập trình viên làm việc theo nhóm cùng một ứng dụng nào đó. Trong một chương trình có cấu trúc, các lập trình viên được phân công viết một tập hợp các hàm và các kiểu dữ liệu. Vì có nhiều lập trình viên khác nhau quản lý các hàm riêng, có liên quan đến các Trang 4 kiểu dữ liệu dùng chung nên các thay đổi mà lập trình viên tạo ra trên một phần tử dữ liệu sẽ làm ảnh hưởng đến công việc của tất cả các người còn lại trong nhóm. Mặc dù trong bối cảnh làm việc theo nhóm, việc viết các chương trình có cấu trúc thì dễ dàng hơn nhưng sai sót trong việc trao đổi thông tin giữa các thành viên trong nhóm có thể dẫn tới hậu quả là mất rất nhiều thời gian để sửa chữa chương trình. 1.1.3. Trừu tượng hóa dữ liệu Sự trừu tượng hóa dữ liệu (Data abstraction) tác động trên các dữ liệu cũng tương tự như sự trừu tượng hóa theo chức năng. Khi có trừu tượng hóa dữ liệu, các cấu trúc dữ liệu và các phần tử có thể được sử dụng mà không cần bận tâm đến các chi tiết cụ thể. Chẳng hạn như các số dấu chấm động đã được trừu tượng hóa trong tất cả các ngôn ngữ lập trình, Chúng ta không cần quan tâm cách biểu diễn nhị phân chính xác nào cho số dấu chấm động khi gán một giá trị, cũng không cần biết tính bất thường của phép nhân nhị phân khi nhân các giá trị dấu chấm động. Điều quan trọng là các số dấu chấm động hoạt động đúng đắn và hiểu được. Sự trừu tượng hóa dữ liệu giúp chúng ta không phải bận tâm về các chi tiết không cần thiết. Nếu lập trình viên phải hiểu biết về tất cả các khía cạnh của vấn đề, ở mọi lúc và về tất cả các hàm của chương trình thì chỉ ít hàm mới được viết ra, may mắn thay trừu tượng hóa theo dữ liệu đã tồn tại sẵn trong mọi ngôn ngữ lập trình đối với các dữ liệu phức tạp như số dấu chấm động. Tuy nhiên chỉ mới gần đây, người ta mới phát triển các ngôn ngữ cho phép chúng ta định nghĩa các kiểu dữ liệu trừu tượng riêng. 1.1.4. Lập trình hướng đối tượng Khái niệm lập trình hướng đối tượng (LTHĐT) được xây dựng trên nền tảng của khái niệm lập trình có cấu trúc và sự trừu tượng hóa dữ liệu. Sự thay đổi căn bản ở chỗ, một chương trình hướng đối tượng được thiết kế xoay quanh dữ liệu mà chúng ta có thể làm việc trên đó, hơn là theo bản thân chức năng của chương trình. Điều này hoàn toàn tự nhiên một khi chúng ta hiểu rằng mục tiêu của chương trình là xử lý dữ liệu. Suy cho cùng, công việc mà máy tính thực hiện vẫn thường được gọi là xử lý dữ Trang 5 liệu. Dữ liệu và thao tác liên kết với nhau ở một mức cơ bản (còn có thể gọi là mức thấp), mỗi thứ đều đòi hỏi ở thứ kia có mục tiêu cụ thể, các chương trình hướng đối tượng làm tường minh mối quan hệ này. Lập trình hướng đối tượng (Object Oriented Programming - gọi tắt là OOP) hay chi tiết hơn là Lập trình định hướng đối tượng, chính là phương pháp lập trình lấy đối tượng làm nền tảng để xây dựng thuật giải, xây dựng chương trình. Thực chất đây không phải là một phương pháp mới mà là một cách nhìn mới trong việc lập trình. Để phân biệt, với phương pháp lập trình theo kiểu cấu trúc mà chúng ta quen thuộc trước đây, hay còn gọi là phương pháp lập trình hướng thủ tục (Procedure-Oriented Programming), người lập trình phân tích một nhiệm vụ lớn thành nhiều công việc nhỏ hơn, sau đó dần dần chi tiết, cụ thể hoá để được các vấn đề đơn giản, để tìm ra cách giải quyết vấn đề dưới dạng những thuật giải cụ thể rõ ràng qua đó dễ dàng minh hoạ bằng ngôn ngữ giải thuật (hay còn gọi các thuật giải này là các chương trình con). Cách thức phân tích và thiết kế như vậy chúng ta gọi là nguyên lý lập trình từ trên xuống (top-down), để thể hiện quá trình suy diễn từ cái chung cho đến cái cụ thể. Các chương trình con là những chức năng độc lập, sự ghép nối chúng lại với nhau cho chúng ta một hệ thống chương trình để giải quyết vấn đề đặt ra. Chính vì vậy, cách thức phân tích một hệ thống lấy chương trình con làm nền tảng, chương trình con đóng vai trò trung tâm của việc lập trình, được hiểu như phương pháp lập trình hướg về thủ tục. Tuy nhiên, khi phân tích để thiết kế một hệ thống không nhất thiết phải luôn luôn suy nghĩ theo hướng “làm thế nào để giải quyết công việc”, chúng ta có thể định hướng tư duy theo phong cách “với một số đối tượng đã có, phải làm gì để giải quyết được công việc đặt ra” hoặc phong phú hơn, “làm cái gì với một số đối tượng đã có đó”, từ đó cũng có thể giải quyết được những công việc cụ thể. Với phương pháp phân tích trong đó đối tượng đóng vai trò trùng tâm của việc lập trình như vậy, người ta gọi là nguyên lý lập trình từ dưới lên (Bottom-up). Lập trình hướng đối tượng liên kết cấu trúc dữ liệu với các thao tác, theo cách mà tất cả thường nghĩ về thế giới quanh mình. Chúng ta thường gắn một số các hoạt động cụ thể với một loại hoạt động nào đó và đặt các giả thiết của mình trên các quan hệ đó. Trang 6 Ví dụ: Chúng ta biết rằng một chiếc xe có các bánh xe, di chuyển được và có thể đổi hướng của nó bằng cách quẹo tay lái. Tương tự như thế, một cái cây là một loại thực vật có thân gỗ và lá. Một chiếc xe không phải là một cái cây, mà cái cây không phải là một chiếc xe, chúng ta có thể giả thiết rằng cái mà chúng ta có thể làm được với một chiếc xe thì không thể làm được với một cái cây. Chẳng hạn, thật là vô nghĩa khi muốn lái một cái cây, còn chiếc xe thì lại chẳng lớn thêm được khi chúng ta tưới nước cho nó. Lập trình hướng đối tượng cho phép chúng ta sử dụng các quá trình suy nghĩ như vậy với các khái niệm trừu tượng được sử dụng trong các chương trình máy tính. Một mẫu tin (record) nhân sự có thể được đọc ra, thay đổi và lưu trữ lại; còn số phức thì có thể được dùng trong các tính toán. Tuy vậy không thể nào lại viết một số phức vào tập tin làm mẫu tin nhân sự và ngược lại hai mẫu tin nhân sự lại không thể cộng với nhau được. Một chương trình hướng đối tượng sẽ xác định đặc điểm và hành vi cụ thể của các kiểu dữ liệu, điều đó cho phép chúng ta biết một cách chính xác rằng chúng ta có thể có được những gì ở các kiểu dữ liệu khác nhau. Điểm căn bản của phương pháp LTHĐT là thiết kế chương trình xoay quanh dữ liệu của hệ thống. Nghĩa là các thao tác xử lý của hệ thống được gắn liền với dữ liệu và như vậy khi có sự thay đổi của cấu trúc dữ liệu thì chỉ ảnh hưởng đến một số ít các phương thức xử lý liên quan. LTHĐT không cho phép dữ liệu chuyển động tự do trong hệ thống. Dữ liệu được gắn chặt với từng phương thức thành các vùng riêng mà các phương thức đó tác động lên và nó được bảo vệ để cấm việc truy nhập tùy tiện từ bên ngoài. LTHĐT cho phép phân tích bài toán thành tập các thực thể được gọi là các đối tượng và sau đó xây dựng các dữ liệu cùng với các phương thức xung quanh các đối tượng đó. ... huôn hình hàm có trùng tên với lời gọi; nếu chỉ có một tương ứng chính xác được tìm thấy, hàm thể hiện tương ứng được sản sinh và vấn đề được giải quyết; còn nếu có nhiều hơn một khuôn hình hàm điều đó sẽ gây ra lỗi biên dịch và quá trình dừng. Cuối cùng, nếu không có khuôn hình hàm phù hợp, ta kiểm tra một lần nữa tất cả các hàm thông thường cùng tên với lời gọi. Trong trường hợp này chúng ta phải tìm kiếm sự tương ứng dựa vào cả các chuyển kiểu cho phép trong C/C++. 6.2. Khuôn hình lớp 6.2.1. Khái niệm Bên cạnh khái niệm khuôn hình hàm, C++ còn cho phép định nghĩa khuôn hình lớp. Cũng giống như khuôn hình hàm, ở đây ta chỉ cần viết định nghĩa các khuôn hình lớp một lần rồi sau đó có thể áp dụng chúng với các kiểu dữ liệu khác nhau để được các lớp thể hiện khác nhau. 6.2.2. Tạo một khuôn hình lớp Trong chương trước ta đã định nghĩa cho lớp SO, giá trị các số là kiểu int. Nếu ta muốn làm việc với các số kiểi float, double,... thì ta phải định nghĩa lại một lớp khác tương tự, trong đó kiểu dữ liệu int cho dữ liệu giatri sẽ được thay bằng float,double,... Để tránh sự trùng lặp trong các tình huống như trên, chương trình dịch C++ cho phép định nghĩa một khuôn hình lớp và sau đó, áp dụng khuôn hình lớp này với các kiểu dữ liệu khác nhau để thu được các lớp thể hiện như mong muốn. Ví dụ : template class SO { kieuso giatri; public : SO (kieuso x =0); void Hienthi(); ... Trang 138 }; Cũng giống như các khuôn hình hàm, template xác định rằng đó là một khuôn hình trong đó có một tham số kỉêu kieuso . C++ sử dụng từ khoá class chỉ để nói rằng kieuso đại diện cho một kiểu dữ liệu nào đó. Việc định nghĩa các hàm thành phần của khuôn hình lớp, người ta phân biệt hai trường hợp: Khi hàm thành phần được định nghĩa bên trong định nghĩa lớp thì không có gì thay đổi. Khi hàm thành phần được định nghĩa bên ngoài lớp, khi đó cần phải nhắc lại cho chương trình biết các tham số kiểu của khuôn hình lớp, có nghĩa là phải nhắc lại template chẳng hạn, trước định nghĩa hàm. Ví dụ hàm Hienthi() được định nghĩa ngoài lớp: template void SO::Hienthi() { cout <<giatri; } 6.2.3. Sử dụng khuôn hình lớp Sau khi một khuôn hình lớp đã được định nghĩa, nó sẽ được dùng để khai báo các đối tượng theo dạng sau : Tên_lớp Tên_đối_tượng; Ví dụ câu lệnh khai báo SO so1; sẽ khai báo một đối tượng so1 có thành phần dữ liệu giatri có kiểu nguyên int. SO có vai trò như một kiểu dữ liệu lớp; người ta gọi nó là một lớp thể hiện của khuôn hình lớp SO. Một cách tổng quát, khi áp dụng một kiểu dữ liệu nào đó với khuôn hình lớp SO ta sẽ có được một lớp thể hiện tương ứng với kiểu dữ liệu. Tương tự với các khai báo SO so2; cho phép khai báo một đối tượng Trang 139 so2 mà thành phần dữ liệu giatri có kiểu float. Ví dụ 6.5 #include #include using namespace std; template class SO { kieuso giatri; public : SO (kieuso x =0); void Hienthi(){ cout<<"Gia tri cua so :"<<giatri<<endl; } }; main(){ SO soint(10); soint.Hienthi(); SO sofl(25.4); sofl.Hienthi(); } Kết quả trên màn hình là: Gia tri cua so : 10 Gia tri cua so : 25.4 6.2.4. Các tham số trong khuôn hình lớp Hoàn toàn giống như khuôn hình hàm, các khuôn hình lớp có thể có các tham số kiểu và tham số biểu thức. Ví dụ một lớp mà các thành phần có các kiểu dữ liệu khác nhau được khai báo theo dạng: template class { T x; U y; Trang 140 ..... Z fct1 (int); ..... }; Một lớp thể hiện được khai báo bằng cách liệt kê đằng sau tên khuôn hình lớp các tham số thực, là tên kiểu dữ liệu, với số lượng bằng các tham số trong danh sách của khuôn hình lớp (template) 6.2.5. Tóm tắt Khuôn hình lớp/hàm là phương tiện mô tả ý nghĩa của một lớp/hàm tổng quát, còn lớp/hàm thể hiện là một bản sao của khuôn hình tổng quát với các kiểu dữ liệu cụ thể. Các khuôn hình lớp/hàm thường được tham số hoá. Tuy nhiên vẫn có thể sử dụng các kiểu dữ liệu cụ thể trong các khuôn hình lớp/hàm nếu cần. Trang 141 Bài tập 1. Viết khuôn hình hàm để tìm số lớn nhất của hai số bất kỳ 2. Viết khuôn hình hàm để trả về giá trị trung bình của một mảng, các tham số hình thức của hàm này là tên mảng, kích thước mảng. 3. Cài đặt hàng đợi templete. 4. Viết khuôn hình hàm để sắp xếp kiểu dữ liệu bất kỳ. 5. Xây dựng khuôn hình lớp cho các tọa độ điểm trong mặt phẳng, các thành phần dữ liệu của lớp là toadox, toadoy. 6. Xây dựng khuôn hình lớp cho vector để quản lý các vector có thành phần có kiểu tùy ý. Trang 142 Tài liệu tham khảo [1] Ivar Jacobson, Object - Oriented Software Engineering, Addison-Wesley Publishing Company, 1992. [2] Michael Blaha, William Premerlani, Object - Oriented Modeling and Design for Database Applications, Prentice Hall, 1998. [2] Phạm Văn ất, C++ và Lập trình hướng đối tượng, NXB Khoa học và Kỹ thuật, 1999. [3] Đoàn Văn Ban, Phân tích và thiết kế hướng đối tượng, NXB Khoa học và Kỹ thuật, 1997. [4] Nguyễn Thanh Thủy, Lập trình hướng đối tượng với C++, NXB Khoa học và Kỹ thuật, 1999. Trang 143 MỤC LỤC LỜI NÓI ĐẦU CHƯƠNG 1: CÁC KHÁI NIỆM CƠ SỞ LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG .... 1 1.1. Giới thiệu ............................................................................................... 1 1.1.1. Lập trình tuyến tính .......................................................................... 1 1.1.2. Lập trình cấu trúc ............................................................................. 2 1.1.3. Trừu tượng hóa dữ liệu ..................................................................... 4 1.1.4. Lập trình hướng đối tượng ................................................................ 4 1.2. Các khái niệm cơ bản của lập trình hướng đối tượng .............................. 7 1.2.1. Đối tượng ......................................................................................... 7 1.2.2. Lớp ................................................................................................... 7 1.2.3. Sự đóng gói (Encapsulation) ............................................................. 8 1.2.4. Tính kế thừa (Inheritance) ................................................................ 9 1.2.5. Tương ứng bội .................................................................................. 9 1.2.6. Liên kết động ................................................................................. 10 1.2.7. Truyền thông báo ........................................................................... 10 1.3. Các bước cần thiết để thiết kế chương trình theo hướng đối tượng ........ 11 1.4. Các ưu điểm của lập trình hướng đối tượng .......................................... 11 1.5. Các ngôn ngữ hướng đối tượng ............................................................. 12 1.6. Một số ứng dụng của LTHĐT ............................................................... 12 CHƯƠNG 2: CÁC MỞ RỘNG CỦA NGÔN NGỮ LẬP TRÌNH C++ ................ 14 2.1. Giới thiệu chung về C++ ...................................................................... 14 2.2. Một số mở rộng của C++ so với C ........................................................ 14 2.2.1. Các từ khóa mới của C++ ............................................................... 14 2.2.2. Cách ghi chú thích .......................................................................... 14 2.2.3. Cách chuyển đổi kiểu dữ liệu.......................................................... 15 2.2.4. Khai báo biến ................................................................................. 16 2.3. Vào ra trong C++ .................................................................................. 17 Trang 144 2.3.1. Xuất dữ liệu .................................................................................... 17 2.3.2. Nhập dữ liệu ................................................................................... 17 2.3.3. Định dạng khi in ra màn hình ......................................................... 18 2.4. Cấp phát và giải phóng bộ nhớ.............................................................. 20 2.5. Biến tham chiếu .................................................................................... 23 2.6. Hằng tham chiếu ................................................................................... 25 2.7. Truyền tham số cho hàm theo tham chiếu ............................................. 25 2.8. Hàm trả về giá trị tham chiếu ................................................................ 28 2.9. Hàm với tham số có giá trị mặc định..................................................... 29 2.10. Các hàm nội tuyến (inline) .................................................................. 32 2.11. Hàm tải bội ......................................................................................... 33 CHƯƠNG 3: LỚP ................................................................................................ 37 3.1. Định nghĩa lớp ...................................................................................... 37 3.2. Tạo lập đối tượng ................................................................................. 39 3.3. Truy nhập tới các thành phần của lớp ................................................... 39 3.4. Con trỏ đối tượng ................................................................................. 44 3.5. Con trỏ this ........................................................................................... 46 3.5.1. Con trỏ this là đối thứ nhất của phương thức .................................. 46 3.5.2. Tham số ứng với đối con trỏ this .................................................... 46 3.6. Hàm bạn ............................................................................................... 47 3.7. Dữ liệu thành phần tĩnh và hàm thành phần tĩnh ................................... 55 3.7.1. Dữ liệu thành phần tĩnh .................................................................. 55 3.7.2. Hàm thành phần tĩnh ...................................................................... 58 3.8. Hàm tạo (constructor) ........................................................................... 60 3.9. Hàm tạo sao chép.................................................................................. 67 3.9.1. Hàm tạo sao chép mặc định ............................................................ 67 3.9.2. Hàm tạo sao chép ........................................................................... 69 3.10. Hàm hủy (destructor) .......................................................................... 75 Trang 145 3.10.1. Công dụng của hàm huỷ ............................................................... 75 3.10.2. Hàm huỷ mặc định ....................................................................... 76 3.10.3. Quy tắc viết hàm huỷ .................................................................... 76 CHƯƠNG 4 : TOÁN TỬ TẢI BỘI ...................................................................... 79 4.1. Định nghĩa toán tử tải bội ..................................................................... 79 4.2. Một số lưu ý khi xây dựng toán tử tải bội ............................................. 80 4.3. Một số ví dụ ......................................................................................... 80 4.4. Định nghĩa chồng các toán tử ++ , -- .................................................... 87 4.5. Định nghĩa chồng toán tử > ...................................................... 90 CHƯƠNG 5: KẾ THỪA ...................................................................................... 93 5.1. Giới thiệu ............................................................................................. 93 5.2. Đơn kế thừa .......................................................................................... 94 5.2.1. Định nghĩa lớp dẫn xuất từ một lớp cơ sở ....................................... 94 5.2.2. Truy nhập các thành phần trong lớp dẫn xuất ................................. 95 5.2.3. Định nghĩa lại các hàm thành phần của lớp cơ sở trong lớp dẫn xuất ............................................................................................................................ 97 5.2.4. Hàm tạo đối với tính kế thừa ........................................................ 101 5.2.5. Hàm hủy đối với tính kế thừa ....................................................... 103 5.3. Đa kế thừa .......................................................................................... 104 5.3.1. Định nghĩa lớp dẫn xuất từ nhiều lớp cơ sở .................................. 104 5.3.2. Một số ví dụ về đa kế thừa ............................................................ 104 5.4. Hàm ảo ............................................................................................... 112 5.4.1 Đặt vấn đề ..................................................................................... 112 5.4.2. Định nghĩa hàm ảo ....................................................................... 114 5.4.3. Quy tắc gọi hàm ảo ....................................................................... 117 5.4.5. Quy tắc gán địa chỉ đối tượng cho con trỏ lớp cơ sở ..................... 117 5.5. Lớp cơ sở ảo ....................................................................................... 120 5.5.1. Khai báo lớp cơ sở ảo ................................................................... 120 Trang 146 5.5.2. Hàm tạo và hàm hủy đối với lớp cơ sở ảo ........................................ 125 CHƯƠNG 6: KHUÔN HÌNH ............................................................................ 132 6.1. Khuôn hình hàm ................................................................................. 132 6.1.1. Khái niệm ..................................................................................... 132 6.1.2. Tạo một khuôn hình hàm .............................................................. 132 6.1.3. Sử dụng khuôn hình hàm .............................................................. 133 6.1.4. Các tham số kiểu của khuôn hình hàm .......................................... 134 6.1.5. Định nghĩa chồng các khuôn hình hàm ......................................... 136 6.2. Khuôn hình lớp ................................................................................... 137 6.2.1. Khái niệm ..................................................................................... 137 6.2.2. Tạo một khuôn hình lớp ............................................................... 137 6.2.3. Sử dụng khuôn hình lớp ............................................................... 138 6.2.4. Các tham số trong khuôn hình lớp ................................................ 139 6.2.5. Tóm tắt ......................................................................................... 140 Tài liệu tham khảo ............................................................................................. 142
File đính kèm:
- bai_giang_lap_trinh_huong_doi_tuong_vo_duc_lan.pdf