Download as pdf or txt
Download as pdf or txt
You are on page 1of 56

Trang 1

Nâng cao
Mô-đun hóa
Kỹ thuật

Trong chương này, bạn sẽ tìm hiểu về:


Các phần của một phương pháp
Phương thức không có tham số
Các phương thức yêu cầu tham số
Các phương thức trả về một giá trị
Truyền mảng cho các phương thức
Quá tải các phương pháp
Sử dụng các phương pháp xác định trước
Các vấn đề về thiết kế phương pháp, bao gồm ẩn việc triển khai,
sự gắn kết và khớp nối
Đệ quy
Trang 2

Các phần của một phương pháp


Trong các ngôn ngữ lập trình hướng đối tượng như Java và C #, các mô-đun thường
được gọi là các phương thức. Trong Chương 2, bạn đã học về nhiều tính năng của các phương pháp và phần lớn
từ vựng liên quan đến chúng. Ví dụ:
Một phương pháp là một mô-đun chương trình có chứa một loạt các báo cáo rằng thực hiện một nhiệm vụ;
bạn có thể gọi hoặc gọi một phương thức từ một chương trình hoặc phương thức khác. Chương trình gọi điện
hoặc phương thức là ứng dụng khách của phương thức được gọi .

Bất kỳ chương trình nào cũng có thể chứa vô số phương thức và mỗi phương thức có thể
gọi là không giới hạn số lần.

Các quy tắc đặt tên cho các phương thức khác nhau trong mọi ngôn ngữ lập trình, nhưng chúng
thường tương tự như các quy tắc của ngôn ngữ cho tên biến. Trong văn bản này, tên phương thức là
theo sau bởi một tập hợp các dấu ngoặc đơn.
Một phương thức phải bao gồm một tiêu đề phương thức (đôi khi còn được gọi là khai báo phương thức),
trong đó chứa thông tin nhận dạng về phương pháp.

Một phương thức bao gồm một thân phương thức . Phần thân chứa phần triển khai của phương pháp —the
các câu lệnh thực hiện các nhiệm vụ của phương thức.

Một câu lệnh trả về phương thức trả về điều khiển cho phương thức gọi sau một phương thức
thực thi. Mặc dù các phương thức có nhiều câu lệnh trả về được cho phép trong nhiều
ngôn ngữ lập trình, thông lệ đó không được khuyến khích. Lập trình có cấu trúc
yêu cầu rằng một phương thức phải chứa một điểm vào duy nhất và một điểm thoát duy nhất.
Do đó, một phương thức chỉ nên có một câu lệnh trả về và nó phải là câu lệnh cuối cùng
tuyên bố.

Các biến và hằng số có thể được khai báo trong một phương thức. Một mục dữ liệu được khai báo trong
phương thức là cục bộ của phương thức đó, có nghĩa là nó nằm trong phạm vi hoặc chỉ được công nhận trong phạm vi đó
phương pháp.

Đối lập với địa phương là toàn cầu. Khi một mục dữ liệu được biết đến với tất cả các phương thức của chương trình
hoặc các mô-đun, nó là một mục dữ liệu toàn cầu . Nói chung, các lập trình viên thích các mục dữ liệu cục bộ
bởi vì khi dữ liệu được chứa trong phương thức sử dụng nó, thì phương thức này càng
di động và ít bị lỗi. Trong Chương 2, bạn đã học được rằng khi một phương thức
được mô tả là có thể di động, nó có thể dễ dàng được chuyển sang ứng dụng khác và sử dụng ở đó.

Các phương thức có thể có danh sách tham số cung cấp thông tin chi tiết về dữ liệu được truyền vào các phương thức.
Những danh sách này không bắt buộc.
Các phương thức có kiểu trả về cung cấp thông tin về dữ liệu mà phương thức trả về. Trong
một số ngôn ngữ, như C ++, kiểu trả về mặc định được ngụ ý nếu không có kiểu trả về nào được liệt kê.
Tham khảo nhanh 9-1 cho thấy các phần quan trọng của một phương pháp. Bạn tìm hiểu thêm về những phần này trong
phần còn lại của chương này.
Trang 3

THAM KHẢO NHANH 9-1 Giải phẫu của một phương pháp
Các quy tắc tạo tên phương thức tương tự
Nếu một phương thức trả về dữ liệu để gọi nó quy tắc tạo tên biến. phương pháp
, sau đó là kiểu dữ liệu cho tên được theo sau bởi dấu ngoặc đơn.
giá trị trả về được đặt tên ở đây.

Dòng này là
tiêu đề phương thức. returnType methodName (danh sách tham số)

các câu lệnh


Nếu một phương thức yêu cầu dữ liệu
trở về được chuyển vào, các mục dữ liệu
Dòng này là sự trở lại và các loại của chúng được liệt kê
tuyên bố. Nếu phương pháp giữa các dấu ngoặc đơn trong
trả về một giá trị, giá trị tiêu đề phương thức.
Các câu lệnh trong một phương thức
sẽ được đặt tên theo
tạo thành phần thân của phương thức.
từ khóa trở lại.
Các biến được khai báo ở đây là cục bộ
đối với phương pháp.

HAI SỰ THẬT & MỘT LỜI NÓI DỐI


Các phần của một phương pháp

1. Một chương trình có thể chứa vô số phương thức, nhưng mỗi phương thức có thể
chỉ được gọi một lần.

2. Một phương thức bao gồm phần đầu và phần thân.

3. Các biến và hằng số nằm trong phạm vi bên trong hoặc cục bộ của chỉ phương thức trong đó
chúng được khai báo.

Sử dụng các phương pháp không có tham số


Hình 9-1 cho thấy một chương trình cho phép người dùng nhập ngôn ngữ ưa thích (tiếng Anh hoặc
Tiếng Tây Ban Nha) và sau đó, sử dụng ngôn ngữ đã chọn, yêu cầu người dùng nhập trọng lượng của mình. Các
sau đó chương trình sẽ tính toán trọng lượng của người dùng trên mặt trăng bằng 16,6% trọng lượng của người dùng trên
Trái đất. Chương trình chính chứa các khai báo cho hai biến và một hằng số. Các
chương trình gọi phương thức displayInstructions () , phương thức này chứa biến cục bộ của chính nó và
hằng số vô hình (và do đó không có sẵn) đối với chương trình chính. Phương pháp
nhắc người dùng về chỉ báo ngôn ngữ và hiển thị lời nhắc bằng ngôn ngữ đã chọn.
Hình 9-2 cho thấy một chương trình thực thi điển hình trong môi trường dòng lệnh.
Trang 4

displayInstructions ()
khởi đầu

Tuyên bố
Tuyên bố num langCode
trọng lượng num string ENGLISH_PROMPT = "Vui lòng
num MOON_FACTOR = 0,166 nhập trọng lượng của bạn bằng pound >> "
num moonWeight string SPANISH_PROMPT = "Ưu tiên
entre en su peso enosystems >> "

displayInstructions () đầu ra "1 - tiếng Anh


hoặc 2 - Espanol >> "

trọng lượng đầu vào đầu vào


langCode

moonWeight = trọng lượng *


MOON_FACTOR
Không Đúng
langCode = 1?

đầu ra "Cân nặng của bạn


trên mặt trăng sẽ
be ", moonWeight
đầu ra đầu ra
SPANISH_PROMPT ENGLISH_PROMPT
dừng lại

khởi đầu
Tuyên bố
trọng lượng num
trở về
num MOON_FACTOR = 0,166
num moonWeight
displayInstructions ()
trọng lượng đầu vào
moonWeight = trọng lượng * MOON_FACTOR
đầu ra "Trọng lượng của bạn trên mặt trăng sẽ là", moonWeight
dừng lại

displayInstructions ()
Tuyên bố
num langCode
string ENGLISH_PROMPT = "Vui lòng nhập trọng lượng của bạn theo đơn vị pound >>"
string SPANISH_PROMPT = "Por favourite entre en su peso enosystems >>"
đầu ra "1 - Tiếng Anh hoặc 2 - Espanol >>"
đầu vào langCode
nếu langCode = 1 thì
đầu ra ENGLISH_PROMPT
khác
đầu ra SPANISH_PROMPT
endif
trở về

Hình 9-1 Một chương trình tính toán trọng lượng của người dùng trên mặt trăng
Trang 5

Trong Chương 2, bạn đã biết rằng cuốn sách này sử dụng một hình chữ nhật có sọc ngang trên đỉnh để biểu diễn
một câu lệnh gọi phương thức trong một lưu đồ. Một số lập trình viên thích sử dụng hình chữ nhật với hai chiều dọc
sọc ở hai bên và bạn nên sử dụng quy ước đó nếu tổ chức của bạn thích nó. Cuốn sách này
bảo lưu hình dạng có hai sọc dọc để biểu thị một phương thức từ thư viện bên ngoài

Hình 9-2 Đầu ra của chương trình tính trọng lượng mặt trăng trong Hình 9-1

Trong Hình 9-1, mỗi chương trình chính và phương thức được gọi chỉ chứa các mục dữ liệu
cần thiết ở cấp địa phương. Chương trình chính không biết về hoặc có quyền truy cập vào
các biến và hằng số langCode , ENGLISH_PROMPT và SPANISH_PROMPT được khai báo cục bộ
trong phương pháp. Tương tự, trong các ngôn ngữ lập trình hiện đại, displayInstructions ()
phương pháp không có kiến thức hoặc quyền truy cập vào trọng lượng , MOON_FACTOR hoặc moonWeight ,
​​
được khai báo trong chương trình chính. Trong chương trình này, không cần
phương pháp để biết về dữ liệu trong khác. Tuy nhiên, đôi khi hai hoặc nhiều phần của một
chương trình yêu cầu quyền truy cập vào cùng một dữ liệu. Khi các phương thức phải chia sẻ dữ liệu, bạn có thể chuyển
dữ liệu vào các phương thức và trả về dữ liệu từ chúng.

Trong chương này, bạn học cách truyền dữ liệu vào và nhận dữ liệu từ các phương thức được gọi. Khi nào
bạn gọi một phương thức từ một chương trình hoặc phương thức khác, bạn nên biết bốn điều:
Phương thức này nói chung hoạt động gì — nói cách khác, bạn nên biết lý do tại sao bạn đang gọi
phương pháp
Tên của phương thức được gọi

Loại thông tin cần gửi đến phương thức nào, nếu có
Loại dữ liệu trả về mong đợi từ phương thức, nếu có
Trang 6

HAI SỰ THẬT & MỘT LỜI NÓI DỐI


Sử dụng các phương pháp không có tham số

1. Khi một phương thức chứa khai báo biến, các biến đó là cục bộ
phương pháp.

2. Giá trị của các biến được khai báo cục bộ


ằ trong một phương thức có thể được sử dụng bởi
phương thức gọi, nhưng không phải bằng các phương thức khác.
3. Trong các ngôn ngữ hiện đại, phương pháp luận thông thường là khai báo các biến cục bộ trong
các phương thức của chúng và chuyển các giá trị của chúng cho các phương thức khác khi cần thiết.

Tạo các phương pháp yêu cầu tham số


Một số phương pháp yêu cầu thông tin được gửi từ bên ngoài. Khi một chương trình vượt qua
mục dữ liệu cho một phương thức, mục dữ liệu là một đối số của phương thức hoặc đơn giản hơn, một
tranh luận. Khi phương thức nhận được mục dữ liệu, nó là một tham số của phương thức hoặc hơn thế nữa
đơn giản là một tham số. Tham số và đối số là những thuật ngữ có liên quan chặt chẽ với nhau. Một phương thức gọi
gửi một đối số đến một phương thức được gọi. Một phương thức được gọi nhận giá trị làm tham số của nó.

Nếu một phương thức không thể nhận các tham số, bạn sẽ phải sử dụng các biến toàn cục hoặc viết một
vô số phương pháp để bao quát mọi tình huống có thể xảy ra. Như một ví dụ thực tế, khi bạn
đặt chỗ nhà hàng, bạn không cần phải sử dụng một phương pháp khác cho mỗi ngày của
năm vào mọi thời điểm có thể trong ngày. Thay vào đó, bạn có thể cung cấp ngày và giờ dưới dạng thông tin
cho người thực hiện phương pháp. Phương pháp ghi lại việc đặt trước được thực hiện
theo cùng một cách thức, bất kể ngày giờ nào được cung cấp.
Như một ví dụ lập trình, nếu bạn thiết kế một phương thức square () nhân một giá trị số
tự nó, bạn nên cung cấp phương thức với một tham số đại diện cho giá trị
bình phương, thay vì phát triển phương thức square1 () bình phương giá trị 1, a square2 ()
phương thức bình phương giá trị 2, v.v. Để gọi một phương thức square () chấp nhận một
, bạn có thể viết một câu lệnh sử dụng một hằng số, chẳng hạn như square (17) hoặc square (86) ,
hoặc một phương thức sử dụng một biến, như hình vuông (inputValue) và cho phép phương thức sử dụng bất kỳ
đối số bạn gửi.
Khi bạn viết khai báo cho một phương thức có thể nhận một tham số, bạn phải cung cấp
một danh sách tham số bao gồm các mục sau đây cho tham số trong phương pháp
dấu ngoặc đơn của khai báo:

Loại tham số
Tên địa phương cho tham số
Trang 7

Tạo các phương pháp yêu cầu tham số

Phần sau của chương này, bạn học cách tạo danh sách tham số với nhiều hơn một tham số.
Tên của một phương thức và danh sách tham số tạo thành chữ ký của phương thức .

Ví dụ: giả sử rằng bạn quyết định cải thiện chương trình trọng lượng mặt trăng trong Hình
9-1 bằng cách làm cho đầu ra cuối cùng thân thiện hơn với người dùng và thêm văn bản giải thích vào
ngôn ngữ đã chọn. Có nghĩa là nếu người dùng có thể yêu cầu một lời nhắc trong một
ngôn ngữ, người dùng sẽ muốn xem giải thích đầu ra bằng cùng một ngôn ngữ.
Tuy nhiên, trong Hình 9-1, biến langCode là cục bộ của displayInstructions ()
và do đó không thể sử dụng trong chương trình chính. Bạn có thể viết lại
lập trình bằng cách thực hiện một số cách tiếp cận:
Bạn có thể viết lại chương trình mà không cần bao gồm bất kỳ phương pháp nào. Bằng cách đó, bạn có thể
nhắc người dùng về tùy chọn ngôn ngữ và hiển thị lời nhắc và kết quả
bằng ngôn ngữ thích hợp. Cách tiếp cận này hoạt động, nhưng bạn sẽ không sử dụng
lợi thế của những lợi ích được cung cấp bởi mô-đun hóa. Những lợi ích đó bao gồm việc
chương trình chính được sắp xếp hợp lý và trừu tượng hơn, đồng thời làm cho displayInstructions ()
phương pháp một đơn vị độc lập có thể dễ dàng được chuyển đến các chương trình khác — cho
ví dụ, các ứng dụng có thể xác định trọng lượng của người dùng trên Sao Thổ hoặc Sao Hỏa.

