1. Thừa kế
Để làm việc với công cụ trò chơi CodeGym, bạn sẽ cần sử dụng tính kế thừa . Nhưng nếu bạn không biết đó là gì thì sao? Một mặt, bạn cần phải hiểu và nghiên cứu chủ đề này. Mặt khác, động cơ được thiết kế đặc biệt rất đơn giản, vì vậy bạn có thể làm được với kiến thức hời hợt về thừa kế.
Vậy thừa kế là gì? Nói một cách đơn giản, thừa kế là mối quan hệ giữa hai lớp. Một trong số chúng đóng vai trò là lớp cha và lớp còn lại trở thành lớp con (hậu duệ). Hơn nữa, một lớp cha thậm chí có thể không biết rằng nó có các lớp con. Nói cách khác, lớp cha không nhận được nhiều lợi ích từ việc có các lớp con.
Nhưng tính kế thừa mang lại nhiều lợi thế cho lớp con. Điều quan trọng nhất trong số đó là tất cả các biến và phương thức của lớp cha đều xuất hiện trong lớp con, như thể mã của lớp cha được sao chép trực tiếp vào lớp con. Điều này không hoàn toàn chính xác, nhưng nó sẽ đủ để hiểu cơ bản về thừa kế.
Dưới đây là một số ví dụ để giúp bạn hiểu rõ hơn về thừa kế.
Ví dụ 1 — đây là ví dụ đơn giản nhất
|
Lớp Child kế thừa Parent lớp với sự trợ giúp của extends từ khóa. |
|
Ví dụ 2 — sử dụng các biến của lớp cha
|
Lớp Child có thể sử dụng các trường age và name của lớp Parent như thể chúng được khai báo trong Child chính lớp đó. |
|
Ví dụ 3 — sử dụng các phương thức của lớp cha
|
Lớp Child có thể sử dụng các biến và phương thức của lớp Cha như thể chúng đã được khai báo trong Child lớp. Trong ví dụ này, chúng tôi sử dụng getName() phương pháp. |
|
Bỏ qua một số chi tiết, chúng ta có thể nói rằng từ quan điểm của trình biên dịch Java, chúng ta chỉ cần sao chép mã của lớp cha vào mã của lớp con:
public class Child extends Parent
{
public int age; // An inherited variable
public String name; // An inherited variable
public getName() { // An inherited method
return name;
}
public void printInfo()
{
System.out.println(getName() + " " + age);
}
}
Child
lớp xuất hiện từ quan điểm của trình biên dịch
2. Ghi đè phương thức
Đôi khi có những tình huống chúng ta làm cho Child
lớp của chúng ta kế thừa một lớp rất hữu ích Parent
, khiến lớp con kế thừa tất cả các biến và phương thức của lớp cha. Nhưng một số phương pháp đó có thể không hoạt động hoàn toàn theo cách chúng ta muốn hoặc hoàn toàn không hoạt động theo cách chúng ta muốn.
Bạn làm gì trong trường hợp này? Chúng ta có thể ghi đè lên một phương thức mà chúng ta không thích cách triển khai của nó . Đây là một điều đơn giản để làm: trong Child
lớp của chúng ta, chúng ta chỉ cần khai báo một phương thức có cùng chữ ký với phương thức trong lớp Parent
và sau đó viết mã của riêng chúng ta vào đó.
Ví dụ 1 — ghi đè phương thức
|
Phương printInfo() thức sẽ hiển thị cụm từ sau:
|
|
Đơn giản hóa tình huống một chút, tính kế thừa khiến mã của lớp cha được sao chép vào lớp con. Nhưng nếu một lớp hậu duệ đã là một phương thức tồn tại trong lớp tổ tiên, thì phương thức đó không được sao chép từ lớp tổ tiên. Ở đây chúng ta nói rằng phương thức trong lớp con sẽ ghi đè phương thức trong lớp cha. Nhìn vào ví dụ dưới đây. Có lẽ nó sẽ giúp mọi thứ rõ ràng hơn một chút:
Đây là cách lớp Con xuất hiện theo quan điểm của trình biên dịch: |
---|
|
Ví dụ 2 - một phép thuật kế thừa nhỏ (và ghi đè phương thức)
public class Parent
{
public getName() {
return "Luke";
}
public void printInfo()
{
System.out.println( getName() );
}
}
public class Child extends Parent
{
public getName() {
return "Luke, I am your father";
}
}
Nếu printInfo()
phương thức được gọi trên một Parent
kiểu, nó sẽ gọi getName()
phương thức của Parent
lớp.
Nếu printInfo()
phương thức được gọi trên một Child
đối tượng, nó sẽ gọi getName()
phương thức của Child
lớp.
Nói cách khác, printInfo()
phương thức chỉ được khai báo trong Parent
lớp, nhưng nó gọi getName()
phương thức của Child
lớp nếu printInfo()
phương thức đó được gọi trên một Child
đối tượng.
Ví dụ:
|
Mã này hiển thị văn bản sau trên màn hình:
|
|
Mã này hiển thị văn bản sau trên màn hình:
|
Và tất cả bởi vì theo quan điểm của trình biên dịch (một phiên bản rất đơn giản của nó), mã của lớp Child
trông như thế này:
public class Child extends Parent
{
public getName() {
return "Luke, I am your father";
}
public void printInfo()
{
System.out.println(getName());
}
}
Child
lớp xuất hiện từ quan điểm của trình biên dịch
3. Danh sách
Dưới đây là lời nhắc ngắn gọn về danh sách ( List
). Danh sách có nhiều điểm chung với mảng:
- Họ có thể lưu trữ rất nhiều dữ liệu của một loại cụ thể.
- Họ cho phép bạn lấy các phần tử theo chỉ mục của họ.
- Các chỉ số của các phần tử bắt đầu từ
0
.
Ưu điểm của danh sách:
Không giống như mảng, danh sách có thể tự động thay đổi kích thước. Ngay sau khi tạo, kích thước của danh sách là 0
. Khi các mục được thêm vào danh sách, kích thước của nó sẽ tăng lên. Ví dụ tạo danh sách:
ArrayList<String> myList = new ArrayList<String>();
ArrayList
Giá trị được chỉ ra trong dấu ngoặc nhọn là kiểu dữ liệu mà danh sách có thể lưu trữ.
Dưới đây là một số phương pháp để làm việc với một danh sách:
Mã số | Mô tả ngắn gọn |
---|---|
|
Tạo một danh sách chuỗi mới |
|
Thêm một phần tử vào cuối danh sách |
|
Thêm phần tử vào đầu danh sách |
|
Lấy một phần tử theo chỉ mục của nó |
|
Thay đổi một phần tử theo chỉ mục của nó |
|
Lấy số phần tử trong danh sách |
|
Xóa một phần tử khỏi danh sách |
Để biết thêm thông tin về danh sách, bạn có thể đọc các bài viết sau:
4. Số ngẫu nhiên
Công cụ trò chơi CodeGym có hai phương pháp có thể được sử dụng để tạo số ngẫu nhiên. Những phương pháp này là:
int getRandomNumber(int max)
int getRandomNumber(int min, int max)
Phương thức đầu tiên — getRandomNumber(int max)
— trả về một số ngẫu nhiên trong phạm vi 0
, 1
, 2
, ... max-1
. Về cơ bản, nó sử dụng Random
lớp từ java.util
gói, nhưng điều đó không thay đổi cách bạn sử dụng một số ngẫu nhiên.
getRandomNumber(int)
chấp nhận một số nguyên làm đối số. Số này sẽ là giới hạn trên của các số mà trình tạo số ngẫu nhiên có thể trả về. Giới hạn dưới là 0. Chú ý! Trình tạo số ngẫu nhiên sẽ KHÔNG BAO GIỜ trả về giá trị của giới hạn trên. Ví dụ: nếu bạn gọi getRandomNumber(3)
, nó sẽ trả về ngẫu nhiên 0, 1 hoặc 2. Như bạn có thể thấy, nó sẽ không trả về 3. Sử dụng trình tạo số ngẫu nhiên theo cách này khá đơn giản nhưng phù hợp với nhiều trường hợp.
Phương thức thứ hai — getRandomNumber(int min, int max)
— trả về một số nguyên ngẫu nhiên trong phạm vi [min, max-1]
. Nó sẽ không bao giờ trả về một số nhỏ hơn min
và nó sẽ không bao giờ trả về một số lớn hơn max-1
.
Làm thế nào những phương pháp này có thể được sử dụng trong thực tế?
1. Xúc xắc
Giả sử bạn muốn mô phỏng việc tung một con súc sắc và lấy một số ngẫu nhiên trong phạm vi 1-6
. Bạn sẽ làm điều này như thế nào? Điều này có thể được thực hiện với mã như thế này:
int dice = getRandomNumber(1, 7);
Phương thức này sẽ trả về một số nguyên ngẫu nhiên trong phạm vi 1-6
.
2. Mục tiêu thực hành
Giả sử bạn muốn mô phỏng việc bắn vào một mục tiêu và độ chính xác của một phát bắn bao gồm một thành phần ngẫu nhiên thay đổi trong phạm vi từ -10
bao +10
gồm. Điều này có thể được thực hiện với mã như thế này:
int dx = getRandomNumber(-10, 11);
Phương thức này sẽ trả về một số nguyên ngẫu nhiên trong phạm vi -10
tới +10
.
Có nhiều cách để sử dụng số ngẫu nhiên trong trò chơi. Bạn chỉ bị giới hạn bởi trí tưởng tượng của bạn. Viết trò chơi của riêng bạn, tinh chỉnh chúng và tận hưởng quá trình.
Mọi người đều có thể chơi game, nhưng chỉ lập trình viên mới có thể tạo ra chúng.
GO TO FULL VERSION