Bài giảng Lập trình hướng đối tượng
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óm tắt nội dung tài liệu: Bài giảng Lập trình hướng đối tượng
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 ... 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.pdf