Bạn có thể giữ lại phương thức displayInstructions () , nhưng hãy tạo ít nhất là langCode
biến toàn cục bằng cách khai báo nó bên ngoài bất kỳ phương thức nào. Nếu bạn thực hiện phương pháp này, bạn
sẽ làm mất một số tính di động của phương thức displayInstructions () vì
mọi thứ nó đã sử dụng sẽ không còn được chứa trong phương thức.
Bạn có thể giữ lại phương thức displayInstructions () như với cục bộ của chính nó
khai báo, nhưng thêm một phần vào chương trình chính cũng yêu cầu người dùng về một
ngôn ngữ để hiển thị kết quả. Điểm bất lợi của phương pháp này là người dùng phải
trả lời cùng một câu hỏi hai lần trong một lần thực hiện chương trình.
Bạn có thể lưu trữ biến chứa mã ngôn ngữ trong chương trình chính để
mà nó có thể được sử dụng để xác định ngôn ngữ kết quả. Bạn cũng có thể giữ lại
phương thức displayInstructions () , nhưng hãy chuyển mã ngôn ngữ cho nó để lời nhắc
sẽ xuất hiện bằng ngôn ngữ thích hợp. Đây là sự lựa chọn tốt nhất vì nó sử dụng
modularity, giữ cho chương trình chính đơn giản hơn và tạo ra một phương thức di động. A
chương trình sử dụng phương thức được hiển thị trong Hình 9-3 và một cách thực thi điển hình
xuất hiện trong Hình 9-4.
Trang 8

Hình 9-3 Chương trình trọng lượng mặt trăng chuyển một đối số cho một phương thức (tiếp tục)
Trang 9

Hình 9-3 Chương trình trọng lượng mặt trăng chuyển một đối số cho một phương thức

Hình 9-4 Thực hiện điển hình của chương trình cân mặt trăng trong Hình 9-3

Trong chương trình chính ở Hình 9-3, một biến số có tên mã được khai báo và người dùng
được nhắc cho một giá trị. Giá trị sau đó được chuyển đến phương thức displayInstructions () . Các
giá trị của mã ngôn ngữ được lưu trữ ở hai nơi trong bộ nhớ:
Phương thức chính lưu mã trong mã biến và chuyển nó đến
displayInstructions () như một đối số.
Phương thức displayInstructions () chấp nhận giá trị của mã đối số là giá trị
của tham số langCode . Nói cách khác, trong phương thức này, langCode đảm nhận
giá trị mà mã có trong chương trình chính.
Trang 10

Bạn có thể coi dấu ngoặc đơn trong khai báo phương thức như một kênh vào phương thức;
các tham số được liệt kê ở đó giữ các giá trị được "đưa vào" trong phương thức.

Một biến được truyền vào một phương thức được truyền theo giá trị ; nghĩa là, một bản sao giá trị của nó được gửi đến
phương thức và được lưu trữ trong một vị trí bộ nhớ mới mà phương thức có thể truy cập được. Các
Phương thức displayInstructions () có thể được gọi bằng cách sử dụng bất kỳ giá trị số nào làm đối số,
cho dù đó là một biến, một hằng số được đặt tên, hay một hằng số theo nghĩa đen. Nói cách khác, giả sử rằng
chương trình chính chứa các khai báo sau:
num x = 2
num langCode = 2
num SPANISH = 2

Sau đó, bất kỳ câu lệnh nào sau đây sẽ hoạt động để gọi displayInstructions ()
phương pháp:

displayInstructions (x) , sử dụng một biến


displayInstructions (langCode) , sử dụng một biến khác

displayInstructions (SPANISH) , sử dụng một hằng số được đặt tên


displayInstructions (2) , sử dụng hằng số theo nghĩa đen
Nếu giá trị được sử dụng làm đối số trong lệnh gọi phương thức là một biến hoặc một hằng số được đặt tên, nó có thể
sở hữu cùng một mã định danh như tham số được khai báo trong tiêu đề phương thức, hoặc nó có thể
sở hữu một mã định danh khác. Trong một phương thức, biến được truyền vào hoặc hằng được đặt tên là
chỉ đơn giản là một trình giữ chỗ tạm thời; nó không có gì khác biệt so với tên của biến hoặc hằng số
"Đi qua" trong chương trình gọi điện.

Mỗi khi một phương thức thực thi, bất kỳ tham số nào được liệt kê trong tiêu đề phương thức đều được khai báo lại—
nghĩa là, các vị trí bộ nhớ mới được bảo lưu và đặt tên. Khi phương thức kết thúc khi trả về
, các biến tham số được khai báo cục bộ không còn tồn tại. Ví dụ, Hình 9-5
hiển thị một chương trình khai báo một biến, gán một giá trị cho nó, hiển thị nó và gửi nó đến một

phương pháp. Trong phương thức, tham số được hiển thị, thay đổi và hiển thị lại. Khi nào
điều khiển quay trở lại chương trình chính, biến ban đầu được hiển thị lần cuối. Như
thực hiện trong Hình 9-6 cho thấy, mặc dù biến trong phương thức đã được thay đổi,
biến ban đầu trong chương trình chính vẫn giữ nguyên giá trị ban đầu của nó vì nó không bao giờ bị thay đổi; nó
chiếm một địa chỉ bộ nhớ khác với biến trong phương thức.
Trang 11

Hình 9-5 Một chương trình gọi một phương thức trong đó đối số và tham số có
cùng một định danh

Hình 9-6 Thực thi chương trình trong Hình 9-5


Trang 12

Tạo các phương pháp yêu cầu nhiều tham số


Bạn tạo và sử dụng một phương thức có nhiều tham số bằng cách thực hiện như sau:

Bạn liệt kê các đối số trong lệnh gọi phương thức, được phân tách bằng dấu phẩy.
Bạn liệt kê một kiểu dữ liệu và mã định danh cục bộ cho mỗi tham số trong tiêu đề phương thức
dấu ngoặc đơn, ngăn cách từng khai báo bằng dấu phẩy. Ngay cả khi nhiều tham số là
cùng một kiểu dữ liệu, kiểu phải được lặp lại với mỗi tham số.

Các đối số được gửi đến một phương thức trong một cuộc gọi phương thức là các tham số thực tế của nó . Các biến trong phương thức
khai báo chấp nhận các giá trị từ các tham số thực tế là các tham số chính thức .

Ví dụ: giả sử bạn muốn tạo một phương thức computeTax () để tính thuế đối với
bất kỳ giá trị nào được chuyển vào nó. Bạn có thể tạo một phương thức mà bạn chuyển hai giá trị — số tiền
bị đánh thuế cũng như tỷ lệ để đánh thuế nó. Hình 9-7 cho thấy một phương thức chấp nhận hai
các thông số như vậy.
Trang 13

Hình 9-7 Một chương trình gọi phương thức computeTax () yêu cầu hai tham số

Trong Hình 9-7, lưu ý rằng một trong các đối số của phương thức có cùng tên với
tham số phương thức và tham số kia có tên khác với tham số tương ứng của nó. Mỗi người có thể có
cùng số nhận dạng với đối tác của nó hoặc tất cả có thể khác nhau. Mỗi mã định danh là cục bộ cho phương thức riêng của nó.

Trong Hình 9-7, hai tham số ( số lượng num và tỷ lệ num ) xuất hiện trong dấu ngoặc đơn trong
tiêu đề phương thức. Dấu phẩy phân tách từng tham số và mỗi tham số yêu cầu được khai báo riêng
Trang 14

kiểu dữ liệu (trong trường hợp này, cả hai đều là số) cũng như định danh riêng của nó. Khi nhiều giá trị
được chuyển cho một phương thức, chúng được chấp nhận vào các tham số theo thứ tự
thông qua. Bạn có thể viết một phương thức để nó nhận bất kỳ số lượng tham số nào theo thứ tự bất kỳ.
Tuy nhiên, khi bạn gọi một phương thức, các đối số bạn gửi đến phương thức phải khớp trong
thứ tự — cả về số và kiểu — các tham số được liệt kê trong khai báo phương thức. Một cuộc gọi
của computeTax (tỷ lệ, số dư) thay vì computeTax (số dư, tỷ lệ) sẽ dẫn đến
các giá trị không chính xác được hiển thị trong câu lệnh đầu ra.
Nếu các đối số của phương thức là cùng một kiểu — ví dụ: hai đối số dạng số — truyền
chúng đến một phương thức không đúng thứ tự dẫn đến một lỗi logic. Chương trình sẽ biên dịch và
thực thi, nhưng sẽ tạo ra kết quả không chính xác trong hầu hết các trường hợp. Nếu một phương thức mong đợi các đối số là
các loại đa dạng — ví dụ, một số và một chuỗi — sau đó chuyển sai các đối số
thứ tự là một lỗi cú pháp và chương trình sẽ không biên dịch.

HAI SỰ THẬT & MỘT LỜI NÓI DỐI


Tạo các phương pháp yêu cầu tham số

1. Một giá trị được gửi đến một phương thức từ một chương trình đang gọi là một tham số.

2. Khi bạn viết khai báo cho một phương thức có thể nhận các tham số, bạn
phải bao gồm một kiểu dữ liệu cho mỗi tham số ngay cả khi nhiều tham số là
cùng loại.

3. Khi một biến được sử dụng làm đối số trong một lệnh gọi phương thức, nó có thể có cùng
định danh làm tham số trong tiêu đề phương thức.

Tạo các phương pháp trả lại giá trị


Một biến được khai báo trong một phương thức không còn tồn tại khi phương thức kết thúc — nó vượt ra khỏi phạm vi.
Khi bạn muốn giữ lại một giá trị tồn tại khi một phương thức kết thúc, bạn có thể trả về giá trị từ
phương thức đến phương thức gọi. Khi một phương thức trả về một giá trị, phương thức đó phải có
kiểu trả về khớp với kiểu dữ liệu của giá trị trả về. Loại trả lại có thể là bất kỳ loại nào,
bao gồm num và string , cũng như các loại khác dành riêng cho ngôn ngữ lập trình mà bạn đang sử dụng
đang sử dụng. Một phương thức cũng có thể không trả về gì, trong trường hợp đó, kiểu trả về là void và phương thức là
một phương thức void . (Thuật ngữ void có nghĩa là “không có gì” hoặc “trống rỗng.”) Kiểu trả về của một phương thức được biết đến
ngắn gọn hơn là kiểu của một phương thức và nó được liệt kê trước tên phương thức khi phương thức
Trang 15

Tạo các phương pháp trả lại giá trị

isdefined. Trước đây, cuốn sách này không bao gồm các kiểu định dạng cho các phương thức vì tất cả các phương thức
đã bị vô hiệu hóa. Từ thời điểm này trở đi, một kiểu trả về được bao gồm trong mọi tiêu đề phương thức.

Cùng với danh sách định danh và tham số, kiểu trả về là một phần của khai báo phương thức. Trả về của một phương thức
type không phải là một phần của chữ ký của nó, mặc dù bạn có thể nghe thấy một số lập trình viên tuyên bố rằng nó là như vậy. Chỉ phương pháp
tên và danh sách tham số tạo thành chữ ký.

Ví dụ: một phương thức trả về số giờ mà một nhân viên đã làm việc có thể có
tiêu đề sau:

num getHoursWorked ()

Phương thức này trả về một giá trị số, vì vậy kiểu của nó là num .
Khi một phương thức trả về một giá trị, bạn thường muốn sử dụng giá trị trả về trong lệnh gọi
, mặc dù điều này không bắt buộc. Ví dụ, Hình 9-8 cho thấy cách một chương trình có thể
sử dụng giá trị được trả về bởi phương thức getHoursWorked () . Một biến có tên là giờ được khai báo
trong chương trình chính. Lời gọi phương thức getHoursWorked () là một phần của câu lệnh gán.
Khi phương thức được gọi, điều khiển logic được chuyển đến getHoursWorked ()
phương thức chứa một biến có tên là workHours . Giá trị nhận được cho biến này,
được trả về chương trình chính nơi nó được gán cho giờ . Sau khi kiểm soát logic
trở về chương trình chính từ phương thức getHoursWorked () , biến cục bộ của phương thức
Giờ làm việc không còn tồn tại. Tuy nhiên, giá trị của nó đã được lưu trữ trong chương trình chính, nơi,
giờ , nó có thể được hiển thị và sử dụng trong một phép tính.

Ví dụ về thời điểm bạn có thể gọi một phương thức nhưng không sử dụng giá trị trả về của nó, hãy xem xét một phương thức nhận được
ký tự từ bàn phím và trả về giá trị của nó cho chương trình đang gọi. Trong một số ứng dụng, bạn sẽ
muốn sử dụng giá trị của các ký tự trả về. Tuy nhiên, trong các ứng dụng khác, bạn có thể muốn nói với
người dùng nhấn phím bất kỳ. Sau đó, bạn có thể gọi phương thức để chấp nhận ký tự từ bàn phím, nhưng bạn
sẽ không quan tâm đến phím nào đã được nhấn hoặc giá trị phím nào được trả về.
Trang 16

Hình 9-8 Một chương trình tính lương gọi một phương thức trả về giá trị

