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

public class Parent
{
}
Lớp Childkế thừa Parentlớp với sự trợ giúp của extendstừ khóa.
public class Child extends Parent
{
}

Ví dụ 2 — sử dụng các biến của lớp cha

public class Parent
{
  public int age;
  public String name;
}
Lớp Childcó thể sử dụng các trường agenamecủa lớp Parentnhư thể chúng được khai báo trong Childchính lớp đó.
public class Child extends Parent
{
  public void printInfo()
  {
    System.out.println(name + " " + age);
  }
}

Ví dụ 3 — sử dụng các phương thức của lớp cha

public class Parent
{
   public int age;
   public String name;
   public getName() {
      return name;
   }
}
Lớp Childcó 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 Childlớp. Trong ví dụ này, chúng tôi sử dụng getName()phương pháp.
public class Child extends Parent
{
   public void printInfo()
   {
      System.out.println(getName() + " " + age);
   }
}

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);
   }
}
Đây là cách Childlớ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 Childlớ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 Childlớ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 Parentvà sau đó viết mã của riêng chúng ta vào đó.

Ví dụ 1 — ghi đè phương thức

public class Parent
{
   public String name;
   public void setName(String nameNew) {
      name = nameNew;
   }

   public getName() {
      return name;
   }
}
Phương printInfo()thức sẽ hiển thị cụm từ sau:
Luke, No!!!
public class Child extends Parent
{
   public void setName(String nameNew) {
      name = nameNew + ", No!!!";
   }

   public void printInfo()
   {
      setName("Luke");
      System.out.println(getName());
   }
}

Đơ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:
public class Child extends Parent
{
   public String name;    // An inherited variable

   public void setName(String nameNew)  // The overridden method replaces the inherited one
   {
      name = nameNew + ", No!!!";
   }

   public getName()    // An inherited method
   {
      return name;
   }

   public void printInfo()
   {
      setName("Luke");
      System.out.println(getName());
   }
}

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 Parentkiểu, nó sẽ gọi getName()phương thức của Parentlớ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 Childlớp.

Nói cách khác, printInfo()phương thức chỉ được khai báo trong Parentlớp, nhưng nó gọi getName()phương thức của Childlớp nếu printInfo()phương thức đó được gọi trên một Childđối tượng.

Ví dụ:

Parent parent = new Parent();
parent.printnInfo();
Mã này hiển thị văn bản sau trên màn hình:
Luke
Child child = new Child();
child.printnInfo();
Mã này hiển thị văn bản sau trên màn hình:
Luke, I am your father

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 Childtrô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());
   }
}
Đây là cách Childlớ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>();
Tạo mớiArrayList

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
ArrayList<String> list = new ArrayList<String>();
Tạo một danh sách chuỗi mới
list.add("name");
Thêm một phần tử vào cuối danh sách
list.add(0, "name");
Thêm phần tử vào đầu danh sách
String name = list.get(5);
Lấy một phần tử theo chỉ mục của nó
list.set(5, "new name");
Thay đổi một phần tử theo chỉ mục của nó
int count = list.size();
Lấy số phần tử trong danh sách
list.remove(4);
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 Randomlớp từ java.utilgó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 minvà 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ừ -10bao +10gồ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 -10tớ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.