3. Luyện Tập Nâng Cao về Class
3.1 EG. 1: Class Account
Một lớp được gọi Account
, mô hình hóa một tài khoản ngân hàng, được thiết kế như thể hiện trong sơ đồ lớp. Nó chứa các thành viên sau:
- Hai
private
biến đối tượng: accountNumber
( int
) và balance
( double
) duy trì số dư tài khoản hiện tại.
- Constructor
- Getters và Setters cho các
private
biến thể hiện. Không có setter nào accountNumber
vì nó không được thiết kế để thay đổi.
public
phương thức credit()
và debit()
, cộng / trừ amount
tương ứng đã cho / từ số dư.
- A
toString()
, trả về " A/C no:xxx, Balance=$xxx.xx
", balance
được làm tròn đến hai chữ số thập phân.
Viết Account
class và trình điều khiển kiểm tra để kiểm tra tất cả các public
phương thức.
Lớp Account (Account.java)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
44
47
48
49
50
|
public class Account {
private int accountNumber;
private double balance;
public Account(int accountNumber, double balance) {
this.accountNumber = accountNumber;
this.balance = balance;
}
public Account(int accountNumber) {
this.accountNumber = accountNumber;
this.balance = 0.0;
}
public int getAccountNumber() {
return this.accountNumber;
}
public double getBalance() {
return this.balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public void credit(double amount) {
balance += amount;
}
public void debit(double amount) {
if (balance < amount) {
System.out.println("amount withdrawn exceeds the current balance!");
} else {
balance -= amount;
}
}
public String toString() {
return String.format("A/C no:%d, Balance=%.2f", accountNumber, balance);
}
}
|
Test Driver Account Class (TestAccount.java)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public class TestAccount {
public static void main(String[] args) {
Account a1 = new Account(1234, 99.99);
System.out.println(a1);
Account a2 = new Account(8888);
System.out.println(a2);
a1.setBalance (88.88);
System.out.println(a1);
System.out.println("The account Number is: " + a1.getAccountNumber());
System.out.println("The balance is: " + a1.getBalance());
a1.credit(10);
System.out.println(a1);
a1.debit(5);
System.out.println(a1);
a1.debit(500);
System.out.println(a1);
}
}
|
Kết quả đầu ra mong muốn:
A/C no:1234, Balance=99.99
A/C no:8888, Balance=0.00
A/C no:1234, Balance=88.88
Account Number is: 1234
Balance is: 88.88
A/C no:1234, Balance=98.88
A/C no:1234, Balance=93.88
amount withdrawn exceeds the current balance!
A/C no:1234, Balance=93.88
3.2 EG. 2: Class Date
Một lớp Date
mô hình một ngày theo lịch với ngày, tháng và năm, được thiết kế như thể hiện trong sơ đồ lớp. Nó chứa các thành viên sau:
- 3
private
biến day
, month
và year
.
- Có
public
constructor , getters và setters cho các private
biến thể hiện.
- Một phương thức
setDate()
, thiết lập day
, month
và year
.
- A
toString()
, trả về " DD/MM/YYYY
", với số 0 đứng đầu DD
và MM
nếu có.
Viết lớp Date
và trình điều khiển kiểm tra để kiểm tra tất cả các public
phương thức. Không hợp lệ đầu vào được yêu cầu cho day
, month
và year
.
Class Date (Date.java)
public class Date {
private int year, month, day;
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public int getYear() {
return this.year;
}
public int getMonth() {
return this.month;
}
public int getDay() {
return this.day;
}
public void setYear(int year) {
this.year = year;
}
public void setMonth(int month) {
this.month = month;
}
public void setDay(int day) {
this.day = day;
}
public String toString() {
return String.format("%02d/%02d/%4d", month, day, year);
}
public void setDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
}
Test Driver cho Date Class (TestDate.java)
public class TestDate {
public static void main(String[] args) {
Date d1 = new Date(2016, 4, 6);
System.out.println(d1);
d1.setYear(2012);
d1.setMonth(12);
d1.setDay(23);
System.out.println(d1);
System.out.println("Year is: " + d1.getYear());
System.out.println("Month is: " + d1.getMonth());
System.out.println("Day is: " + d1.getDay());
d1.setDate(2988, 1, 2);
System.out.println(d1);
}
}
Đầu ra mong muốn:
June 4, 2016
12/23/2012
Year is: 2012
Month is: 12
Day is: 23
2/1/2988
3.3 EG. 3: Class Time
Một lớp được gọi Time
, mô hình một thể hiện thời gian với giờ, phút và giây, được thiết kế như thể hiện trong sơ đồ lớp. Nó chứa các thành viên sau:
- 3
private
biến dụ hour
, minute
và second
.
- Nhà xây dựng, getters và setters.
- Một phương thức
setTime()
để thiết lập hour
, minute
và second
.
- Một
toString()
trả về " hh:mm:ss
" với số 0 đứng đầu nếu có.
- Một phương pháp
nextSecond()
tiến bộ this
thể hiện thêm một giây. Nó trả về this
thể hiện để hỗ trợ các hoạt động chuỗi (xếp tầng), ví dụ , t1.nextSecond().nextSecond()
. Hãy lưu ý rằng nextSecond()
trong 23:59:59
là 00:00:00
.
Viết class Time
và trình điều khiển kiểm tra để kiểm tra tất cả các phương thức công khai. Không có xác nhận đầu vào được yêu cầu.
Class Time (Time.java)
public class Time {
private int second, minute, hour;
public Time(int second, int minute, int hour) {
this.second = second;
this.minute = minute;
this.hour = hour;
}
public Time() {
this.second = 0;
this.minute = 0;
this.hour = 0;
}
public int getSecond() {
return this.second;
}
public int getMinute() {
return this.minute;
}
public int getHour() {
return this.hour;
}
public void setSecond(int second) {
this.second = second;
}
public void setMinute(int minute) {
this.minute = minute;
}
public void setHour(int hour) {
this.hour = hour;
}
public String toString() {
return String.format("%02d:%02d:%02d", hour, minute, second);
}
public void setTime(int second, int minute, int hour) {
this.second = second;
this.minute = minute;
this.hour = hour;
}
public Time nextSecond() {
++second;
if (second >= 60) {
second = 0;
++minute;
if (minute >= 60) {
minute = 0;
++hour;
if (hour >= 24) {
hour = 0;
}
}
}
return this;
}
}
Test Driver (TestTime.java)
public class TestTime {
public static void main(String[] args) {
Time t1 = new Time(1, 2, 3);
System.out.println(t1);
Time t2 = new Time();
System.out.println(t2);
t1.setHour (4);
t1.setMinute(5);
t1.setSecond(6);
System.out.println(t1);
System.out.println("Hour is: " + t1.getHour());
System.out.println("Minute is: " + t1.getMinute());
System.out.println("Second is: " + t1.getSecond());
t1.setTime(58, 59, 23);
System.out.println(t1);
System.out.println(t1.nextSecond());
System.out.println(t1.nextSecond().nextSecond().nextSecond());
}
}
Kết quả đầu ra mong muốn:
03:02:01
00:00:00
04:05:06
Hour is: 4
Minute is: 5
Second is: 6
23:59:58
23:59:59
00:00:02
3.4 EG. 4: Class Time và Input Validation (xác thực đầu vào)
Trong ví dụ này, chúng ta sẽ xác nhận các đầu vào để đảm bảo rằng 0≤hour≤23
, 0≤minute≤59
, và 0≤second≤59
. Chúng tôi viết lại Time
lớp của chúng tôi như sau. Hãy lưu ý rằng tất cả các xác nhận được thực hiện trong setters. Tất cả các phương thức khác (chẳng hạn như các hàm tạo và setTime()
gọi setters để thực hiện xác nhận đầu vào - để tránh trùng lặp mã.
public class Time {
private int second;
private int minute;
private int hour;
public void setSecond(int second) {
if (second >=0 && second <= 59) {
this.second = second;
} else {
this.second = 0;
System.out.println("error: invalid second");
}
}
public void setMinute(int minute) {
if (minute >=0 && minute <= 59) {
this.minute = minute;
} else {
this.minute = 0;
System.out.println("error: invalid minute");
}
}
public void setHour(int hour) {
if (hour >=0 && hour <= 23) {
this.hour = hour;
} else {
this.hour = 0;
System.out.println("error: invalid hour");
}
}
public void setTime(int second, int minute, int hour) {
this.setSecond(second);
this.setMinute(minute);
this.setHour(hour);
}
public Time(int second, int minute, int hour) {
this.setTime(second, minute, hour);
}
public Time() {
this.second = 0;
this.minute = 0;
this.hour = 0;
}
public int getSecond() {
return this.second;
}
public int getMinute() {
return this.minute;
}
public int getHour() {
return this.hour;
}
public String toString() {
return String.format("%02d:%02d:%02d", hour, minute, second);
}
public Time nextSecond() {
++second;
if (second == 60) {
second = 0;
++minute;
if (minute == 60) {
minute = 0;
++hour;
if (hour == 24) {
hour = 0;
}
}
}
return this;
}
}
3.5 EG. 5 (Nâng Cao): Class Time Xác Thực Đầu Vào thông qua xử lý lỗi ngoại lệ
Trong ví dụ trước, chúng ta in một thông báo lỗi và đặt biến thành 0, nếu đầu vào không hợp lệ. Điều này là ít hoàn hảo hơn. Cách thích hợp để xử lý các đầu vào không hợp lệ là thông qua cơ chế được gọi là cơ chế xử lý ngoại lệ .
Bản sửa đổi Time.java
sử dụng cơ chế xử lý ngoại lệ như sau:
public class Time {
private int second;
private int minute;
private int hour;
public void setSecond(int second) {
if (second >=0 && second <= 59) {
this.second = second;
} else {
throw new IllegalArgumentException("Invalid second!");
}
}
public void setMinute(int minute) {
if (minute >=0 && minute <= 59) {
this.minute = minute;
} else {
throw new IllegalArgumentException("Invalid minute!");
}
}
public void setHour(int hour) {
if (hour >=0 && hour <= 23) {
this.hour = hour;
} else {
throw new IllegalArgumentException("Invalid hour!");
}
}
public void setTime(int second, int minute, int hour) {
this.setSecond(second);
this.setMinute(minute);
this.setHour(hour);
}
public Time(int second, int minute, int hour) {
this.setTime(second, minute, hour);
}
public Time() {
this.second = 0;
this.minute = 0;
this.hour = 0;
}
public int getSecond() {
return this.second;
}
public int getMinute() {
return this.minute;
}
public int getHour() {
return this.hour;
}
public String toString() {
return String.format("%02d:%02d:%02d", hour, minute, second);
}
public Time nextSecond() {
++second;
if (second == 60) {
second = 0;
++minute;
if (minute == 60) {
minute = 0;
++hour;
if (hour == 24) {
hour = 0;
}
}
}
return this;
}
}
Exception Handling
Xử lý ngoại lệ
Phải làm gì nếu không hợp lệ hour
, minute
hoặc second
được đưa ra làm đầu vào? In một thông báo lỗi? Chấm dứt chương trình đột ngột? Tiếp tục hoạt động bằng cách đặt tham số về mặc định của nó? Đây là một quyết định thực sự khó khăn và không có giải pháp hoàn hảo phù hợp với mọi tình huống.
Trong Java, thay vì in một thông báo lỗi, bạn có thể ném một Exception
đối tượng được gọi là (chẳng hạn như IllegalArgumentException
) cho người gọi và để người gọi xử lý ngoại lệ một cách duyên dáng. Ví dụ,
public void setHour(int hour) {
if (hour >= 0 && hour <= 23) {
this.hour = hour;
} else {
throw new IllegalArgumentException("Invalid hour!");
}
}
Người gọi có thể sử dụng cấu trúc try-catch
để xử lý ngoại lệ một cách duyên dáng . Ví dụ,
try {
Time t = new Time(60, 59, 12);
System.out.println("This and the remaining will be skipped, if exception occurs");
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
}
Các câu lệnh trong phần try
sẽ được thực thi. Nếu tất cả các câu lệnh trong try
đều thành công, thì catch
bị bỏ qua và thực thi tiếp tục cho câu lệnh tiếp theo sau try-catch
. Tuy nhiên, nếu một trong các câu lệnh trong phần try
ném một ngoại lệ (trong trường hợp này là một IllegalArgumentException
), phần còn lại của phần try
sẽ được bỏ qua và phần thực thi sẽ được chuyển sang phần catch
. Chương trình luôn tiếp tục tuyên bố tiếp theo sau try-catch
(thay vì đột ngột chấm dứt).
A Test Driver Class for the Time Class (TestTime.java)
public class TestTime {
public static void main(String[] args) {
Time t1 = new Time(1, 2, 3);
System.out.println(t1);
// Time t2 = new Time(60, 59, 12);
try {
Time t3 = new Time(60, 59, 12);
System.out.println("This line will be skipped, if exception occurs");
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
}
System.out.println("Continue after exception!");
}
}
Nếu không đúng try-catch
, " Time t2
" sẽ đột ngột chấm dứt chương trình, nghĩa là phần còn lại của chương trình sẽ không được chạy (hãy thử bằng cách bỏ bình luận tuyên bố). Với việc try-catch
xử lý thích hợp , chương trình có thể tiếp tục hoạt động (nghĩa là xử lý ngoại lệ duyên dáng).
3.6 EG. 6: Class Point
Lớp Point
mô hình một điểm 2D tại (x,y)
, như được hiển thị trong sơ đồ lớp. Nó chứa các thành viên sau:
- 2
private
biến đối tượng x
và y
, duy trì vị trí của điểm.
- Constructor, getters và setters.
- Một phương thức
setXY()
, đặt x
và y
điểm; và một phương thức getXY()
, trả về x
và y
trong một int
mảng 2 phần tử .
- A
toString()
, trả về " (x,y)
".
- 3 phiên bản quá tải
distance()
:
distance(int x, int y)
trả về khoảng cách từ this
thể hiện đến điểm đã cho tại (x,y)
.
distance(Point another)
trả về khoảng cách từ this
thể hiện đến thể hiện đã cho Point
(được gọi another
).
distance()
trả về khoảng cách từ this
cá thể đến (0,0)
.
Class Point (Point.java)
public class Point {
private int x, y;
public Point() {
this.x = 0;
this.y = 0;
}
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return this.x;
}
public void setX (int x) {
this.x = x;
}
public int getY () {
return this.y;
}
public void setY (int y) {
this.y = y;
}
public String toString() {
return "(" + this.x + "," + this.y + ")";
}
public int[] getXY() {
int[] results = new int[2];
results[0] = this.x;
results[1] = this.y;
return results;
}
public void setXY(int x, int y) {
this.x = x;
this.y = y;
}
public double distance(int x, int y) {
int xDiff = this.x - x;
int yDiff = this.y - y;
return Math.sqrt(xDiff*xDiff + yDiff*yDiff);
}
public double distance(Point another) {
int xDiff = this.x - another.x;
int yDiff = this.y - another.y;
return Math.sqrt(xDiff*xDiff + yDiff*yDiff);
}
public double distance() {
return Math.sqrt(this.x*this.x + this.y*this.y);
}
}
A Test Driver (TestPoint.java)
public class TestPoint {
public static void main(String[] args) {
Point p1 = new Point(1, 2);
System.out.println(p1);
Point p2 = new Point();
System.out.println(p2);
p1.setX (3);
p1.setY (4);
System.out.println(p1);
System.out.println("X is: " + p1.getX());
System.out.println("Y is: " + p1.getY());
p1.setXY(5, 6);
System.out.println(p1);
System.out.println("X is: " + p1.getXY()[0]);
System.out.println("Y is: " + p1.getXY()[1]);
p2.setXY(10, 11);
System.out.printf("Distance is: %.2f%n", p1.distance(10, 11));
System.out.printf("Distance is: %.2f%n", p1.distance(p2));
System.out.printf("Distance is: %.2f%n", p2.distance(p1));
System.out.printf("Distance is: %.2f%n", p1.distance());
}
}
3.7 EG. 7: The Ball class
dss
Lớp Ball
mô hình một quả bóng chuyển động, được thiết kế như thể hiện trong sơ đồ lớp. Nó chứa các thành viên sau:
- 4
private
biến x
, y
, xStep
, yStep
, mà duy trì vị trí của bóng và sự dịch chuyển mỗi bước di chuyển.
- Constructor, getters và setters.
- Phương pháp
setXY()
và setXYStep()
, trong đó thiết lập vị trí và kích thước bước của quả bóng; và getXY()
và getXYSpeed()
.
- A
toString()
, trả về " Ball@(x,y),speed=(xStep,yStep)
".
- Một phương pháp
move()
, làm tăng x
và y
do xStep
và yStep
tương ứng; và trả về this
thể hiện để hỗ trợ hoạt động chuỗi.
The Ball Class (Ball.java)
public class Ball {
private double x, y, xStep, yStep;
public Ball(double x, double y, double xStep, double yStep) {
this.x = x;
this.y = y;
this.xStep = xStep;
this.yStep = yStep;
}
public double getX() {
return this.x;
}
public void setX(double x) {
this.x = x;
}
public double getY () {
return this.y;
}
public void setY(double y) {
this.y = y;
}
public double getXStep() {
return this.xStep;
}
public void setXStep(double xStep) {
this.xStep = xStep;
}
public double getYStep() {
return this.yStep;
}
public void setYStep(double yStep) {
this.yStep = yStep;
}
public String toString() {
return "Ball@(" + x + "," + y + "),speed=(" + xStep + "," + yStep + ")";
}
public double[] getXY() {
double[] results = new double[2];
results[0] = this.x;
results[1] = this.y;
return results;
}
public void setXY(double x, double y) {
this.x = x;
this.y = y;
}
public double[] getXYStep() {
double[] results = new double[2];
results[0] = this.xStep;
results[1] = this.yStep;
return results;
}
public void setXYStep(double xStep, double yStep) {
this.xStep = xStep;
this.yStep = yStep;
}
public Ball move() {
x += xStep;
y + = yStep;
return this;
}
}
A Test Driver (TestBall.java)
public class TestBall {
public static void main(String[] args) {
Ball b1 = new Ball(1, 2, 11, 12);
System.out.println(b1);
b1.setX (3);
b1.setY (4);
b1.setXStep(13);
b1.setYStep(14);
System.out.println(b1);
System.out.println("x is: " + b1.getX());
System.out.println("y is: " + b1.getY());
System.out.println("xStep is: " + b1.getXStep());
System.out.println("yStep is: " + b1.getYStep());
b1.setXY(5, 6);
b1.setXYStep(15, 16);
System.out.println(b1);
System.out.println("x is: " + b1.getXY()[0]);
System.out.println("y is: " + b1.getXY()[1]);
System.out.println("xStep is: " + b1.getXYStep()[0]);
System.out.println("yStep is: " + b1.getXYStep()[1]);
System.out.println(b1.move());
System.out.println(b1.move().move().move());
}
}
Hãy thử : Để hỗ trợ bóng nảy trong một ranh giới hình chữ nhật, hãy thêm một biến được gọi radius
, và các phương thức reflectHorizontal()
và reflectVertical()
.
3.8 EG. 8: Class Student
Giả sử rằng ứng dụng của chúng tôi yêu cầu chúng tôi làm mẫu cho sinh viên. Một sinh viên có tên và địa chỉ. Chúng tôi được yêu cầu theo dõi các khóa học của mỗi học sinh, cùng với điểm số (từ 0 đến 100) cho mỗi khóa học. Một sinh viên không được học quá 30 khóa cho toàn bộ chương trình. Chúng tôi được yêu cầu in tất cả các lớp khóa học, và cả lớp trung bình tổng thể.
Chúng ta có thể thiết kế Student
lớp như trong sơ đồ lớp. Nó chứa các thành viên sau:
private
các biến thể hiện name
( String
), address
( String
), numCourses
( int
), course
( String[30]
) và grades
( int[30]
). Theo numCourses
dõi số lượng các khóa học của sinh viên này cho đến nay. Các courses
và grades
hai mảng song song, lưu trữ các khóa học thực hiện (ví dụ {"IM101", "IM102", "IM103"}
) và lớp tương ứng của họ (ví dụ {89, 56, 98}
).
- Một constructor xây dựng một thể hiện với cho
name
và Address
. Nó cũng xây dựng các courses
và grades
các mảng và thiết lập numCourses
để 0.
- Getters cho
name
và address
; thiết lập cho address
. Không có setter nào được định nghĩa name
vì nó không được thiết kế để thay đổi.
- A
toString()
, in " name(address)
".
- Một phương thức
addCourseGrade(course, grade)
, nối thêm các phần đã cho course
và grade
vào courses
và grades
các mảng tương ứng; và gia tăng numCourses
.
- Một phương thức
printGrades()
, in " name course1:grade1, course2:grade2,...
".
- Một phương pháp
getAverageGrade()
, trả về điểm trung bình của tất cả các khóa học đã thực hiện.
The Student Class (Student.java)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
public class Student {
private String name;
private String address;
private String[] courses;
private int[] grades;
private int numCourses;
private static final int MAX_COURSES = 30;
public Student(String name, String address) {
this.name = name;
this.address = address;
courses = new String[MAX_COURSES];
grades = new int[MAX_COURSES];
numCourses = 0;
}
public String getName() {
return this.name;
}
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
public String toString() {
return name + "(" + address + ")";
}
public void addCourseGrade(String course, int grade) {
courses[numCourses] = course;
grades[numCourses] = grade;
++numCourses;
}
public void printGrades() {
System.out.print(name);
for (int i = 0; i < numCourses; ++i) {
System.out.print(" " + courses[i] + ":" + grades[i]);
}
System.out.println();
}
public double getAverageGrade() {
int sum = 0;
for (int i = 0; i < numCourses; ++i) {
sum += grades[i];
}
return (double)sum/numCourses;
}
}
|
Test Driver cho Student Class (TestStudent.java)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public class TestStudent {
public static void main(String[] args) {
Student ahTeck = new Student("Tan Ah Teck", "1 Happy Ave");
System.out.println(ahTeck);
ahTeck.setAddress("8 Kg Java");
System.out.println(ahTeck);
System.out.println(ahTeck.getName());
System.out.println(ahTeck.getAddress());
ahTeck.addCourseGrade("IM101", 89);
ahTeck.addCourseGrade("IM102", 57);
ahTeck.addCourseGrade("IM103", 96);
ahTeck.printGrades();
System.out.printf("The average grade is %.2f%n", ahTeck.getAverageGrade());
}
}
|
Kết quả đầu ra mong muốn:
Tan Ah Teck(1 Happy Ave)
Tan Ah Teck (8 Kg Java)
Tan Ah Teck
8 Kg Java
Tan Ah Teck IM101:89 IM102:57 IM103:96
The average grade is 80.67
Lưu ý : Chúng tôi đã sử dụng mảng Trong ví dụ này, có một số hạn chế. Mảng cần được phân bổ trước với độ dài cố định. Hơn nữa, chúng ta cần hai mảng song song để theo dõi hai thực thể. Có các cấu trúc dữ liệu nâng cao có thể thể hiện các dữ liệu này tốt hơn và hiệu quả hơn.
Đăng nhận xét