Trong Hình 9-8, lưu ý kiểu trả về num đứng trước tên phương thức trong
Tiêu đề phương thức getHoursWorked () . Kiểu trả về được khai báo của một phương thức phải khớp với kiểu
giá trị được sử dụng trong câu lệnh trả về ; nếu không, chương trình sẽ không biên dịch. A
giá trị số được đưa vào câu lệnh trả về một cách chính xác — câu lệnh cuối cùng trong câu lệnh
phương thức getHoursWorked () . Khi bạn đặt một giá trị trong một câu lệnh trả về , giá trị sẽ được gửi
từ phương thức được gọi trở lại phương thức đang gọi.
Câu lệnh trả về của một phương thức có thể trả về tối đa một giá trị. Giá trị trả về có thể là một
biến hoặc một hằng số. Giá trị có thể là một kiểu dữ liệu đơn giản hoặc một kiểu dữ liệu phức tạp. Đối với
Ví dụ, trong Chương 10, bạn sẽ học cách tạo các đối tượng, là các kiểu dữ liệu phức tạp hơn.

Bạn không bắt buộc phải gán giá trị trả về của một phương thức cho một biến để sử dụng giá trị đó. Thay thế,
bạn có thể sử dụng trực tiếp giá trị trả về của một phương thức mà không cần lưu trữ nó. Bạn sử dụng giá trị của một phương thức trong
giống như cách bạn sẽ sử dụng bất kỳ biến nào cùng loại. Ví dụ, bạn có thể xuất một
trả về giá trị trong một câu lệnh như sau:
đầu ra "Giờ làm việc là", getHoursWorked ()
Trang 17

getHoursWorked () giốngnhư cách bạn sử dụng bất kỳ giá trị số đơn giản nào. Hình 9-9
hiển thị một ví dụ về một chương trình sử dụng trực tiếp giá trị trả về của một phương thức mà không cần lưu trữ nó.
Giá trị của biến workHours được tô bóng trả về từ phương thức được sử dụng trực tiếp trong
tính tổng trong chương trình chính.

Hình 9-9 Một chương trình sử dụng giá trị trả về của một phương thức mà không lưu trữ nó

Khi một chương trình cần sử dụng giá trị trả về của một phương thức ở nhiều nơi, thì việc lưu trữ
trả về giá trị trong một biến thay vì gọi phương thức nhiều lần. Một câu lệnh chương trình gọi một
phương thức yêu cầu nhiều thời gian và tài nguyên máy tính hơn một câu lệnh không gọi bất kỳ bên ngoài nào
các phương pháp. Các lập trình viên sử dụng thuật ngữ chi phí để mô tả bất kỳ nguồn lực và thời gian bổ sung nào được
hoạt động.

Như đã đề cập trước đó, về mặt kỹ thuật, trong hầu hết các ngôn ngữ lập trình, bạn được phép đưa vào
nhiều câu lệnh trả về trong một phương thức, nhưng cuốn sách này không khuyến nghị phương pháp
hầu hết các chương trình kinh doanh. Ví dụ, hãy xem xét phương thức findLargest () trong Hình 9-10.
Phương thức chấp nhận ba tham số và trả về giá trị lớn nhất. Mặc dù điều này
phương pháp hoạt động chính xác và bạn có thể thấy kỹ thuật này được sử dụng, phong cách của nó là khó hiểu
có cấu trúc. Trong Chương 3, bạn đã biết rằng logic có cấu trúc yêu cầu mỗi cấu trúc phải chứa
một điểm vào và một điểm thoát. Các câu lệnh trả về trong Hình 9-10 vi phạm điều này
quy ước bằng cách rời khỏi các cấu trúc quyết định trước khi chúng hoàn tất. Hình 9-11 cho thấy
Trang 18

cách vượt trội và được đề xuất để xử lý vấn đề. Trong Hình 9-11, giá trị lớn nhất là
được lưu trữ trong một biến. Sau đó, khi cấu trúc quyết định lồng nhau hoàn tất, giá trị được lưu trữ là
được trả về trong câu lệnh phương thức cuối cùng.

Đừng làm điều đó


Nó không có cấu trúc để
trả về từ một phương thức tại
nhiều điểm.

Đừng làm điều đó


Nó không có cấu trúc để
trở lại từ một phương pháp
tại nhiều điểm.

Hình 9-10 Cách tiếp cận không có cấu trúc để trả về một trong một số giá trị
Trang 19

Hình 9-11 Cách tiếp cận được đề xuất, có cấu trúc để trả về một trong một số giá trị

Sử dụng Biểu đồ IPO


Khi thiết kế các phương pháp để sử dụng trong các chương trình lớn hơn, một số lập trình viên thấy hữu ích khi
sử dụng biểu đồ IPO , một công cụ xác định và phân loại từng mục cần thiết trong phương pháp như
liên quan đến đầu vào, xử lý hoặc đầu ra. Ví dụ: hãy xem xét một phương pháp tìm thấy
Trang 20

nhỏ nhất trong ba giá trị số. Khi bạn nghĩ về việc thiết kế phương pháp này, bạn có thể bắt đầu
bằng cách đặt mỗi thành phần của nó vào một trong ba loại xử lý, như được hiển thị trong
Hình 9-12.

Đầu vào Chế biến Đầu ra

Giá trị đầu tiên Nếu giá trị đầu tiên nhỏ hơn mỗi giá trị khác
Giá trị thứ hai hai, lưu nó dưới dạng giá trị nhỏ nhất; ngược lại, nếu Giá trị nhỏ nhất
Giá trị thứ ba giá trị thứ hai nhỏ hơn giá trị thứ ba, lưu nó dưới dạng
giá trị nhỏ nhất; nếu không, hãy lưu giá trị thứ ba
là giá trị nhỏ nhất

Hình 9-12 Biểu đồ IPO cho phương pháp tìm giá trị nhỏ nhất trong ba giá trị số

Biểu đồ IPO trong Hình 9-12 cung cấp tổng quan về các bước xử lý liên quan đến
phương pháp. Giống như lưu đồ hoặc mã giả, biểu đồ IPO chỉ là một công cụ khác để giúp bạn lập kế hoạch
logic của các chương trình của bạn. Nhiều lập trình viên chỉ tạo biểu đồ IPO cho các phương pháp cụ thể
trong các chương trình của họ và như một giải pháp thay thế cho việc tạo dòng chảy hoặc viết mã giả. Biểu đồ IPO
cung cấp tổng quan về đầu vào cho phương pháp, các bước xử lý phải xảy ra và
kết quả đầu ra. Cuốn sách này nhấn mạnh việc tạo lưu đồ và mã giả, nhưng bạn có thể tìm thấy
nhiều ví dụ khác về biểu đồ IPO trên Web.

HAI SỰ THẬT & MỘT LỜI NÓI DỐI


Tạo các phương pháp trả lại giá trị

1. Kiểu trả về cho một phương thức có thể là bất kỳ kiểu nào, bao gồm số, ký tự,
và chuỗi, cũng như các kiểu cụ thể hơn khác tồn tại trong chương trình
ngôn ngữ bạn đang sử dụng.

2. Kiểu trả về của một phương thức phải cùng kiểu với một trong các phương thức
thông số.

3. Bạn không bắt buộc phải sử dụng giá trị trả về của một phương thức.

rs. đo para của od


meth các vâng han sự kết hợp
đếnI màu
yêu
đỏcầu
không
Làphải
kiểu xoaysre thod Ame ent. emchỉ sốrn tu lại 'S thod eme inth lue ofva kiểu hthe sự kếtphải
hợp
kiểu xoaydựng.Thứ
lên kiểu
tự bất kìlà có thểod meth ofa pe rnty retu Các # 2. Làent vật tổest giả dối
Các
Trang 21

Truyền một mảng sang một phương thức

Truyền một mảng sang một phương thức


Trong Chương 6, bạn đã biết rằng bạn có thể khai báo một mảng để tạo danh sách các phần tử và
bạn có thể sử dụng bất kỳ phần tử mảng riêng lẻ nào giống như cách bạn sẽ sử dụng bất kỳ
biến cùng loại. Ví dụ: giả sử rằng bạn khai báo một mảng số là
sau:
num someNums [12]

Sau đó, bạn có thể xuất ra someNums [0] hoặc thực hiện số học với someNums [11] , chỉ
như bạn làm đối với bất kỳ biến đơn giản nào không phải là một phần của mảng. Tương tự, bạn có thể vượt qua
một phần tử mảng cho một phương thức giống hệt như cách bạn sẽ truyền một biến hoặc
không thay đổi.
Hãy xem xét chương trình được hiển thị trong Hình 9-13. Chương trình này tạo ra một mảng gồm bốn số
giá trị và sau đó xuất chúng. Tiếp theo, chương trình gọi một phương thức có tên là tripleTheValue ()
bốn lần, lần lượt chuyển từng phần tử của mảng. Phương thức xuất ra giá trị đã truyền,
nhân nó với 3 và xuất lại. Cuối cùng, trở lại chương trình gọi điện, bốn số
là đầu ra một lần nữa. Hình 9-14 cho thấy một quá trình thực thi chương trình này trong một dòng lệnh
Môi trường.
Trang 22

Hình 9-13 Chương trình PassArrayElement (tiếp theo)


Trang 23

Hình 9-13 Chương trình PassArrayElement

Hình 9-14 Đầu ra của chương trình PassArrayElement

Như bạn có thể thấy trong Hình 9-14, chương trình hiển thị bốn giá trị ban đầu, sau đó chuyển từng giá trị
giá trị của phương thức tripleTheValue () , nơi nó được hiển thị, nhân với 3 và được hiển thị
lần nữa. Sau khi phương thức thực thi bốn lần, logic trở lại chương trình chính, nơi
Trang 24

bốn giá trị được hiển thị lại, cho thấy rằng chúng không thay đổi bởi các nhiệm vụ mới
trong tripleTheValue () . Biến oneVal là cục bộ của phương thức tripleTheValue () ;
do đó, bất kỳ thay đổi nào đối với nó không phải là vĩnh viễn và không được phản ánh trong mảng được khai báo trong
chương trình chính. Mỗi biến oneVal trong phương thức tripleTheValue () chỉ chứa một bản sao
của phần tử mảng được truyền vào phương thức và biến oneVal chứa mỗi
được gán, giá trị lớn hơn chỉ tồn tại trong khi phương thức tripleTheValue () đang thực thi. Trong tất cả các
tôn trọng, một phần tử mảng duy nhất hoạt động giống như bất kỳ biến đơn lẻ nào cùng kiểu.
Thay vì truyền một phần tử mảng đơn lẻ cho một phương thức, bạn có thể chuyển toàn bộ mảng dưới dạng
tranh luận. Bạn có thể chỉ ra rằng một tham số phương thức phải là một mảng bằng cách sử dụng
quy ước đặt dấu ngoặc vuông sau kiểu dữ liệu trong danh sách tham số của phương thức.
Khi bạn truyền một mảng cho một phương thức, những thay đổi bạn thực hiện đối với các phần tử của mảng trong phương thức
là vĩnh viễn; nghĩa là chúng được phản ánh trong mảng ban đầu đã được gửi đến phương thức.
Mảng, không giống như các kiểu tích hợp đơn giản, được chuyển bằng tham chiếu ; phương thức nhận thực tế
địa chỉ bộ nhớ của mảng và có quyền truy cập vào các giá trị thực trong các phần tử của mảng. Các
tên của một mảng đại diện cho một địa chỉ bộ nhớ và chỉ số con được sử dụng với một tên mảng
đại diện cho một phần bù từ địa chỉ đó.

Một số ngôn ngữ, chẳng hạn như Visual Basic, sử dụng dấu ngoặc đơn sau mã định danh để chỉ ra một mảng là
tham số cho một phương thức. Nhiều ngôn ngữ khác, bao gồm Java, C ++ và C #, sử dụng dấu ngoặc vuông sau
loại dữ liệu. Bởi vì cuốn sách này sử dụng dấu ngoặc đơn theo sau tên phương thức, nó sử dụng dấu ngoặc để chỉ ra mảng.

Các biến nonarray đơn giản thường được chuyển cho các phương thức theo giá trị. Nhiều ngôn ngữ lập trình cung cấp
phương tiện để chuyển các biến theo tham chiếu cũng như theo giá trị. Cú pháp để thực hiện điều này khác nhau giữa
các ngôn ngữ cho phép nó; bạn sẽ hiểu thêm về khái niệm này khi bạn học một ngôn ngữ cụ thể.

Chương trình được hiển thị trong Hình 9-15 tạo ra một mảng gồm bốn giá trị số. Sau
các số được xuất ra, toàn bộ mảng được chuyển cho một phương thức có tên là quadrupleTheValues ​() .
Trong tiêu đề phương thức, tham số được khai báo dưới dạng một mảng bằng cách sử dụng dấu ngoặc vuông
sau loại tham số. Trong phương pháp, các con số được xuất ra, cho thấy rằng chúng
giữ lại các giá trị của chúng từ chương trình chính khi nhập phương thức. Sau đó, các giá trị mảng
được nhân với 4. Mặc dù quadrupleTheValues ​() không trả về gì cho lệnh gọi
chương trình, khi chương trình hiển thị mảng lần cuối cùng trong logic dòng chính, tất cả
của các giá trị đã được thay đổi thành các giá trị tăng gấp bốn lần mới của chúng. Hình 9-16 cho thấy một
thực hiện chương trình. Bởi vì mảng được truyền bằng tham chiếu, quadrupleTheValues ​()
phương thức “biết” địa chỉ của mảng được khai báo trong chương trình gọi và làm cho
thay đổi trực tiếp đến mảng ban đầu đã được khai báo trong chương trình đang gọi.
Trang 25

Hình 9-15 Chương trình PassEntireArray (tiếp theo)


Trang 26

Hình 9-15 Chương trình PassEntireArray (tiếp theo)


Trang 27
Trang 28

Hình 9-16 Đầu ra của chương trình PassEntireArray

Khi một mảng là một tham số phương thức, các dấu ngoặc vuông trong tiêu đề phương thức vẫn trống và không
giữ một kích thước. Tên mảng được truyền vào là một địa chỉ bộ nhớ cho biết thời điểm bắt đầu của mảng.
Tùy thuộc vào ngôn ngữ bạn đang làm việc, bạn có thể kiểm soát các giá trị mà bạn sử dụng cho một chỉ số dưới
mảng theo nhiều cách khác nhau. Trong một số ngôn ngữ, bạn cũng có thể muốn chuyển một hằng số chỉ ra mảng
kích thước của phương pháp. Trong các ngôn ngữ khác, bạn có thể truy cập trường độ dài được tạo tự động cho mảng.
Dù bằng cách nào, bản thân kích thước mảng không bao giờ được ngụ ý khi bạn sử dụng tên mảng. Tên mảng chỉ cho biết
điểm bắt đầu mà từ đó các chỉ số phụ sẽ được sử dụng.

HAI SỰ THẬT & MỘT LỜI NÓI DỐI


Truyền một mảng sang một phương thức

1. Bạn có thể chuyển toàn bộ một mảng làm đối số của phương thức.

2. Bạn có thể chỉ ra rằng một tham số phương thức phải là một mảng bằng cách đặt hình vuông
dấu ngoặc sau kiểu dữ liệu trong danh sách tham số của phương thức.

3. Mảng, không giống như các kiểu tích hợp đơn giản, được truyền theo giá trị; phương thức nhận được một
bản sao của mảng ban đầu.

Phương pháp quá tải


Trong lập trình, nạp chồng liên quan đến việc cung cấp các ý nghĩa đa dạng cho một định danh duy nhất.
Khi bạn sử dụng ngôn ngữ tiếng Anh, bạn thường xuyên quá tải các từ. Khi bạn nói phá vỡ một
cửa sổ, bẻ bánh mì, phá vỡ ngân hàng, và nghỉ ngơi, bạn mô tả bốn điều rất khác nhau
các hành động sử dụng các phương pháp khác nhau và tạo ra các kết quả khác nhau. Tuy nhiên, bất kỳ ai
Trang 29

nói tiếng Anh hiểu tốt ý nghĩa của bạn bởi vì break được hiểu trong ngữ cảnh của
Cuộc thảo luận.

Trong hầu hết các ngôn ngữ lập trình, một số toán tử bị quá tải. Ví dụ: dấu + giữa hai giá trị
cho biết phép cộng, nhưng một dấu + ở bên trái của một giá trị có nghĩa là giá trị đó dương. Dấu + có khác
ý nghĩa dựa trên các đối số được sử dụng với nó.

Quá tải một phương thức là một ví dụ về tính đa hình - khả năng của một phương thức hoạt động thích hợp
theo ngữ cảnh. Theo nghĩa đen, đa hình có nghĩa là “nhiều dạng”.

Khi bạn nạp chồng một phương thức , bạn viết nhiều phương thức với một tên dùng chung nhưng khác
danh sách tham số. Khi bạn gọi một phương thức quá tải, trình dịch ngôn ngữ sẽ hiểu
phiên bản nào của phương pháp sẽ sử dụng dựa trên các đối số được sử dụng. Ví dụ, giả sử rằng
bạn tạo một phương pháp để xuất một tin nhắn và số tiền đến hạn trên hóa đơn của khách hàng, như được hiển thị trong
Hình 9-17. Phương thức nhận một tham số số đại diện cho khách hàng
cân bằng và tạo ra hai dòng sản lượng. Giả sử rằng bạn cũng cần một phương pháp tương tự
thành printBill () , ngoại trừ phương pháp mới áp dụng chiết khấu cho hoá đơn của khách hàng. Một cách giải quyết
vấn đề này sẽ là viết một phương thức mới với một tên khác — ví dụ:
printBillWithDiscount () .
Nhược điểm của phương pháp này là lập trình viên sử dụng
phương pháp của bạn phải nhớ tên của từng phiên bản hơi khác nhau. Nó là tự nhiên hơn
để khách hàng của phương pháp của bạn sử dụng một tên phương pháp được thiết kế tốt cho tác vụ in
hóa đơn, nhưng để có thể đưa ra các lập luận khác nhau khi thích hợp. Trong trường hợp này, bạn có thể
nạp chồng phương thức printBill () để ngoài phiên bản có một
đối số số, bạn có thể tạo một phiên bản có hai đối số số — một
đại diện cho số dư và một đại diện cho tỷ lệ chiết khấu. Hình 9-17 cho thấy hai
phiên bản của phương thức printBill () .
Trang 30

Hình 9-17 Hai phiên bản được nạp chồng của phương thức printBill ()
© 2015 Cengage Learning

Nếu cả hai phiên bản printBill () đều được bao gồm trong một chương trình và bạn gọi phương thức bằng cách sử dụng
đối số số đơn, như trong printBill (custBalance) , phiên bản đầu tiên của phương thức trong
Hình 9-17 thực thi. Nếu bạn sử dụng hai đối số số trong cuộc gọi, như trong printBill
(custBalance, rate) , phiên bản thứ hai của phương thức thực thi.
Nếu nó phù hợp với nhu cầu của bạn, bạn có thể cung cấp nhiều phiên bản hơn của phương thức printBill () , như
được hiển thị trong Hình 9-18. Phiên bản đầu tiên chấp nhận một tham số số chứa
số dư của khách hàng và tham số chuỗi chứa thông báo bổ sung có thể là
tùy chỉnh cho người nhận hóa đơn và hiển thị trên hóa đơn. Ví dụ: nếu một chương trình tạo ra một
cuộc gọi phương thức chẳng hạn như sau, phiên bản printBill () này sẽ thực thi:

printBill (custBal, "Đến hạn sau 10 ngày")

Phiên bản thứ hai của phương pháp trong Hình 9-18 chấp nhận ba tham số, cung cấp
số dư, tỷ lệ chiết khấu và thông báo tùy chỉnh. Ví dụ: lệnh gọi phương thức sau
sẽ sử dụng phiên bản này của phương pháp:
printBill (balanceDue, discountRate, specialMessage)
Trang 31

Hình 9-18 Hai phiên bản được nạp chồng bổ sung của phương thức printBill ()

Không bao giờ bắt buộc phải tải các phương thức quá tải trong chương trình. Thay vào đó, bạn có thể tạo nhiều phương pháp
với các số nhận dạng duy nhất như printBill () và printBillWithDiscountAndMessage () .
Quá tải các phương pháp không làm giảm công việc của bạn khi tạo một chương trình; bạn cần phải
viết từng phương thức riêng lẻ. Lợi thế được cung cấp cho khách hàng của phương pháp của bạn;
những người sử dụng phương pháp của bạn chỉ cần nhớ một tên thích hợp cho tất cả các
các nhiệm vụ.

Trong nhiều ngôn ngữ lập trình, câu lệnh đầu ra thực sự là một phương thức nạp chồng mà bạn gọi.
Sử dụng một tên duy nhất chẳng hạn như đầu ra, cho dù bạn muốn xuất một số, một chuỗi hay bất kỳ tên nào
sự kết hợp của cả hai, là thuận tiện.

Ngay cả khi bạn viết hai hoặc nhiều phiên bản quá tải của một phương thức, nhiều ứng dụng khách chương trình sẽ sử dụng
chỉ một phiên bản. Ví dụ: giả sử rằng bạn phát triển một chương trình tạo hóa đơn có chứa
tất cả bốn phiên bản của phương thức printBill () vừa được thảo luận và sau đó bán nó cho các
Trang 32

các công ty. Một tổ chức áp dụng chương trình của bạn và các phương pháp của nó có thể chỉ muốn
sử dụng một hoặc hai phiên bản của phương pháp. Bạn có thể sở hữu nhiều thiết bị mà chỉ một số
trong số các tính năng có ý nghĩa đối với bạn; ví dụ, một số người sở hữu lò vi sóng
chỉ sử dụng nút Popcorn hoặc không bao giờ sử dụng Rã đông.

Tránh các phương pháp mơ hồ


Khi bạn quá tải một phương thức, bạn có nguy cơ tạo ra các phương thức không rõ ràng — một tình huống
trong đó trình biên dịch không thể xác định phương pháp nào sẽ sử dụng. Mỗi khi bạn gọi một phương thức,
trình biên dịch quyết định xem có tồn tại một phương thức phù hợp hay không; nếu vậy, phương thức thực thi, và nếu không,
bạn nhận được một thông báo lỗi. Ví dụ: giả sử rằng bạn viết hai phiên bản của một
phương thức printBill () , như trong chương trình ở Hình 9-19. Một phiên bản của phương pháp này là
dự định chấp nhận số dư của khách hàng và tỷ lệ chiết khấu, và người kia dự định chấp nhận
số dư khách hàng và số tiền chiết khấu được biểu thị bằng đô la.
Trang 33

newBal = bal - (bal * newBal = bal -


giảm giá) giảm giá

đầu ra "Cảm ơn bạn đã đầu ra "Cảm ơn bạn đã


đơn đặt hàng của bạn " đơn đặt hàng của bạn "

đầu ra "Please đầu ra "Please


chuyển tiền ", newBal chuyển tiền ", newBal Đừng làm điều đó
Khi hai phương pháp có
các chữ ký giống nhau,
trở về trở về
chương trình không thể xác định
cái nào để thực hiện.
khởi đầu
Tuyên bố
số dư
num giảm giáInDollars
số dư đầu vào, chiết khấu
printBill (số dư, chiết khấuInDollars)
dừng lại

?
void printBill (num bal, num giảm giá)
Tuyên bố
num newBal
newBal = bal - (bal * giảm giáRate)
đầu ra "Cảm ơn bạn đã đặt hàng"
đầu ra "Vui lòng chuyển tiền", newBal
trở về

void printBill (num bal, num giảm giáInDollars)


Tuyên bố
?
num newBal
newBal = bal - giảm giáInDollars
đầu ra "Cảm ơn bạn đã đặt hàng"
đầu ra "Vui lòng chuyển tiền", newBal
trở về

Hình 9-19 Chương trình chứa lệnh gọi phương thức không rõ ràng
© 2015 Cengage Learning
Trang 34

Mỗi phiên bản trong hai phiên bản printBill () trong Hình 9-19 là một phương thức hợp lệ của riêng nó.
Tuy nhiên, khi hai phiên bản tồn tại trong cùng một chương trình, một vấn đề nảy sinh. Khi mà
chương trình chính gọi printBill () bằng cách sử dụng hai đối số số, trình biên dịch không thể
xác định phiên bản để gọi. Bạn có thể nghĩ rằng phiên bản của phương pháp với
tham số có tên là giảm giáInDollars sẽ thực thi, vì lệnh gọi phương thức sử dụng
chiết khấu định danhInDollars . Tuy nhiên, trình biên dịch xác định phiên bản của một phương thức
để gọi chỉ dựa trên các kiểu dữ liệu đối số, không phải từ định danh của chúng. Bởi vì cả hai phiên bản của
Phương thức printBill () có thể chấp nhận hai tham số số, trình biên dịch không thể
xác định phiên bản nào sẽ thực thi, do đó lỗi xảy ra và quá trình biên dịch chương trình dừng lại.

Bản thân một phương thức được nạp chồng không phải là mơ hồ — nó chỉ trở nên mơ hồ nếu bạn tạo một phương thức
gọi phù hợp với nhiều chữ ký phương thức. Trong nhiều ngôn ngữ, một chương trình có khả năng
các phương thức không rõ ràng sẽ chạy mà không gặp sự cố nếu bạn không thực hiện bất kỳ lệnh gọi phương thức nào phù hợp hơn
hơn một phương pháp.

Các phương thức có thể được nạp chồng một cách chính xác bằng cách cung cấp các danh sách tham số khác nhau cho các phương thức có
tên tương tự. Các phương thức có tên giống hệt nhau có danh sách tham số giống hệt nhau nhưng khác
kiểu trả về không bị quá tải — chúng không rõ ràng. Ví dụ, hai phương pháp sau
tiêu đề tạo ra sự mơ hồ:
chuỗi aMethod (num x)
num aMethod (num y)

Trình biên dịch xác định phiên bản nào của phương thức sẽ gọi dựa trên danh sách tham số,
không trả lại các loại. Khi phương thức gọi aMethod (17) được thực hiện, trình biên dịch sẽ không

biết phương thức nào trong hai phương thức để thực thi vì cả hai lựa chọn có thể có
đối số số.

Tất cả các ngôn ngữ lập trình hướng đối tượng phổ biến đều hỗ trợ nhiều kiểu dữ liệu số. Ví dụ,
Java, C #, C ++ và Visual Basic đều hỗ trợ kiểu dữ liệu số nguyên (số nguyên) khác với
kiểu dữ liệu dấu phẩy động (vị trí thập phân). Nhiều ngôn ngữ thậm chí còn có nhiều kiểu số chuyên biệt hơn, chẳng hạn như
như đã ký và chưa ký. Các phương thức chấp nhận các kiểu cụ thể khác nhau được nạp chồng chính xác.
Trang 35

Sử dụng các phương pháp được xác định trước

HAI SỰ THẬT & MỘT LỜI NÓI DỐI


Phương pháp quá tải

1. Trong lập trình, nạp chồng liên quan đến việc cung cấp các ý nghĩa đa dạng cho một
định danh.

2. Khi bạn nạp chồng một phương thức, bạn viết nhiều phương thức với các tên khác nhau
nhưng danh sách tham số giống hệt nhau.

3. Các phương thức có thể được nạp chồng một cách chính xác bằng cách cung cấp các danh sách tham số khác nhau
cho các phương thức có cùng tên.

Sử dụng các phương pháp được xác định trước


Tất cả các ngôn ngữ lập trình hiện đại đều chứa nhiều phương thức đã được viết sẵn
dành cho lập trình viên. Các phương pháp xác định trước có thể bắt nguồn từ một số nguồn:
Một số phương pháp viết sẵn được xây dựng thành một ngôn ngữ. Ví dụ: các phương pháp thực hiện
đầu vào và đầu ra thường được xác định trước.
Khi bạn làm việc trên một chương trình trong một nhóm, mỗi lập trình viên có thể được chỉ định cụ thể
các phương thức để tạo và các phương thức của bạn sẽ tương tác với các phương thức do người khác viết.
Nếu bạn làm việc cho một công ty, nhiều phương pháp tiêu chuẩn có thể đã được viết sẵn và
bạn sẽ được yêu cầu sử dụng chúng. Ví dụ: công ty có thể có một tiêu chuẩn

phương pháp hiển thị logo của nó.


Các phương pháp được xác định trước giúp bạn tiết kiệm thời gian và công sức. Ví dụ: trong hầu hết các ngôn ngữ, hiển thị
thông báo trên màn hình liên quan đến việc sử dụng một phương pháp cài sẵn. Khi bạn muốn hiển thị Xin chào trên
màn hình nhắc lệnh trong C #, bạn viết như sau:

Console.WriteLine ("Xin chào");

Trong Java, bạn viết:

System.out.println ("Xin chào");

Trong các câu lệnh này, bạn có thể nhận ra WriteLine () và println () là tên phương thức
bởi vì chúng được theo sau bởi dấu ngoặc đơn; dấu ngoặc đơn chứa một đối số đại diện cho
thông báo sẽ hiển thị. Nếu những phương pháp này không được viết trước, bạn sẽ phải biết
chi tiết cấp thấp về cách thao tác các pixel trên màn hình để hiển thị các ký tự. Thay vào đó, bằng cách
bằng cách sử dụng các phương pháp viết sẵn, bạn có thể tập trung vào nhiệm vụ cấp cao hơn là hiển thị
thông điệp hữu ích và phù hợp.
Trang 36

Trong C #, quy ước là bắt đầu tên phương thức bằng một chữ cái viết hoa. Trong Java, tên phương thức
thông thường bắt đầu bằng một chữ thường. Các phương thức WriteLine () và println () tuân theo
quy ước của ngôn ngữ tương ứng. Các phương thức WriteLine () và println () đều được nạp chồng trong
ngôn ngữ tương ứng của họ. Ví dụ: nếu bạn truyền một chuỗi cho một trong hai phương thức, thì phiên bản của phương thức đó
chấp nhận một tham số chuỗi thực thi, nhưng nếu bạn truyền một số, một phiên bản khác chấp nhận một số
tham số thực thi.

Hầu hết các ngôn ngữ lập trình cũng chứa nhiều phương pháp toán học khác nhau, chẳng hạn như
tính căn bậc hai hoặc giá trị tuyệt đối của một số. Các phương pháp khác truy xuất
ngày và giờ hiện tại từ hệ điều hành hoặc chọn một số ngẫu nhiên để sử dụng trong trò chơi
ứng dụng. Các phương pháp này được viết ra để tạo sự thuận tiện cho bạn — tính toán căn bậc hai
và việc tạo ra các số ngẫu nhiên là những công việc phức tạp, vì vậy rất tiện lợi khi có các phương pháp
đã được viết, thử nghiệm và có sẵn khi bạn cần. Tên của các phương thức
thực hiện các chức năng này khác nhau giữa các ngôn ngữ lập trình, vì vậy bạn cần nghiên cứu
tài liệu của ngôn ngữ để sử dụng chúng. Ví dụ, nhiều phương thức của một ngôn ngữ là
được mô tả trong sách giáo khoa ngôn ngữ lập trình giới thiệu và bạn cũng có thể tìm thấy ngôn ngữ
tài liệu trực tuyến.
Cho dù bạn muốn sử dụng một phương pháp xác định trước hay bất kỳ phương pháp nào khác, bạn nên biết
bốn chi tiết sau:
Phương thức nói chung làm gì — ví dụ, tính căn bậc hai.
Tên của phương thức — ví dụ, nó có thể là sqrt () .

Các tham số bắt buộc của phương thức — ví dụ, một phương thức căn bậc hai có thể yêu cầu
một tham số số duy nhất. Có thể có nhiều phiên bản quá tải của phương pháp
từ đó bạn có thể chọn. Ví dụ: một phiên bản phương thức có thể chấp nhận một số nguyên
và một phiên bản khác có thể chấp nhận một số dấu phẩy động.
Kiểu trả về của phương thức — ví dụ, một phương thức căn bậc hai rất có thể trả về
một giá trị số là căn bậc hai của đối số được truyền cho
phương pháp.
Bạn không cần biết phương pháp được triển khai như thế nào — nghĩa là cách hướng dẫn
các câu lệnh được viết bên trong nó. Giống như tất cả các phương pháp, bạn có thể sử dụng các phương thức tích hợp sẵn mà không cần
lo lắng về các chi tiết triển khai cấp thấp của họ.
Trang 37

HAI SỰ THẬT & MỘT LỜI NÓI DỐI


Sử dụng các phương pháp được xác định trước

1. Tên của một phương thức thực hiện một chức năng cụ thể (chẳng hạn như tạo
số ngẫu nhiên) có thể giống nhau trong các ngôn ngữ lập trình khác nhau.

2. Khi bạn muốn sử dụng một phương pháp được xác định trước, bạn nên biết phương pháp
nói chung, cùng với tên, các tham số bắt buộc và kiểu trả về.

3. Khi bạn muốn sử dụng một phương pháp xác định trước, bạn không cần biết cách
phương pháp hoạt động nội bộ để có thể sử dụng phương pháp một cách hiệu quả.

Các vấn đề về thiết kế phương pháp: Ẩn triển khai,


Sự liên kết và khớp nối
Để thiết kế các phương pháp hiệu quả, bạn nên xem xét một số chất lượng của chương trình:
Bạn nên sử dụng ẩn thực hiện; nghĩa là, máy khách của một phương thức không cần phải
hiểu các cơ chế bên trong của một phương pháp.

Bạn nên cố gắng tăng cường sự gắn kết.


Bạn nên cố gắng giảm khớp nối.

Tìm hiểu về Ẩn triển khai


Một nguyên tắc quan trọng của mô-đun hóa là khái niệm ẩn thực hiện ,
đóng gói các chi tiết phương pháp. Đó là, khi một chương trình thực hiện một yêu cầu đối với một phương thức, nó
không biết chi tiết về cách phương thức được thực thi. Ví dụ, khi bạn thực hiện một
đặt chỗ nhà hàng, bạn không cần biết việc đặt chỗ trên thực tế được ghi lại như thế nào tại
nhà hàng — có lẽ nó được viết trong một cuốn sách, được đánh dấu trên một bảng đen lớn, hoặc được nhập vào
một cơ sở dữ liệu máy tính. Các chi tiết triển khai không liên quan đến bạn với tư cách là khách hàng quen và nếu
nhà hàng thay đổi phương pháp của mình từ năm này sang năm khác, việc thay đổi không ảnh hưởng đến
sử dụng phương thức đặt chỗ — bạn vẫn gọi và cung cấp tên, ngày tháng và giờ của mình. Với
các phương thức được viết tốt, sử dụng ẩn triển khai có nghĩa là một phương thức gọi một phương thức khác
chỉ phải biết những điều sau:

Tên của phương thức được gọi


Loại thông tin nào cần gửi đến phương thức
Loại dữ liệu trả về nào mong đợi từ phương thức

Trang 38

Nói cách khác, phương pháp kêu gọi cần phải hiểu chỉ có giao diện với phương pháp đó
được gọi là. Giao diện là phần duy nhất của một phương thức mà máy khách của phương thức (hoặc
trình gọi của phương thức) tương tác. Chương trình không cần biết phương thức hoạt động như thế nào
trong nội bộ. Ngoài ra, nếu bạn thay thế một triển khai phương pháp mới, cải tiến nhưng
giao diện của phương pháp không thay đổi, bạn sẽ không cần thực hiện thay đổi trong bất kỳ phương thức nào
gọi phương thức đã thay đổi.

Các lập trình viên đề cập đến các chi tiết triển khai ẩn như tồn tại trong hộp đen — bạn có thể
kiểm tra những gì đi vào và những gì đi ra, nhưng không kiểm tra chi tiết về cách thức hoạt động của phương pháp
phía trong.

Tăng độ gắn kết


Khi bạn bắt đầu thiết kế các chương trình máy tính, rất khó để quyết định số tiền cần đưa vào
phương pháp. Ví dụ: một quy trình yêu cầu 40 hướng dẫn có thể được chứa trong một 40-
phương pháp hướng dẫn, hai phương pháp 20 hướng dẫn, năm phương pháp 8 hướng dẫn hoặc nhiều phương pháp khác
các tổ hợp. Trong hầu hết các ngôn ngữ lập trình, bất kỳ kết hợp nào trong số này đều được phép; bạn
có thể viết một chương trình thực thi và tạo ra kết quả chính xác bất kể bạn chia
các bước riêng lẻ thành các phương pháp. Tuy nhiên, đặt quá nhiều hoặc quá ít hướng dẫn trong một
phương pháp làm cho một chương trình khó theo dõi hơn và giảm tính linh hoạt.
Để giúp xác định sự phân chia nhiệm vụ phù hợp giữa các phương pháp, bạn muốn phân tích
sự gắn kết của mỗi phương pháp , đề cập đến cách các câu lệnh bên trong của một phương pháp phục vụ cho
hoàn thành mục đích của phương pháp. Trong các phương pháp có tính gắn kết cao, tất cả các hoạt động đều có liên quan,
hoặc "đi cùng nhau." Các phương pháp như vậy gắn kết về mặt chức năng — tất cả các hoạt động của chúng đều góp phần vào
hiệu suất của một nhiệm vụ duy nhất. Các phương pháp gắn kết về mặt chức năng thường đáng tin cậy hơn
hơn những cái có độ gắn kết thấp; họ được coi là mạnh hơn và họ tạo ra các chương trình
dễ dàng hơn để viết, đọc và bảo trì.

Ví dụ, hãy xem xét một phương pháp tính toán tổng lương. Phương thức nhận các tham số
xác định mức lương của công nhân và số giờ làm việc. Phương pháp tính tổng lương
và hiển thị nó. Tính liên kết của phương pháp này cao vì mỗi hướng dẫn của nó
đóng góp vào một nhiệm vụ — tính toán tổng lương. Nếu bạn có thể viết một câu mô tả những gì
phương thức chỉ sử dụng hai từ — ví dụ: Tính tổng, Giá trị khối hoặc Hiển thị
ghi lại — phương pháp có thể gắn kết về mặt chức năng.
Bạn có thể làm việc trong một môi trường lập trình có quy tắc chẳng hạn như Không có phương pháp nào sẽ
dài hơn có thể được in trên một trang hoặc Không có phương pháp nào sẽ có nhiều hơn 30 dòng mã. Các
nhà sản xuất quy tắc đang cố gắng đạt được sự gắn kết hơn, nhưng các quy tắc như vậy là tùy tiện. Một hai dòng
phương pháp có thể có độ gắn kết thấp và phương pháp 40 dòng có thể có độ gắn kết cao. Bởi vì
các phương pháp tốt, gắn kết về mặt chức năng chỉ thực hiện một nhiệm vụ, chúng có xu hướng ngắn. Tuy nhiên,
vấn đề không phải là kích thước. Nếu cần 20 câu lệnh để thực hiện một tác vụ trong một phương thức, phương thức
vẫn còn gắn kết.

Hầu hết các lập trình viên không đưa ra quyết định một cách có ý thức về tính liên kết cho mỗi phương pháp
họ viết. Thay vào đó, họ phát triển “cảm giác” về những loại nhiệm vụ thuộc về nhau và
các tập hợp con của nhiệm vụ nên được chuyển hướng sang các phương pháp riêng của chúng.

Trang 39

Giảm khớp nối


Khớp nối là thước đo độ bền của kết nối giữa hai phương pháp chương trình; nó
thể hiện mức độ thông tin được trao đổi bằng các phương thức. Khớp nối chặt chẽ
hoặc lỏng lẻo, tùy thuộc vào mức độ một phương pháp dựa vào thông tin từ phương pháp khác. Chặt chẽ
ghép nối , xảy ra khi các phương thức phụ thuộc vào nhau quá mức, làm cho các chương trình
dễ bị sai sót hơn. Với sự kết hợp chặt chẽ, bạn có nhiều đường dẫn dữ liệu để theo dõi, nhiều
cơ hội để dữ liệu xấu truyền từ phương pháp này sang phương thức khác và nhiều cơ hội cho một phương pháp
để thay đổi thông tin cần thiết bằng một phương pháp khác. Khớp nối lỏng lẻo xảy ra khi các phương thức
không phụ thuộc vào người khác. Nói chung, bạn muốn giảm khớp nối nhiều nhất có thể
bởi vì các kết nối giữa các phương thức khiến chúng khó viết hơn, duy trì,
và sử dụng lại.

Hãy tưởng tượng bốn đầu bếp đi lang thang vào và ra khỏi bếp trong khi chuẩn bị một món hầm. Nếu mỗi
được phép thêm gia vị theo ý muốn mà không cần kiến ​thức của các đầu bếp khác, bạn có thể kết thúc
với một thảm họa ẩm thực. Tương tự, nếu bốn phương pháp chương trình trả lương có thể thay đổi tổng lương của bạn
nếu không có "kiến thức" về các phương pháp khác, bạn có thể kết thúc với một thảm họa tài chính. A
chương trình trong đó một số phương pháp có quyền truy cập vào con số tổng lương của bạn, có các phương pháp
liên kết chặt chẽ. Một chương trình ưu việt sẽ kiểm soát quyền truy cập vào giá trị bảng lương bằng cách chuyển nó
chỉ cho các phương pháp cần nó.
Bạn có thể đánh giá xem sự kết hợp giữa các phương pháp là lỏng lẻo hay chặt chẽ bằng cách kiểm tra cách
phương pháp chia sẻ dữ liệu.
Kết hợp chặt chẽ xảy ra khi các phương thức có quyền truy cập vào các biến được xác định toàn cục giống nhau.
Khi một phương thức thay đổi giá trị được lưu trữ trong một biến, các phương thức khác sẽ bị ảnh hưởng. Bạn
nên tránh kết hợp chặt chẽ, nhưng lưu ý rằng bạn có thể thấy nó trong các chương trình được viết bởi
khác.
Khớp nối lỏng lẻo xảy ra khi một bản sao dữ liệu phải được chia sẻ được chuyển từ một
phương pháp khác. Bằng cách đó, việc chia sẻ dữ liệu luôn có mục đích — các biến phải
được chuyển đến và từ các phương thức sử dụng chúng một cách rõ ràng. Các phương thức lỏng lẻo nhất (tốt nhất) vượt qua
các đối số đơn lẻ nếu có thể, thay vì nhiều biến hoặc toàn bộ bản ghi.

Ngoài ra, có thời gian và địa điểm cho các phím tắt. Nếu một bản ghi nhớ phải hết trong năm phút nữa,
bạn không có thời gian để thay đổi phông chữ hoặc thêm clip nghệ thuật bằng trình xử lý văn bản của mình. Tương tự, nếu bạn
cần một kết quả lập trình nhanh, bạn rất có thể sử dụng các tên biến khó hiểu, chặt chẽ
khớp nối và sự gắn kết tối thiểu. Tuy nhiên, khi bạn tạo một ứng dụng chuyên nghiệp, bạn
nên ghi nhớ các hướng dẫn chuyên môn.
Trang 40

HAI SỰ THẬT & MỘT LỜI NÓI DỐI


Các vấn đề về thiết kế phương pháp: Ẩn triển khai, Liên kết và Khớp nối

1. Một phương thức gọi phải biết giao diện của bất kỳ phương thức nào mà nó gọi.

2. Bạn nên cố gắng tránh khớp nối lỏng lẻo, xảy ra khi các phương pháp không
phụ thuộc vào người khác.

3. Sự gắn kết chức năng xảy ra khi tất cả các hoạt động trong một phương pháp đóng góp vào
chỉ thực hiện một nhiệm vụ.

ent. mặt dây


mắcchuyền
nợ
Chúng
odstôimeth cái đó gso uplin sinh thái
lỏng lẻo
cho mục ld
đích
shou Bạn # 2. Làent vật tổest giả dối
Các

Hiểu đệ quy
Đệ quy xảy ra khi một phương thức được xác định theo nghĩa của chính nó. Một phương thức tự gọi là
phương pháp đệ quy . Một số ngôn ngữ lập trình không cho phép một phương thức gọi chính nó, nhưng
những điều đó có thể được sử dụng để tạo ra các phương thức đệ quy tạo ra các hiệu ứng thú vị.

Hình 9-20 cho thấy một ví dụ đơn giản về đệ quy. Chương trình gọi một phương thức infinity () ,
hiển thị Trợ giúp! và gọi lại chính nó (xem câu lệnh tô bóng). Cuộc gọi thứ hai tới
infinity () hiển
thị Trợ giúp! và tạo ra cuộc gọi thứ ba. Kết quả là một số lượng lớn
số lần lặp lại của phương thức infinity () . Đầu ra được hiển thị trong Hình 9-21.

Hình 9-20 Một chương trình gọi một phương thức đệ quy
Trang 41

Hình 9-21 Đầu ra của chương trình trong Hình 9-20

Mỗi khi bạn gọi một phương thức, địa chỉ mà chương trình sẽ trả về tại
hoàn thành của phương thức được lưu trữ trong một vị trí bộ nhớ được gọi là ngăn xếp . Khi một phương pháp
kết thúc, địa chỉ được truy xuất từ ​ngăn xếp và chương trình quay trở lại vị trí nơi
lệnh gọi phương thức đã được thực hiện, sau đó chuyển sang hướng dẫn tiếp theo. Ví dụ: giả sử rằng một
chương trình gọi methodA () và methodA () gọi methodB () . Khi chương trình gọi
methodA () ,
một địa chỉ trả về được lưu trữ trong ngăn xếp, và sau đó methodA () bắt đầu thực thi.
Khi methodA () gọi methodB () , một địa chỉ trả về trong methodA () được lưu trữ trong ngăn xếp và
methodB () bắt
đầu thực thi. Khi methodB () kết thúc, địa chỉ đã nhập cuối cùng được truy xuất từ
ngăn xếp và điều khiển chương trình trở về hoàn thành methodA () . Khi methodA () kết thúc,
địa chỉ còn lại được truy xuất từ ​ngăn xếp và điều khiển chương trình trở về chính
phương thức chương trình để tiếp tục thực hiện.

Giống như tất cả bộ nhớ máy tính, ngăn xếp có kích thước hữu hạn. Khi chương trình trong Hình 9-20 gọi
các vô cực () phương pháp, chồng nhận được rất nhiều địa chỉ trả lại rằng nó cuối cùng
tràn. Các cuộc gọi đệ quy sẽ kết thúc sau một số lần lặp lại quá nhiều và
chương trình đưa ra thông báo lỗi.
Tất nhiên, không có ứng dụng thực tế nào cho một chương trình đệ quy vô hạn. Cũng như bạn phải là
cẩn thận không tạo các vòng lặp vô tận, khi bạn viết các phương thức đệ quy hữu ích, bạn phải
cung cấp một cách để cuối cùng dừng đệ quy. Các giá trị đầu vào khiến một phương thức
recursive được gọi là các trường hợp đệ quy và giá trị đầu vào làm cho việc dừng đệ quy là
được gọi là trường hợp cơ sở hoặc trường hợp kết thúc .
Trang 42

Sử dụng đệ quy thành công sẽ dễ dàng hơn nếu bạn hiểu kỹ về vòng lặp. Bạn đã học về các vòng lặp trong
Chương 5. Một ví dụ hàng ngày về đệ quy được in trên chai dầu gội đầu: Tạo bọt, xả, lặp lại.

Hình 9-22 cho thấy một ứng dụng sử dụng đệ quy một cách hiệu quả. Chương trình gọi một
phương pháp đệ quy tính tổng của mọi số nguyên từ 1 trở lên và bao gồm
giá trị đối số của phương thức. Ví dụ: tổng của mọi số nguyên lên đến và bao gồm 3 là 1 + 2 + 3,
hoặc 6, và tổng của mọi số nguyên đến và bao gồm 4 là 1 + 2 + 3 + 4, hoặc 10.

Hình 9-22 Chương trình sử dụng phương thức cum Tích lũy () đệ quy

Khi nghĩ về các mối quan hệ tổng hợp tích lũy, hãy nhớ rằng tổng của tất cả các
số nguyên lên đến và bao gồm bất kỳ số nào là số đó cộng với tổng các số nguyên cho
số thấp hơn tiếp theo. Nói cách khác, hãy xem xét những điều sau:
Tổng các chữ số từ 1, đến và bao gồm cả 1, chỉ đơn giản là 1.
Tổng các chữ số từ 1 đến 2 là tổng trước đó, cộng với 2.

Tổng các chữ số từ 1 đến 3 là tổng trước đó, cộng với 3.


Tổng các chữ số từ 1 đến 4 là tổng trước đó, cộng với 4.
Và như thế.
Trang 43

Phương thức lũy thừa đệ quy () trong Hình 9-22 sử dụng kiến thức này. Đối với mỗi số ,
tổng tích lũy của nó bao gồm giá trị của chính số đó cộng với tổng tích lũy của tất cả
những con số trước đó ít hơn. Chương trình trong Hình 9-22 gọi phương thức cum Tích lũy ()
10 lần trong một vòng lặp để hiển thị tổng tích lũy của mọi số nguyên từ 1 đến 10. Hình 9-23
hiển thị đầu ra.

Hình 9-23 Đầu ra của chương trình trong Hình 9-22

Nếu bạn xem xét các Hình 9-22 và 9-23 cùng nhau, bạn có thể thấy những điều sau:

Khi 1 được truyền cho cumulativeSum () phương pháp, nếu tuyên bố trong phương pháp
xác định rằng đối số bằng 1, returnVal trở thành 1 và 1 được trả về cho
đầu ra. (Giá trị đầu vào 1 là trường hợp cơ sở hoặc trường hợp kết thúc.)
Trong lần truyền tiếp theo qua vòng lặp, 2 được chuyển tới phương thức cum Tích lũy () . Khi nào
phương pháp nhận 2 như một cuộc tranh cãi, những nếu tuyên bố trong phương pháp này là sai, và
returnVal được
đặt thành 2 cộng với giá trị của cum Tích lũy (1) . (Giá trị đầu vào 2 là một đệ quy
case.) Lệnh gọi thứ hai này tới cum Tích lũy () sử dụng 1 làm đối số trả về giá trị 1, vì vậy khi
phương thức kết thúc, nó trả về 2 + 1 hoặc 3.
Trong lần thứ ba chuyển qua vòng lặp trong chương trình gọi, 3 được chuyển đến
phương thức cum Tích lũy () . Khi phương pháp này nhận được 3 như một cuộc tranh cãi, những nếu tuyên bố
bên trong phương thức là false và phương thức trả về 3 cộng với giá trị của cum Tích lũy (2) .
(Giá trị đầu vào 3, như 2, là một trường hợp đệ quy.) Giá trị của lệnh gọi này là 2 cộng
tích lũySum (1) . Giá trị của cum Tích lũy (1) là 1. Cuối cùng, Tích lũy (3)
là 3 + 2 + 1.
Nhiều chương trình phức tạp hoạt động trên danh sách các mục sử dụng xử lý đệ quy.
Tuy nhiên, việc tuân theo logic của một phương pháp đệ quy có thể khó khăn và các chương trình sử dụng
đệ quy đôi khi dễ bị lỗi và khó gỡ lỗi. Bởi vì các chương trình như vậy cũng có thể
khó cho những người khác để duy trì, một số tổ chức kinh doanh cấm các lập trình viên của họ
sử dụng logic đệ quy trong các chương trình của công ty. Nhiều vấn đề được giải quyết bằng đệ quy
phương pháp có thể được giải quyết bằng cách sử dụng vòng lặp. Ví dụ, kiểm tra chương trình trong Hình 9-24. Điều này
chương trình tạo ra kết quả tương tự như chương trình đệ quy trước đó, nhưng
thời trang đơn giản.
Trang 44

Hình 9-24 Chương trình không đệ quy tính tổng tích lũy

Một minh họa hài hước về đệ quy được tìm thấy trong câu này: "Để hiểu đệ quy, bạn phải
trước tiên hãy hiểu đệ quy. ” Một mục từ điển hài hước là "Đệ quy: Xem đệ quy." Những ví dụ này
chứa một phần tử chân lý, nhưng các thuật toán đệ quy hữu ích luôn có một điểm mà tại đó vòng lặp vô hạn là
đã thoát ra. Nói cách khác, trường hợp cơ sở hoặc trường hợp kết thúc luôn đạt được tại một số điểm.

HAI SỰ THẬT & MỘT LỜI NÓI DỐI


Hiểu đệ quy

1. Một phương thức gọi chính nó là một phương thức đệ quy.

2. Mỗi khi bạn gọi một phương thức, địa chỉ mà chương trình sẽ trả về
khi hoàn thành phương thức được lưu trữ trong một vị trí bộ nhớ được gọi là
cây rơm.

3. Tuân theo logic của một phương pháp đệ quy thường dễ hơn nhiều so với làm theo
logic của một chương trình thông thường, do đó, đệ quy làm cho việc gỡ lỗi dễ dàng hơn.
Trang 45

Tóm tắt chương


Phương thức là một mô-đun chương trình chứa một loạt các câu lệnh thực hiện một tác vụ.
Bất kỳ chương trình nào cũng có thể chứa vô số phương thức và mỗi phương thức có thể
gọi là không giới hạn số lần. Một phương thức phải bao gồm một tiêu đề, một nội dung và một
câu lệnh trả về đánh dấu sự kết thúc của phương thức.
Các biến và hằng số nằm trong phạm vi trong hoặc cục bộ, chỉ phương thức trong đó
chúng được khai báo.
Khi bạn truyền một mục dữ liệu vào một phương thức, nó sẽ là một đối số của phương thức. Khi mà
phương thức nhận mục dữ liệu, nó được gọi là một tham số. Khi bạn viết khai báo cho
một phương thức có thể nhận tham số, bạn phải bao gồm kiểu dữ liệu và tên cục bộ cho
mỗi tham số trong dấu ngoặc đơn của khai báo phương thức. Bạn có thể vượt qua nhiều
các đối số cho một phương thức được gọi bằng cách liệt kê các đối số trong lệnh gọi phương thức và
ngăn cách chúng bằng dấu phẩy. Khi bạn gọi một phương thức, các đối số bạn gửi đến
phương thức phải khớp theo thứ tự — cả về số và kiểu — các tham số được liệt kê trong
khai báo phương thức.
Kiểu trả về của một phương thức cho biết kiểu dữ liệu của giá trị mà phương thức sẽ gửi lại
đến vị trí nơi cuộc gọi phương thức đã được thực hiện. Kiểu trả về còn được gọi là
kiểu của phương thức và được đặt trước tên phương thức khi phương thức được định nghĩa.
Khi một phương thức trả về một giá trị, bạn thường muốn sử dụng giá trị trả về trong lệnh gọi
, mặc dù điều này không bắt buộc.
Bạn có thể chuyển một phần tử mảng đơn lẻ vào một phương thức theo cách giống hệt như cách bạn làm
truyền một biến hoặc hằng số. Bạn có thể chỉ ra rằng một tham số phương thức là một mảng bởi
đặt dấu ngoặc vuông sau kiểu dữ liệu trong danh sách tham số của phương thức. Khi bạn vượt qua
một mảng cho một phương thức, nó được truyền bằng tham chiếu; nghĩa là, phương thức nhận được thực tế
địa chỉ bộ nhớ của mảng và có quyền truy cập vào các giá trị thực trong các phần tử của mảng.
Khi bạn nạp chồng một phương thức, bạn viết nhiều phương thức với một tên dùng chung nhưng
danh sách tham số khác nhau. Trình biên dịch hiểu ý nghĩa của bạn dựa trên
đối số bạn sử dụng khi gọi phương thức. Quá tải một phương pháp dẫn đến nguy cơ
tạo ra các phương thức không rõ ràng — một tình huống trong đó trình biên dịch không thể xác định phương thức nào
phiên bản của một phương pháp để sử dụng.

Tất cả các ngôn ngữ lập trình hiện đại đều chứa nhiều phương thức viết sẵn, được viết sẵn để lưu
bạn thời gian và nỗ lực.
Với các phương pháp được viết tốt, việc triển khai sẽ bị ẩn. Để gọi một phương thức, bạn cần
chỉ biết tên của phương thức, loại thông tin cần gửi đến phương thức và
loại dữ liệu trả về mong đợi từ phương thức. Khi viết các phương pháp, bạn nên
phấn đấu đạt tính liên kết cao và khớp nối lỏng lẻo.

Đệ quy xảy ra khi một phương thức được định nghĩa theo nghĩa của chính nó. Theo logic của một
Phương pháp đệ quy có thể khó và các chương trình sử dụng đệ quy đôi khi bị lỗi-
dễ bị lỗi và khó gỡ lỗi.
Trang 46

Điều khoản quan trọng


Một phương pháp là một mô-đun chương trình có chứa một loạt các báo cáo rằng thực hiện một nhiệm vụ.

Máy khách của một phương thức là một chương trình hoặc phương thức khác sử dụng phương thức này.

Một tiêu đề phương pháp trước một cơ thể phương pháp; tiêu đề bao gồm mã định danh phương pháp
và có thể là thông tin nhận dạng cần thiết khác, chẳng hạn như loại trả lại và
danh sách tham số.

Một thân phương thức chứa tất cả các câu lệnh trong phương thức.

Việc triển khai mô tả phần thân của một phương thức hoặc các câu lệnh thực hiện các nhiệm vụ của một
phương pháp.

Một câu lệnh trả về phương thức đánh dấu sự kết thúc của một phương thức và xác định điểm tại đó
điều khiển trả về phương thức gọi.

Cục bộ mô tả các mục dữ liệu chỉ được biết đến với phương thức mà chúng được khai báo.

Toàn cầu mô tả các mục dữ liệu được biết đến với tất cả các phương thức trong một chương trình.

Một lập luận đến một phương pháp là một giá trị truyền cho một phương pháp trong các cuộc gọi đến phương pháp này.

Một tham số để một phương pháp là một mục dữ liệu được định nghĩa trong một tiêu đề phương pháp mà chấp nhận dữ liệu thông qua

vào phương pháp từ bên ngoài.


Một danh sách tham số là tất cả các kiểu dữ liệu và tên tham số xuất hiện trong một tiêu đề phương pháp.

Chữ ký của một phương thức bao gồm tên và danh sách tham số của nó.

Một biến được truyền vào một phương thức được truyền theo giá trị ; nghĩa là, một bản sao giá trị của nó được gửi đến
phương thức và được lưu trữ trong một vị trí bộ nhớ mới có thể truy cập vào phương thức.

Các tham số thực tế là các đối số trong một lời gọi phương thức.

Các tham số chính thức là các biến trong khai báo phương thức chấp nhận các giá trị từ
các thông số thực tế.

Kiểu trả về của một phương thức cho biết kiểu dữ liệu của giá trị mà phương thức sẽ gửi lại
vị trí nơi cuộc gọi phương thức đã được thực hiện.

Một phương thức void trả về không có giá trị.

Kiểu của một phương thức là kiểu giá trị trả về của nó.

Chi phí đề cập đến tất cả các nguồn lực và thời gian cần thiết cho một hoạt động.

Một IPO biểu đồ xác định và phân loại từng hạng mục cần thiết trong phương pháp này là có liên quan đến
đầu vào, xử lý hoặc đầu ra.
Trang 47

Được chuyển bởi tham chiếu mô tả cách các giá trị được chấp nhận vào một phương thức khi phương thức
nhận được mục địa chỉ bộ nhớ thực tế. Mảng được truyền bằng tham chiếu.

Quá tải liên quan đến việc cung cấp các ý nghĩa đa dạng cho một mã định danh duy nhất.

Tính đa hình là khả năng của một phương pháp hoạt động thích hợp theo
bối cảnh.

Để quá tải một phương thức là tạo nhiều phiên bản có cùng tên nhưng khác
danh sách tham số.

Các phương thức mơ hồ là những phương thức mà trình biên dịch không thể phân biệt được
vì chúng có cùng tên và kiểu tham số.

Việc thực hiện ẩn là một nguyên tắc lập trình mô tả sự đóng gói của
chi tiết phương pháp.

Các giao diện cho một phương pháp bao gồm các phương pháp của kiểu trả về, tên và lập luận. Nó là
phần mà khách hàng nhìn thấy và sử dụng.

Một hộp đen là việc sử dụng các lập trình viên tương tự để tham khảo thực hiện phương pháp ẩn
chi tiết.

Tính liên kết là một thước đo về cách các câu lệnh nội bộ của một phương pháp phục vụ để hoàn thành
mục đích của phương pháp.

Sự gắn kết chức năng xảy ra khi tất cả các hoạt động trong một phương pháp đóng góp vào hiệu suất của
chỉ một nhiệm vụ. Sự gắn kết chức năng là mức độ gắn kết cao nhất; bạn nên phấn đấu cho nó trong
tất cả các phương pháp bạn viết.

Khớp nối là thước đo độ bền của kết nối giữa hai chương trình
các phương pháp.
Sự kết hợp chặt chẽ xảy ra khi các phương pháp phụ thuộc vào nhau quá mức; nó tạo ra các chương trình
dễ bị sai sót hơn.

Khớp nối lỏng lẻo xảy ra khi các phương pháp không phụ thuộc vào những phương pháp khác.

Đệ quy xảy ra khi một phương thức được định nghĩa theo nghĩa của chính nó.

Một phương pháp đệ quy là một phương pháp mà các cuộc gọi riêng của mình.

Các ngăn xếp là một vùng nhớ chứa địa chỉ mà phương pháp này cần trở lại.

Các trường hợp đệ quy mô tả các giá trị đầu vào khiến một phương thức đệ quy thực thi
lần nữa.

Các trường hợp cơ sở hoặc chấm dứt hợp của một phương pháp đệ quy mô tả các giá trị mà kết thúc
sự lặp lại.
Trang 48

Bài tập

Câu hỏi đánh giá

1. Điều nào sau đây là đúng?

a. Một chương trình có thể gọi tối đa một phương thức.


b. Một phương thức có thể chứa một hoặc nhiều phương thức khác.
c. Một chương trình có thể chứa một phương thức gọi một phương thức khác.
d. Những điều ở trên đều đúng.
2. Phương thức nào sau đây phải có?

a. một danh sách tham số c. một giá trị trả lại


b. một tiêu đề d. tất cả những điều trên

3. Nội dung nào sau đây liên quan chặt chẽ nhất đến khái niệm địa phương?
a. trừu tượng c. cấp độ chương trình
b. hướng đối tượng d. trong phạm vi
4. Mặc dù tham số điều khoản và đối số có liên quan chặt chẽ với nhau, nhưng sự khác biệt là
đối số đó đề cập đến .
a. một giá trị trong một cuộc gọi phương thức c. một tham số chính thức
b. một hằng số đã qua d. một biến cục bộ cho một phương thức

5. Giao diện của một phương thức là .


a. danh sách tham số c. định danh
b. loại trả lại d. tất cả những điều trên
6. Khi bạn viết khai báo cho một phương thức có thể nhận một tham số,
cái nào sau đây phải được đưa vào khai báo phương thức?
a. tên của đối số sẽ được sử dụng để gọi phương thức
b. tên địa phương cho tham số
c. kiểu dữ liệu của tham số
d. hai trong số những điều trên
7. Khi bạn sử dụng một tên biến trong một cuộc gọi phương thức, nó như biến trong
tiêu đề phương thức.

a. có thể có cùng tên c. phải có cùng tên


b. không thể có cùng tên d. không thể có cùng một kiểu dữ liệu
9/7/2021 Kỹ thuật mô đun hóa nâng cao

Trang 49

Bài tập

8. Giả sử rằng bạn đã viết một phương thức với tiêu đề void myMethod (num a,
chuỗi b) . Cách gọi nào sau đây là đúng?
a. myMethod (12) c. myMethod ("Tạm biệt")
b. myMethod (12, "Xin chào") d. Không thể nói được.
419
9. Giả sử rằng bạn đã viết một phương thức với tiêu đề num yourMethod (string
tên, mã số) . Kiểu của phương pháp là .
a. num c. num và chuỗi
b. chuỗi d. vô hiệu
10. Giả sử rằng bạn đã viết một phương thức với chuỗi tiêu đề myMethod (num
điểm, cấp chuỗi) .
Cũng giả sử rằng bạn đã khai báo một biến số
kiểm tra được đặt tên . Cách gọi nào sau đây là đúng?
a. myMethod () c. myMethod (kiểm tra, thử nghiệm)
b. myMethod (thử nghiệm) d. myMethod (kiểm tra, "A")
11. Giá trị được sử dụng trong câu lệnh trả về của một phương thức phải .
a. là số
b. là một biến
c. khớp với kiểu dữ liệu được sử dụng trước tên phương thức trong tiêu đề
d. hai trong số những điều trên
12. Khi một phương thức nhận được một bản sao của giá trị được lưu trữ trong một đối số được sử dụng trong
cuộc gọi phương thức, nó có nghĩa là biến đã .

a. vô danh
b. qua giá trị
c. thông qua tham chiếu
d. đã gán giá trị ban đầu của nó khi nó được khai báo
13. Một phương thức void .
a. không có câu lệnh nào c. không trả lại gì
b. không yêu cầu tham số d. không có tên
14. Khi một mảng được truyền cho một phương thức, nó sẽ .

https://translate.googleusercontent.com/translate_f 45/52
9/7/2021 Kỹ thuật mô đun hóa nâng cao
a. thông qua tham chiếu c. không có tên trong phương pháp
b. qua giá trị d. không thể thay đổi trong phương pháp

15. Khi bạn quá tải trò chơi, bạn viết nhiều phương thức với cùng một .

a. Tên c. số lượng thông số


b. danh sách tham số d. loại trả lại

Trang 50

CHƯƠNG 9 Kỹ thuật mô đun hóa nâng cao

16. Một chương trình chứa một phương thức với tiêu đề là num tínhTaxes (số lượng num,
tên chuỗi) .
Phương thức nào sau đây có thể cùng tồn tại trong cùng một chương trình
không có sự mơ hồ có thể có?
a. num tínhTaxes (tên chuỗi, số lượng num)
420 b. Chuỗi tính toán Thuế (số tiền, người nộp thuế chuỗi)
c. số tính toán thuế (số hàng nămPay, chuỗi người nộp thuếId)
d. Tất cả những điều này có thể cùng tồn tại mà không có sự mơ hồ.

17. Các phương thức trong cùng một chương trình có tên giống nhau và danh sách tham số giống nhau
Chúng tôi .

a. quá tải c. choáng ngợp


b. làm việc quá sức d. mơ hồ

18. Các phương thức trong các chương trình khác nhau có tên giống nhau và danh sách tham số giống hệt nhau
Chúng tôi .
a. quá tải c. cả hai ở trên
b. bất hợp pháp d. không có cái nào ở trên

19. Khái niệm về mô tả chính xác nhất cách một phương thức gọi không phải là
nhận thức về các câu lệnh trong một phương thức được gọi.
a. sự trừu tượng c. ẩn thực hiện
b. hướng đối tượng d. sự đóng gói

20. Lập trình viên nên cố gắng .

a. tăng khớp nối


b. tăng sự gắn kết
c. cả hai ở trên
d. chẳng phải A cũng chẳng phải b

Bài tập lập trình

1. Tạo biểu đồ IPO cho từng phương pháp sau:


a. Phương pháp tính toán số tiền nợ khi kiểm tra nhà hàng, bao gồm
tiền boa
b. Phương pháp tính toán các chi phí liên quan đến giáo dục hàng năm của bạn

https://translate.googleusercontent.com/translate_f 46/52
9/7/2021 Kỹ thuật mô đun hóa nâng cao
c. Phương pháp tính toán chi phí nhà ở hàng năm của bạn, bao gồm tiền thuê nhà hoặc
thanh toán thế chấp và các tiện ích

Trang 51

Bài tập

2. Tạo logic cho một chương trình liên tục nhắc người dùng về một số
đô la cho đến khi người dùng nhập 0. Chuyển mỗi số tiền đã nhập cho một phương pháp chuyển đổi
hiển thị bảng phân tích số tiền đã chuyển thành ít hóa đơn nhất; trong khác
từ, phương pháp tính số giây 20, 10, 5 và 1 cần thiết.
3. a. Tạo logic cho một chương trình tính toán và hiển thị số lượng
421
số tiền bạn sẽ có nếu đầu tư $ 5000 với lãi suất đơn giản 2% cho
một năm. Tạo một phương thức riêng để thực hiện phép tính và trả về kết quả
được hiển thị.
b. Sửa đổi chương trình trong Bài tập 3a để chương trình chính nhắc người dùng
cho số tiền và chuyển nó sang phương pháp tính lãi.
c. Sửa đổi chương trình trong Bài tập 3b để chương trình chính cũng nhắc
người dùng cho lãi suất và chuyển cả số tiền và lãi suất
tỷ lệ với phương pháp tính lãi.

4. Tạo logic cho một chương trình chấp nhận mức lương hàng năm làm đầu vào. Vượt qua
lương cho một phương pháp tính toán khoản thanh toán nhà ở hàng tháng cao nhất mà người dùng
có khả năng chi trả, giả sử rằng tổng số tiền thanh toán của năm không quá 25 phần trăm
tiền lương hàng năm.
5. a. Tạo logic cho một chương trình thực hiện các chức năng số học. Thiết kế
chương trình chứa hai biến số và nhắc người dùng nhập các giá trị cho
các biến. Truyền cả hai biến cho các phương thức có tên sum () và difference () .
Tạo logic cho các phương thức sum () và difference () ; họ tính toán
tổng và hiệu giữa các giá trị của hai đối số, tương ứng. Mỗi
phương pháp sẽ thực hiện tính toán thích hợp và hiển thị kết quả.
b. Sửa đổi chương trình trong Bài tập 5a để chuyển hai giá trị đã nhập vào
một phương thức có tên getChoice () . Phương thức getChoice () hỏi người dùng
liệu phép cộng hay phép trừ nên được thực hiện và sau đó chuyển hai
giá trị của phương thức thích hợp, nơi kết quả được hiển thị.
6. Tạo logic cho một chương trình liên tục nhắc người dùng nhập một số
cho đến khi người dùng nhập 0. Ứng dụng lần lượt chuyển giá trị đến
các phương pháp sau:
Một phương pháp hiển thị tất cả các số nguyên từ 1 trở lên và bao gồm
đã nhập số
Một phương pháp tính tổng của tất cả các số nguyên từ 1 trở lên và
bao gồm cả số đã nhập
Một phương pháp tính tích của tất cả các số nguyên từ 1 đến
và bao gồm cả số đã nhập
7. Tạo logic cho một chương trình gọi một phương thức tính giá cuối cùng cho một
giao dịch mua bán. Chương trình chứa các biến giữ giá của một mặt hàng,
hoa hồng của nhân viên bán hàng được biểu thị bằng tỷ lệ phần trăm và chiết khấu cho khách hàng
được biểu thị dưới dạng phần trăm. Tạo một phương thức CalculPrice () xác định

https://translate.googleusercontent.com/translate_f 47/52
9/7/2021 Kỹ thuật mô đun hóa nâng cao

Trang 52

CHƯƠNG 9 Kỹ thuật mô đun hóa nâng cao

giá cuối cùng và trả về giá trị cho phương thức gọi. Tính toán giá ()
phương pháp yêu cầu ba đối số: giá sản phẩm, tỷ lệ hoa hồng của nhân viên bán hàng và
tỷ lệ chiết khấu của khách hàng. Giá cuối cùng của sản phẩm là giá gốc cộng với tiền
số tiền nhiệm vụ trừ đi số tiền chiết khấu. Chiết khấu cho khách hàng được coi là một
tỷ lệ phần trăm của tổng giá sau khi hoa hồng nhân viên bán hàng đã được thêm vào
422 giá gốc.
8. Tạo logic cho một chương trình liên tục nhắc người dùng về hai số
giá trị đại diện cho kích thước của một căn phòng theo bộ. Bao gồm hai quá tải
các phương pháp tính diện tích của căn phòng. Một phương thức sử dụng hai para-
mét và tính diện tích bằng cách nhân các tham số. Người khác mất một
tham số số đơn, được bình phương để tính diện tích. Mỗi phương pháp hiển thị
kết quả tính toán của nó. Chấp nhận đầu vào và trả lời như sau:
Khi người dùng nhập số không cho giá trị đầu tiên, hãy kết thúc chương trình.

Nếu người dùng nhập một số âm cho một trong hai giá trị, hãy tiếp tục nhắc lại
người dùng cho đến khi giá trị không âm.
Nếu cả hai số đã nhập đều lớn hơn 0, hãy gọi phiên bản phương pháp
chấp nhận hai tham số và chuyển cho nó cả hai giá trị.
Nếu giá trị thứ hai bằng 0, hãy gọi phiên bản của phương thức chỉ chấp nhận một
và chuyển cho nó giá trị khác không.

9. a. Lập kế hoạch logic cho chương trình của công ty bảo hiểm để xác định chính sách
phí bảo hiểm. Chương trình liên tục nhắc người dùng về hợp đồng bảo hiểm
con số. Khi người dùng nhập một giá trị sentinel thích hợp, hãy kết thúc chương trình.
Gọi một phương thức nhắc mỗi người dùng về loại chính sách cần thiết — sức khỏe hoặc
Tự động. Mặc dù phản hồi của người dùng không cho biết trạng thái hoặc tự động, hãy tiếp tục
nhắc người dùng. Khi giá trị hợp lệ, hãy trả về nó từ phương thức. Vượt qua
phản hồi của người dùng đối với một phương pháp mới trong đó phí bảo hiểm được đặt và trả về— $ 550
đối với chính sách sức khỏe hoặc $ 225 đối với chính sách ô tô. Hiển thị kết quả cho từng chính sách.

b. Sửa đổi Bài tập 9a để phương thức cài đặt đặc biệt gọi một trong hai
các phương pháp bổ sung — một phương pháp xác định phí bảo hiểm sức khỏe hoặc một phương pháp
xác định phí bảo hiểm tự động. Phương thức bảo hiểm sức khỏe hỏi người dùng liệu
họ hút thuốc; phí bảo hiểm là $ 550 cho người hút thuốc và $ 345 cho người không hút thuốc. Các
phương thức bảo hiểm ô tô yêu cầu người dùng nhập số lượng vé giao thông mà họ
đã nhận được trong ba năm qua. Phí bảo hiểm là $ 225 cho người lái xe có ba
vé trở lên, $ 190 cho những người có một hoặc hai vé và $ 110 cho những người có
không có vé. Mỗi phương thức trong số hai phương pháp này đều trả về số tiền đặc biệt cho
phương thức gọi, trả về số tiền sẽ được hiển thị.

https://translate.googleusercontent.com/translate_f 48/52
9/7/2021 Kỹ thuật mô đun hóa nâng cao

Trang 53

Bài tập

10. Tạo logic cho một chương trình nhắc người dùng nhập các giá trị số cho
một tháng, ngày và năm. Sau đó, chuyển ba biến cho sau
phương pháp:
a. Một phương pháp hiển thị ngày với dấu gạch ngang theo thứ tự tháng-ngày-năm, vì nó là
thường được đại diện ở Hoa Kỳ — ví dụ: 6-24-2015 423
b. Một phương pháp hiển thị ngày với dấu gạch ngang theo thứ tự ngày-tháng-năm, vì nó là
thường được đại diện ở Vương quốc Anh — ví dụ: 24-6-2015
c. Một phương pháp hiển thị ngày với dấu gạch ngang theo thứ tự năm-tháng-ngày, vì nó là
được trình bày trong Tiêu chuẩn Quốc tế — ví dụ: 2015-6-24
d. Một phương pháp nhắc người dùng về định dạng mong muốn (“US”, “UK” hoặc “IS”)
và sau đó chuyển ba giá trị cho một trong các phương pháp được mô tả trong phần a, b,
và c của bài tập này

11. Tạo logic cho một chương trình tính toán giá khách sạn tại Cornwall's
Quán trọ đồng quê. Bao gồm hai phương thức được nạp chồng có tên computeRate () . Một
phiên bản chấp nhận một số ngày và tính tỷ lệ ở mức $ 99,99 mỗi ngày.
Người kia chấp nhận một số ngày và mã cho gói bữa ăn. Nếu mã là
A, ba bữa ăn mỗi ngày được bao gồm và giá là $ 169,00 mỗi ngày. Nếu
mã là C, bao gồm bữa sáng và giá $ 112,00 mỗi ngày. Tất cả những thứ khác
mã không hợp lệ. Mỗi phương thức trả về tỷ lệ cho chương trình gọi trong đó
nó được hiển thị. Chương trình chính hỏi người dùng về số ngày trong một
ở và liệu các bữa ăn có nên được bao gồm không; sau đó, dựa trên người dùng
phản hồi, chương trình gọi phương thức đầu tiên hoặc nhắc bữa ăn
mã kế hoạch và gọi phương thức thứ hai.

12. Tạo logic cho một chương trình nhắc người dùng về 10 số và lưu trữ chúng
trong một mảng. Truyền mảng tới một phương thức đảo ngược thứ tự của các số.
Hiển thị các số đã đảo ngược trong chương trình chính.
13. Tạo logic cho một chương trình nhắc người dùng nhập sáu số và lưu trữ chúng
trong một mảng. Chuyển mảng tới một phương thức tính trung bình cộng của
số và trả về giá trị cho chương trình đang gọi. Hiển thị từng số và
nó cách giá trị trung bình cộng bao xa. Tiếp tục nhắc người dùng về
bộ bổ sung gồm sáu số cho đến khi người dùng muốn thoát.

Trang 54

CHƯƠNG 9 Kỹ thuật mô đun hóa nâng cao


https://translate.googleusercontent.com/translate_f 49/52
9/7/2021 Kỹ thuật mô đun hóa nâng cao

14. Phòng Dịch vụ Thông tin tại Thư viện Springfield đã tạo
phương pháp với các chữ ký sau:

Chữ ký Sự miêu tả

424 num getNumber (num cao, num thấp) Nhắc người dùng về một số và tiếp tục
nhắc nhở cho đến khi con số giảm xuống giữa mức cao được chỉ định
và giới hạn thấp; trả về một số hợp lệ

chuỗi getCharacter () Nhắc người dùng về một chuỗi ký tự và trả về


đã nhập chuỗi

num lookUpISBN (tiêu đề chuỗi) Chấp nhận tên sách và trả lại ISBN;
trả về 0 nếu không tìm thấy sách

string lookUpTitle (num isbn) Chấp nhận ISBN của một cuốn sách và trả lại một tên sách; trả lại
một ký tự khoảng trắng nếu không tìm thấy sách

chuỗi isBookAvailable (num isbn) Chấp nhận ISBN, tìm kiếm cơ sở dữ liệu thư viện và
trả về "Y" hoặc "N" cho biết sách có
hiện đang có sẵn

Bảng 9-1 Phương pháp thư viện

a. Thiết kế một chương trình tương tác thực hiện những điều sau đây, sử dụng phần viết sẵn
bất cứ khi nào chúng thích hợp.

Nhắc người dùng và đọc số thẻ thư viện, số này phải ở giữa
1000 và 9999.
Nhắc người dùng và đọc một tùy chọn tìm kiếm — 1 để tìm kiếm một cuốn sách bằng
ISBN, 2 để tìm kiếm sách theo tiêu đề và 3 để thoát. Nếu mục nhập không hợp lệ,
lặp lại yêu cầu.
Trong khi người dùng không nhập 3, hãy nhắc ISBN hoặc tiêu đề dựa trên
lựa chọn trước đó của người dùng. Nếu người dùng nhập ISBN, hãy lấy và hiển thị
tên sách và yêu cầu người dùng nhập "Y" hoặc "N" để xác nhận xem tên sách
đúng.
Nếu người dùng đã nhập một ISBN hợp lệ hoặc một tiêu đề khớp với một ISBN hợp lệ, hãy kiểm tra
sách có sẵn hay không và hiển thị thông báo thích hợp cho người dùng.
Người dùng có thể tiếp tục tìm kiếm sách cho đến khi họ nhập 3 là
tùy chọn tìm kiếm.

b. Phát triển logic triển khai từng phương pháp trong Bài tập 14a.

Trang 55

Bài tập

15. Mỗi chương trình trong Hình 9-25 sử dụng một phương pháp đệ quy. Cố gắng xác định
đầu ra trong mỗi trường hợp.

https://translate.googleusercontent.com/translate_f 50/52
9/7/2021 Kỹ thuật mô đun hóa nâng cao

a. b. c.
khởi đầu khởi đầu khởi đầu 425
đầu ra đệ quyA (0) đầu ra đệ quyB (2) đầu ra đệ quyC (2)
dừng lại dừng lại dừng lại
num đệ quyA (num x) num đệ quyB (num x) num đệ quyC (num x)
kết quả num kết quả num kết quả num
nếu x = 0 thì nếu x = 0 thì nếu x = 1 thì
kết quả = x kết quả = x kết quả = x
khác khác khác
kết quả = x * kết quả = x * kết quả = x *
(đệ quyA (x - 1)) (đệ quyB (x - 1)) (đệ quyC (x - 1))
endif endif endif
trả về kết quả trả về kết quả trả về kết quả

Hình 9-25 Các vấn đề cho Bài tập 15


© 2015 Cengage Learning

Thực hiện bảo trì


1. Tệp có tên MAINTENANCE09-01.txt được bao gồm trong tệp có thể tải xuống của bạn
hồ sơ sinh viên. Giả sử rằng chương trình này là một chương trình làm việc trong tổ chức của bạn
và nó cần sửa đổi như được mô tả trong các nhận xét (các dòng bắt đầu bằng
hai dấu gạch chéo) ở đầu tệp. Công việc của bạn là thay đổi chương trình để đáp ứng
các thông số kỹ thuật mới.

Tìm lỗi

1. Các tệp có thể tải xuống của bạn cho Chương 9 bao gồm DEBUG09-01.txt, DEBUG09-02.txt,
và DEBUG09-03.txt. Mỗi tệp bắt đầu với một số nhận xét mô tả
vấn đề. Nhận xét là những dòng bắt đầu bằng hai dấu gạch chéo (//). Theo dõi
nhận xét, mỗi tệp chứa mã giả có một hoặc nhiều lỗi bạn phải tìm
và sửa lại.
2. Các tệp có thể tải xuống của bạn cho Chương 9 bao gồm một tệp có tên DEBUG09-04.jpg
chứa một sơ đồ có lỗi cú pháp và / hoặc lôgic. Kiểm tra lưu đồ và
sau đó tìm và sửa tất cả các lỗi.

Khu vực chơi game

1. Trong phần Khu vực trò chơi của Chương 6 và 8, bạn đã thiết kế logic cho một bài kiểm tra
chứa các câu hỏi về chủ đề bạn chọn. Bây giờ, hãy sửa đổi chương trình để
nó chứa một loạt năm câu hỏi trắc nghiệm có liên quan đến chủ đề
lựa chọn của bạn. Mỗi câu hỏi có bốn lựa chọn trả lời. Ngoài ra, hãy tạo một song song

Trang 56

CHƯƠNG 9 Kỹ thuật mô đun hóa nâng cao

mảng chứa câu trả lời đúng cho mỗi câu hỏi — A, B, C hoặc D. Lần lượt, vượt qua
mỗi câu hỏi đến một phương pháp hiển thị câu hỏi và chấp nhận
câu trả lời. Nếu người chơi không nhập một lựa chọn câu trả lời hợp lệ, buộc người chơi phải
nhập lại sự lựa chọn. Trả lại câu trả lời hợp lệ (nhưng không nhất thiết phải đúng) của người dùng cho
chương trình chính. Sau khi câu trả lời của người dùng được đưa trở lại chương trình chính, hãy chuyển nó
426
và câu trả lời đúng cho một phương pháp xác định xem các giá trị có bằng nhau hay không
và hiển thị một thông báo thích hợp. Sau khi người dùng trả lời tất cả năm câu hỏi,

https://translate.googleusercontent.com/translate_f 51/52
9/7/2021 Kỹ thuật mô đun hóa nâng cao
hiển thị số câu trả lời đúng và sai mà người dùng đã chọn.
2. Trong phần Game Zone của Chương 6, bạn đã thiết kế logic cho trò chơi
Hangman, trong đó người dùng đoán các chữ cái trong một từ ẩn. Cải thiện trò chơi để
lưu trữ một mảng 10 từ. Từng từ một, chuyển từng từ đến một phương thức cho phép
người dùng để đoán các chữ cái liên tục cho đến khi trò chơi được giải quyết. Phương thức trả về
số lần đoán để hoàn thành từ đó. Lưu trữ số trong một mảng
trước khi quay lại phương thức cho từ tiếp theo. Sau khi tất cả 10 từ đã được
đoán, hiển thị một bản tóm tắt về số lượng đoán được yêu cầu cho mỗi từ như
cũng như số lần đoán trung bình cho mỗi từ.

Lên cho cuộc thảo luận

1. Một lợi thế khi viết một chương trình được chia nhỏ thành các phương thức là
cấu trúc cho phép các lập trình viên khác nhau viết các phương thức riêng biệt, do đó phân chia
công việc. Bạn muốn tự mình viết một chương trình lớn hay làm việc trên một
trong đó mỗi lập trình viên tạo ra một hay nhiều phương thức? Tại sao?
2. Trong chương này, bạn đã học được rằng các triển khai ẩn thường được cho là tồn tại trong một
hộp đen. Ưu điểm và nhược điểm của phương pháp này là gì ở cả hai
lập trình và cuộc sống thực?

https://translate.googleusercontent.com/translate_f 52/52

You might also like