<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tiểu Share</title>
    <description>The latest articles on DEV Community by Tiểu Share (@tieushare).</description>
    <link>https://dev.to/tieushare</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4157840%2Fcf2f82ef-3a87-408f-86bb-07ac00db694a.png</url>
      <title>DEV Community: Tiểu Share</title>
      <link>https://dev.to/tieushare</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tieushare"/>
    <language>en</language>
    <item>
      <title>Từ Khóa final trong Java | Cách sử dụng và ví dụ</title>
      <dc:creator>Tiểu Share</dc:creator>
      <pubDate>Fri, 13 Nov 2026 05:17:41 +0000</pubDate>
      <link>https://dev.to/tieushare/tu-khoa-final-trong-java-cach-su-dung-va-vi-du-3bl3</link>
      <guid>https://dev.to/tieushare/tu-khoa-final-trong-java-cach-su-dung-va-vi-du-3bl3</guid>
      <description>&lt;p&gt;&amp;nbsp;&lt;span&gt;"Trong Java, &lt;/span&gt;&lt;b&gt;&lt;a href="https://www.tieushare.com/2026/10/tu-khoa-final-trong-java.html" rel="noopener noreferrer"&gt;từ khóa final&lt;/a&gt;&lt;/b&gt;&lt;span&gt; là một công cụ mạnh mẽ để đảm bảo tính bất biến và an toàn trong lập trình. Nó được sử dụng để hạn chế việc thay đổi giá trị, ghi đè phương thức, hoặc kế thừa lớp, từ đó tăng tính ổn định và rõ ràng cho mã nguồn".&lt;/span&gt;&lt;/p&gt;
&lt;span id="docs-internal-guid-cff0a18d-7fff-3a6d-dde2-4a7746bd6285"&gt;&lt;/span&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Từ khóa final có thể được áp dụng trong các ngữ cảnh sau:&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;↳ Biến final (hằng số)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Phương thức final&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Lớp final&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Ngoài ra, một biến final có thể là:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Biến final rỗng: &lt;/span&gt;&lt;span&gt;Là biến final chưa được khởi tạo ngay từ đầu. Loại biến này có thể được khởi tạo duy nhất một lần trong constructor.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Biến final static: &lt;/span&gt;&lt;span&gt;Được khởi tạo trong khối static duy nhất, đảm bảo tính bất biến toàn cục.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Sử dụng từ khóa final giúp chương trình trở nên rõ ràng và dễ bảo trì hơn. Chúng ta sẽ tìm hiểu chi tiết về từng ngữ cảnh sử dụng từ khóa final ở phần bên dưới.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqeOGrzq1RJG3ToUOGABToKh4Z7TCniUC7uzyHvR8Pry_SZGE5ZWX3qebSn4dBGfhN-D2VRVzzVzUVXbREH4FtbJQIr88C_0PFoqkNtEY8SCl1OiKOENHoXFnUfTBhsX_WSQs7PVpo9nnK_0mhuhez4VY-ItlpHvSyA8fnZB0du8OKCKNUxiY4oCwZdkE/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả các ngữ cảnh của từ khóa final." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEgqeOGrzq1RJG3ToUOGABToKh4Z7TCniUC7uzyHvR8Pry_SZGE5ZWX3qebSn4dBGfhN-D2VRVzzVzUVXbREH4FtbJQIr88C_0PFoqkNtEY8SCl1OiKOENHoXFnUfTBhsX_WSQs7PVpo9nnK_0mhuhez4VY-ItlpHvSyA8fnZB0du8OKCKNUxiY4oCwZdkE%2Fw640-h360%2Fimage.png" title="Ảnh mô tả các ngữ cảnh của từ khóa final." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span&gt;Ảnh mô tả các ngữ cảnh của từ khóa final.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅰ. Biến final (Biến hằng)&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Khi khai báo một biến với từ khóa final, giá trị của biến đó không thể thay đổi sau khi được khởi tạo. Biến này được gọi là hằng số.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Việc sử dụng biến final giúp tăng cường tính bảo mật cho chương trình, vì nó ngăn chặn việc vô tình thay đổi giá trị của các biến quan trọng.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Biến final cũng có thể cải thiện hiệu suất chương trình, vì trình biên dịch Java có thể tối ưu hóa code tốt hơn cho các biến không thay đổi.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Cú pháp để khai báo biến final như sau:&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;b&gt;Cú Pháp&lt;/b&gt;
&lt;pre&gt;&lt;code&gt;final   = giá_trị_ban_đầu;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;&lt;b&gt;Dưới đây là giải thích chi tiết về cú pháp khai báo này:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &amp;lt;kiểu_dữ_liệu&amp;gt;: &lt;/span&gt;&lt;span&gt;là kiểu dữ liệu của biến, ví dụ như int, double, String, ...&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &amp;lt;tên_biến&amp;gt;: &lt;/span&gt;&lt;span&gt;là tên của biến.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &amp;lt;giá_trị_ban_đầu&amp;gt;: &lt;/span&gt;&lt;span&gt;là giá trị khởi tạo ban đầu của biến (không bắt buộc). Nếu có, bạn chỉ có thể gán giá trị này một lần và không thể thay đổi sau đó.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Book.java&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class Book {
    // Khai báo các trường final
    final int MAX_SIZE = 100;// Độ dài tối đa
    final double PI = 3.14159;// Giá trị PI
    final String APP_NAME = "MyApp";// Tên ứng dụng

    // Phương thức để thay đổi các giá trị final (lỗi sẽ xảy ra vì không thể gán lại giá trị cho final)
    public void ChangeName(int MAX_SIZE, double PI, String APP_NAME) {
        this.MAX_SIZE = MAX_SIZE; // Lỗi: Không thể gán lại giá trị cho một biến final
        this.PI = PI;// Lỗi: Không thể gán lại giá trị cho một biến final
        this.APP_NAME = APP_NAME;// Lỗi: Không thể gán lại giá trị cho một biến final
    }

    public static void main(String[] args) {
        Book book = new Book();
        book.setTitle(200, 3.14, "APP"); // Gọi phương thức setTitle với các giá trị mới
    }
} &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Exception in thread "main" java.lang.Error: Unresolved compilation problem: The method setTitle(int, double, String) is undefined for the type Book at Book.main(Book.java:16)&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;Biến final trống&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Biến final trống, hay còn gọi là biến final không khởi tạo (blank final variable), là một biến final mà không có giá trị ban đầu được gán cho nó khi khai báo. Trong Java, bạn có thể khai báo biến final trống và sau đó chỉ có thể gán giá trị cho nó trong constructor của lớp hoặc trong khối static (nếu là biến static).&lt;/span&gt;&lt;/p&gt;

&lt;b&gt;MyClass.java&lt;/b&gt;
&lt;pre&gt;&lt;code&gt; class MyClass {
    final int MAX_SIZE;
    final double PI;

    public MyClass(int MAX_SIZE, double PI) {
        this.MAX_SIZE = MAX_SIZE;// Gán giá trị trong constructor
        this.PI = PI;// Gán giá trị trong constructor
    }

    // static {
    //     PI = 3.14159;// Gán giá trị trong khối static
    // }

    public static void main(String[] args) {
        MyClass obj = new MyClass(100, 3.14);
        System.out.println("Kích thước tối đa: " + obj.MAX_SIZE);
        System.out.println("PI= " + obj.PI);
    }
} &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Kích thước tối đa: 100
PI= 3.14&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;Lưu ý rằng sau khi một biến final trống được gán giá trị trong constructor hoặc khối static, bạn không thể thay đổi giá trị của nó.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Biến final static&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Biến final static trong Java là biến hằng được khai báo với từ khóa final và static.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Biến final static là biến có giá trị không thay đổi và thuộc về lớp (class) chứ không phải đối tượng (instance) của lớp đó.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Biến final static được khởi tạo trong khối static (static block) của lớp.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Biến final static giúp bạn chia sẻ các hằng số được sử dụng nhiều lần trong toàn bộ chương trình.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Cú pháp để khai báo biến final static như sau:&lt;/span&gt;&lt;/h3&gt;

&lt;b&gt;Cú Pháp&lt;/b&gt;
&lt;pre&gt;&lt;code&gt;final static   = ;
final static  ;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;MyClass.java&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class MyClass {
    final static int MAX_SIZE = 100;
    final static double PI;

    static {
        PI = 3.14159;// Gán giá trị trong khối static
    }

    public static void main(String[] args) {
        MyClass obj = new MyClass();
        System.out.println("Kích thước tối đa: " + obj.MAX_SIZE);
        System.out.println("PI= " + MyClass.PI);
    }
} &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Kích thước tối đa: 100
PI= 3.14 &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;&lt;b&gt;Điều quan trọng cần lưu ý là:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Hằng số MAX_SIZE và PI là final, do đó không thể thay đổi giá trị của chúng sau khi đã được gán giá trị ban đầu.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;MAX_SIZE được truy cập thông qua một đối tượng của lớp MyClass, trong khi PI có thể được truy cập trực tiếp thông qua lớp MyClass vì nó là biến static.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Khi bạn khai báo một tham số là final, bạn không thể thay đổi giá trị của nó sau khi đã được khởi tạo. Điều này áp dụng cho các biến cục bộ, tham số của phương thức và các thuộc tính của lớp. Việc sử dụng từ khóa final đảm bảo rằng giá trị của biến sẽ không bị thay đổi, tạo ra sự an toàn và nhất quán trong mã nguồn.&lt;/span&gt;&lt;/p&gt;

&lt;b&gt;Example.java&lt;/b&gt;
&lt;pre&gt;&lt;code&gt;public class Example {
    public void printMessage(final String message) {
        message = "New Message"; // Lỗi: không thể gán giá trị mới cho biến final
        System.out.println(message);
        final int number = 10;
        number = 20; // Lỗi: không thể gán giá trị mới cho biến final
        System.out.println(number);
    }

    public static void main(String[] args) {
        Example example = new Example();
        example.printMessage("Hello, World!");
    }
} &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Exception in thread "main" java.lang.Error: Unresolved compilation problems: The final local variable message cannot be assigned. It must be blank and not using a compound assignment The final local variable number cannot be assigned. It must be blank and not using a compound assignment at Example.printMessage(Example.java:3) at Example.main(Example.java:12) &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;Trong tất cả các ví dụ trên, biến final không thể thay đổi giá trị sau khi đã được khởi tạo. Điều này giúp ngăn chặn các lỗi không mong muốn và tạo ra mã nguồn dễ bảo trì hơn.&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅱ. Phương thức final&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Khi một phương thức được khai báo là final, nó không thể bị ghi đè bởi bất kỳ phương thức nào trong lớp con. Điều này đảm bảo rằng hành vi của phương thức không thể bị thay đổi khi lớp được kế thừa. Trình biên dịch và máy ảo Java (JVM) có thể thực hiện tối ưu hóa hiệu suất cho các phương thức final vì biết rằng các phương thức này không thể bị ghi đè.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Cú pháp khai báo phương thức final:&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;

&lt;b&gt;Cú Pháp&lt;/b&gt;
&lt;pre&gt;&lt;code&gt;final  () {
    // thân phương thức
} &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;Example.java&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Parent {
    final void show() {
        System.out.println("Đây là phương thức final.");
    }
}

class Child extends Parent {
    //Không thể ghi đè phương thức show() của lớp Parent
    @Override
    void show() {
        System.out.println("Đang cố gắng ghi đè");
    }
}

public class Example {
    public static void main(String[] args) {
        Child obj = new Child();
        obj.show(); // Gọi phương thức từ lớp Parent
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Exception in thread "main" java.lang.IncompatibleClassChangeError: class Child overrides final method Parent.show() &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;Việc sử dụng phương thức final thường được áp dụng khi bạn muốn đảm bảo rằng một phương thức cụ thể không bị thay đổi hành vi bởi các lớp con. Điều này có thể hữu ích trong các tình huống mà việc thay đổi hành vi của phương thức có thể gây ra lỗi hoặc ảnh hưởng đến tính toàn vẹn của lớp.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Kế thừa phương thức final&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Từ khóa final có thể được kế thừa nhưng không thể bị ghi đè (override) bởi lớp con. Điều này có nghĩa là bạn có thể sử dụng phương thức final trong các lớp con, nhưng không thể thay đổi cách thức hoạt động của nó trong lớp con.&lt;/span&gt;&lt;/p&gt;

&lt;b&gt;Example.java&lt;/b&gt;
&lt;pre&gt;&lt;code&gt;// Lớp cha (ParentClass)
class ParentClass {
    // Phương thức final
    public final void displayMessage() {
        System.out.println("Đây là phương thức final từ ParentClass đuược gọi từ Lớp con (ChildClass).");
    }
}

// Lớp con (ChildClass) kế thừa từ ParentClass
class ChildClass extends ParentClass {
    // Cố gắng ghi đè phương thức final sẽ gây lỗi biên dịch
    /*
    @Override
    public void displayMessage() {
        System.out.println("Đang cố gắng ghi đè phương thức final trong ChildClass.");
    }
    */
    
}

public class Example {
    public static void main(String[] args) {
        
        // tạo đối tượng từ lớp ChildClass
        ChildClass child = new ChildClass();
        child.displayMessage(); // Gọi phương thức final được kế thừa từ ParentClass
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Đây là phương thức final từ ParentClass đuược gọi từ Lớp con (ChildClass).&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;Tóm lại, phương thức final có thể được kế thừa nhưng không thể bị ghi đè, đảm bảo rằng hành vi của phương thức không thể bị thay đổi bởi các lớp con, giúp bảo vệ tính toàn vẹn của phương thức và đảm bảo rằng các lớp con không thể làm sai lệch hành vi đã được xác định trong lớp cha. Điều này rất quan trọng khi bạn muốn bảo vệ một phần cụ thể của mã nguồn khỏi bị thay đổi không mong muốn trong quá trình kế thừa.&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅳ. Lớp final&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Khi một lớp được khai báo với &lt;a href="https://www.tieushare.com/2026/10/tu-khoa-final-trong-java.html" rel="noopener noreferrer"&gt;từ khóa final&lt;/a&gt;, nghĩa là lớp đó không thể bị kế thừa bởi bất kỳ lớp nào khác. Việc sử dụng lớp final thường nhằm mục đích bảo vệ cấu trúc và hành vi của lớp, đảm bảo rằng không ai có thể mở rộng và thay đổi chúng.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Cú pháp khai báo lớp final:&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;

&lt;b&gt;Cú Pháp&lt;/b&gt;
&lt;pre&gt;&lt;code&gt; final class  {
    // các thành phần của lớp
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;Example.java&lt;/b&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Lớp Parent được khai báo là final, nghĩa là không thể kế thừa lớp này&lt;br&gt;
public final class Parent {&lt;br&gt;
    // Phương thức show() của lớp Parent&lt;br&gt;
    void show() {

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// Lớp Child cố gắng kế thừa từ lớp Parent, nhưng sẽ gây lỗi biên dịch vì lớp Parent là final&lt;br&gt;
public class Child extends Parent {&lt;br&gt;
    // Phương thức show() của lớp Child cố gắng ghi đè phương thức show() của lớp Parent&lt;br&gt;
    void show() {&lt;br&gt;
        System.out.println("Đang cố gắng kế thừa");&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;// Lớp Example chứa phương thức main để chạy chương trình&lt;br&gt;&lt;br&gt;
public class Example {&lt;br&gt;&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;&lt;br&gt;
        // Tạo một đối tượng của lớp Child&lt;br&gt;&lt;br&gt;
        Child obj = new Child();&lt;br&gt;&lt;br&gt;
        // Gọi phương thức show() từ đối tượng obj&lt;br&gt;&lt;br&gt;
        obj.show(); // Gọi phương thức từ lớp Parent&lt;br&gt;&lt;br&gt;
    }&lt;br&gt;&lt;br&gt;
} &lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Exception in thread "main" java.lang.Error: Unresolved compilation problems: The public type Parent must be defined in its own file The public type Child must be defined in its own file The type Child cannot subclass the final class Parent&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Lớp final thường được sử dụng trong các tình huống sau:&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Lớp cung cấp các phương thức tiện ích, chẳng hạn như các lớp trong thư viện Java như java.lang.Math hoặc java.lang.String.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Lớp đại diện cho các khái niệm mà việc kế thừa không có ý nghĩa, chẳng hạn như các lớp đại diện cho hằng số hoặc các dịch vụ không thay đổi.&lt;/span&gt;&lt;/p&gt;
&lt;span&gt;&lt;br&gt;&lt;/span&gt;

</description>
      <category>từkhóafinaltrongjava</category>
      <category>finalclassjava</category>
      <category>finaltrongjavalàgì</category>
      <category>tieushare</category>
    </item>
    <item>
      <title>Gói (Packages) trong Java | Cách tạo và sử dụng</title>
      <dc:creator>Tiểu Share</dc:creator>
      <pubDate>Thu, 12 Nov 2026 03:16:26 +0000</pubDate>
      <link>https://dev.to/tieushare/goi-packages-trong-java-cach-tao-va-su-dung-4fg7</link>
      <guid>https://dev.to/tieushare/goi-packages-trong-java-cach-tao-va-su-dung-4fg7</guid>
      <description>&lt;p&gt;&lt;span id="docs-internal-guid-83cd2ad7-7fff-3dbb-533d-ea5d00f8bab6"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;"Trong Java, &lt;a href="https://www.tieushare.com/2026/10/goi-packages-trong-java.html" rel="noopener noreferrer"&gt;&lt;b&gt;gói (package)&lt;/b&gt;&lt;/a&gt; là một cách tổ chức các lớp và giao diện liên quan thành một nhóm logic. Điều này giúp quản lý mã nguồn dễ dàng hơn, tránh xung đột tên, và hỗ trợ tái sử dụng mã một cách hiệu quả. Dưới đây là những điều cơ bản bạn cần biết về gói trong Java."&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅰ. Gói (Packages) là gì?&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Một gói (packages) trong java là một nhóm các "kiểu dữ liệu" có liên quan với nhau, cung cấp tính bảo mật truy cập và quản lý không gian tên. Lưu ý rằng "kiểu dữ liệu" ở đây đề cập đến các lớp (class), giao diện (interface), kiểu liệt kê (enumeration) và kiểu chú thích (annotation type). Kiểu liệt kê và kiểu chú thích là những dạng đặc biệt của lớp và giao diện, vì vậy "kiểu dữ liệu" trong bài học này thường được gọi đơn giản là lớp và giao diện.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Trong Java, gói (package) có thể được phân loại theo hai hình thức chính:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;↳ Gói được dựng sẵn (Built-in Packages)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Gói do người dùng định nghĩa (User-defined Packages)&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiUTSiUsV49MbM0LeCl8mdvD4DII9QUW9AK80AcSdyTQejrU3p6kRZ-B-1jTxpvjwsRQtVEOR6Z98v1pdKDNCfK7JX_Pqk9L1cEIPGCD-p2ISaCysYEK0EB2pe-nKcwq3E7354Lr31E1v7eRaWKf2ygthCW25BLb_mAxlRsPvcZgxYHOtn4W3SsoquovE/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả các loại package trong Java." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEiiUTSiUsV49MbM0LeCl8mdvD4DII9QUW9AK80AcSdyTQejrU3p6kRZ-B-1jTxpvjwsRQtVEOR6Z98v1pdKDNCfK7JX_Pqk9L1cEIPGCD-p2ISaCysYEK0EB2pe-nKcwq3E7354Lr31E1v7eRaWKf2ygthCW25BLb_mAxlRsPvcZgxYHOtn4W3SsoquovE%2Fw640-h360%2Fimage.png" title="Ảnh mô tả các loại package trong Java." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span&gt;Ảnh mô tả các loại package trong Java.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅱ. &lt;a href="https://www.tieushare.com/2026/10/goi-packages-trong-java.html" rel="noopener noreferrer"&gt;Gói được dựng sẵn (Built-in Packages)&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Các gói được dựng sẵn là các gói được cung cấp sẵn bởi Java API (Application Programming Interface). Chúng bao gồm rất nhiều lớp và giao diện mà bạn có thể sử dụng để phát triển ứng dụng của mình mà không cần phải tự viết lại từ đầu. Không có con số chính xác cho số lượng Gói Được Dựng Sẵn (Built-in Packages) trong Java vì nó liên tục được cập nhật và phát triển. Tuy nhiên, dựa trên tài liệu tham khảo, khảo sát cộng đồng và kinh nghiệm thực tế, ta có thể liệt kê một số gói phổ biến sau:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;1. Gói cơ bản (java.lang):&lt;/span&gt;&lt;span&gt; Chứa các lớp cốt lõi như Object, String, Math, System, v.v., cung cấp các chức năng cơ bản như thao tác chuỗi, số học, nhập/xuất dữ liệu, v.v.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;2. Gói thu thập (java.util):&lt;/span&gt;&lt;span&gt; Cung cấp các cấu trúc dữ liệu và thuật toán hữu ích như danh sách, tập hợp, bản đồ, v.v., giúp quản lý và xử lý dữ liệu hiệu quả.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;3. Gói I/O (java.io):&lt;/span&gt;&lt;span&gt; Cung cấp các lớp để đọc và ghi dữ liệu từ các nguồn khác nhau như tệp tin, bàn phím, mạng, v.v.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;4. Gói thời gian (java.time):&lt;/span&gt;&lt;span&gt; Gói java.time chứa các lớp để làm việc với ngày và giờ, được giới thiệu từ Java 8.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;5. Gói SQL (java.sql):&lt;/span&gt;&lt;span&gt; Cung cấp các lớp để kết nối và thao tác với cơ sở dữ liệu SQL.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;6. Gói giao diện (javax.swing):&lt;/span&gt;&lt;span&gt; Gói javax.swing chứa các lớp để xây dựng giao diện người dùng (GUI)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;7. Gói mạng (java.net):&lt;/span&gt;&lt;span&gt; Cung cấp các lớp để lập trình mạng như kết nối socket, giao thức HTTP, FTP, v.v.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;8. Gói xử lý ngoại lệ (java.lang.Exception):&lt;/span&gt;&lt;span&gt; Cung cấp các lớp để xử lý các lỗi và ngoại lệ trong chương trình.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;9. Gói đồng thời (java.util.concurrent):&lt;/span&gt;&lt;span&gt; Cung cấp các lớp và giao diện để lập trình đa luồng và đồng thời trong Java.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;10. Gói bảo mật (java.security):&lt;/span&gt;&lt;span&gt; Cung cấp các lớp cho các tính năng bảo mật như mã hóa, xác thực, quản lý khóa, v.v.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;11. Gói chú thích (java.lang.annotation):&lt;/span&gt;&lt;span&gt; Cung cấp các lớp để tạo và sử dụng chú thích trong Java.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Ngoài ra, một số gói khác cũng có thể được sử dụng phổ biến tùy theo lĩnh vực ứng dụng cụ thể, ví dụ:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Gói xử lý ảnh (javax.imageio)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Gói xử lý XML (javax.xml)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Gói dịch vụ web (javax.ws)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Gói GUI (javafx, Swing)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Lưu ý: &lt;/span&gt;&lt;span&gt;Mức độ phổ biến của các gói có thể thay đổi theo thời gian và giữa các dự án khác nhau. Việc sử dụng các gói phụ thuộc vào nhu cầu cụ thể của từng ứng dụng. Nên tham khảo tài liệu và hướng dẫn sử dụng cho từng gói để sử dụng hiệu quả.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Bên cạnh danh sách trên, bạn có thể tham khảo thêm trang web chính thức của Oracle để tìm hiểu về các Gói Được Dựng Sẵn (Built-in Packages) trong Java: &lt;/span&gt;&lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/allpackages-index.html" rel="noopener noreferrer"&gt;&lt;span&gt;&lt;b&gt;Tại đây&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅲ. &lt;a href="https://www.tieushare.com/2026/10/goi-packages-trong-java.html" rel="noopener noreferrer"&gt;Gói do người dùng định nghĩa (User-defined Packages)&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Gói do người dùng định nghĩa là các gói mà bạn tạo ra để tổ chức các lớp và giao diện của riêng bạn. Việc sử dụng gói tự định nghĩa giúp bạn quản lý mã nguồn một cách có cấu trúc và tránh xung đột tên.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Lý do sử dụng Gói(Packages)?&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;↳ Nhóm các thành phần liên quan: &lt;/span&gt;&lt;span&gt;Gói giúp bạn nhóm các lớp và giao diện có liên quan với nhau. Điều này giúp mã nguồn của bạn dễ quản lý và dễ hiểu hơn.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Quản lý không gian tên (Namespace Management): &lt;/span&gt;&lt;span&gt;Gói giúp tránh xung đột tên lớp bằng cách tổ chức chúng trong các không gian tên riêng biệt. Ví dụ, bạn có thể có hai lớp có tên giống nhau trong các gói khác nhau.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Kiểm soát truy cập (Access Control): &lt;/span&gt;&lt;span&gt;Gói cung cấp cơ chế bảo mật để kiểm soát quyền truy cập vào các thành phần của nó. Bạn có thể sử dụng các từ khóa truy cập như public, protected, và private để giới hạn quyền truy cập vào các thành phần của gói.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tái sử dụng mã nguồn: &lt;/span&gt;&lt;span&gt;Gói cho phép bạn tái sử dụng mã nguồn dễ dàng bằng cách tổ chức các thư viện và chức năng chung trong các gói riêng biệt. Điều này giúp giảm thiểu việc viết lại mã và tăng hiệu suất làm việc.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;Tạo một Gói (Package)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Để tạo một Gói, bạn cần thực hiện các bước sau:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Chọn tên Gói: &lt;/span&gt;&lt;span&gt;Quy tắc đặt tên Gói sẽ được đề cập trong phần tiếp theo.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Thêm câu lệnh package: &lt;/span&gt;&lt;span&gt;Đặt một câu lệnh package với tên Gói đã chọn ở đầu mỗi tệp nguồn chứa các kiểu dữ liệu (lớp, giao diện, kiểu liệt kê và kiểu chú thích) mà bạn muốn đưa vào Gói đó.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Câu lệnh package (ví dụ: package com.example.myapp;) phải là dòng đầu tiên trong tệp nguồn.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Lưu Trữ Tệp: &lt;/span&gt;&lt;span&gt;Lưu trữ tệp Java trong một thư mục tương ứng với tên gói.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
 &lt;b&gt;MyClass.java&lt;/b&gt;&lt;br&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Lưu tệp này với tên MyClass.java trong thư mục com/example/myapp
package com.example.myapp;

public class MyClass {
    public void display() {
        System.out.println("Đây là phương thức của lớp MyClass trong gói com.example.myapp");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h2&gt;&lt;span&gt;&lt;span&gt;Cách đặt tên Gói (Package)&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Tại sao cần đặt tên gói trong Java?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Hãy tưởng tượng hàng triệu lập trình viên Java trên thế giới cùng viết các lớp và giao diện. Rất có khả năng nhiều người sẽ sử dụng cùng một cái tên cho các kiểu dữ liệu khác nhau. Ví dụ, có hai lớp Service được định nghĩa trong hai gói khác nhau:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Gói com.example&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Gói java.awt&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Mặc dù tên lớp giống nhau, trình biên dịch vẫn cho phép vì chúng nằm trong các gói khác nhau. Tên đầy đủ của mỗi lớp bao gồm cả tên gói:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;com.example.Service&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;java.awt.Service&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Tuy nhiên, vấn đề xảy ra khi hai lập trình viên độc lập sử dụng cùng một tên cho các gói của họ. Lúc này, trình biên dịch không thể phân biệt được các lớp có cùng tên và sẽ dẫn đến lỗi.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Để giải quyết vấn đề này, Java sử dụng quy ước đặt tên (Naming Conventions). Quy ước này giúp đảm bảo rằng các tên gói và tên lớp không bị trùng lặp, tránh xung đột và tạo ra một hệ thống tổ chức mã rõ ràng, dễ quản lý.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Quy ước đặt tên (Naming Conventions)&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Tên gói nên được viết toàn bộ bằng chữ thường: &lt;/span&gt;&lt;span&gt;Điều này giúp tránh xung đột với tên của các lớp hoặc giao diện, vì tên lớp và giao diện thường bắt đầu bằng chữ hoa.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Các công ty sử dụng tên miền ngược lại để đặt tên gói: &lt;/span&gt;&lt;span&gt;Ví dụ, công ty có tên miền example.com sẽ sử dụng com.example làm tiền tố cho các gói của họ.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tránh xung đột tên trong cùng một công ty: &lt;/span&gt;&lt;span&gt;Bằng cách thêm tên khu vực hoặc tên dự án sau tên công ty để tránh xung đột trong cùng một công ty. (ví dụ: com.example.region.mypackage).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Gói chuẩn của Java: &lt;/span&gt;&lt;span&gt;Các gói Được Dựng Sẵn trong java luôn bắt đầu với tiền tố java. hoặc javax. cung cấp các chức năng cốt lõi cho ngôn ngữ Java.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tên miền không hợp lệ làm tên gói: &lt;/span&gt;&lt;span&gt;Nếu tên miền chứa ký tự đặc biệt hoặc không hợp lệ theo quy tắc đặt tên của Java, bạn có thể thêm dấu gạch dưới để hợp pháp hóa tên gói.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Ví dụ hợp pháp hóa tên gói:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Tên miền hyphenated-name.example.org sẽ trở thành gói org.example.hyphenated_name.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Tên miền example.int sẽ trở thành gói int_.example.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Tên miền 123name.example.com sẽ trở thành gói com.example._123name.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;Truy cập các thành phần của Gói (Package)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Các thành phần của gói bao gồm các lớp (classes), giao diện (interfaces), kiểu liệt kê (enumerations) và kiểu chú thích (annotation types). Các thành phần này được gọi là thành viên của gói (package members).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Có ba cách để truy cập một thành phần công khai của một gói từ bên ngoài gói đó:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Sử dụng tên đầy đủ của thành phần đó.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Import thành phần đó.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Import toàn bộ gói chứa thành phần đó.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Mỗi cách phù hợp cho các tình huống khác nhau, được giải thích chi tiết trong các phần tiếp theo.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Sử dụng tên đầy đủ của thành phần đó.&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Nếu bạn đang cố gắng sử dụng một thành phần từ một Gói khác và Gói đó chưa được import, bạn phải sử dụng tên đầy đủ của thành phần đó, bao gồm cả tên Gói. Ví dụ, nếu bạn có một lớp Rectangle trong gói graphics, tên đầy đủ của lớp đó sẽ là graphics.Rectangle.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Main.java&lt;/b&gt;&lt;br&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Import gói java.awt để sử dụng lớp Graphics
import java.awt.*;

public class Main {
    public static void main(String[] args) {
        // Tạo đối tượng Rectangle từ gói graphics
        graphics.Rectangle myRectangle = new graphics.Rectangle(10, 20);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;Sử dụng tên đầy đủ phù hợp cho các trường hợp sử dụng không thường xuyên. Tuy nhiên, khi một tên được sử dụng nhiều lần, việc gõ tên nhiều lần sẽ trở nên tẻ nhạt và code khó đọc. Như một cách thay thế, bạn có thể import thành phần đó hoặc toàn bộ Gói của nó và sau đó sử dụng tên đơn giản.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Import thành phần đó.&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Nếu bạn muốn sử dụng một thành phần nhiều lần mà không muốn gõ tên đầy đủ, bạn có thể import thành phần đó. Câu lệnh import được đặt ở đầu file, sau câu lệnh package (nếu có). Dưới đây là cách bạn import lớp Rectangle từ Gói graphics được tạo trong phần trước:&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Main.java&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import graphics.Rectangle;

public class Example {
    public static void main(String[] args) {
        Rectangle myRectangle = new Rectangle();
    }
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;Cách tiếp cận này hoạt động tốt nếu bạn chỉ sử dụng một vài thành phần từ Gói graphics. Nhưng nếu bạn sử dụng nhiều kiểu dữ liệu từ một Gói, bạn nên import toàn bộ Gói.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Import toàn bộ gói chứa thành phần đó.&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Để import tất cả các kiểu dữ liệu có trong một Gói cụ thể, hãy sử dụng câu lệnh import với ký tự wildcard (*).&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Main.java&lt;/b&gt;      &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import graphics.*;

public class Test {
    public static void main(String[] args) {
        Circle myCircle = new Circle();
        Rectangle myRectangle = new Rectangle();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;Sử dụng ký tự wildcard (*) sẽ import tất cả các lớp và giao diện trong gói graphics. Bây giờ bạn có thể tham chiếu đến bất kỳ lớp hoặc giao diện nào trong Gói graphics bằng tên đơn giản của nó.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Lưu ý về ký tự Wildcard (*)&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Ký tự wildcard (*) chỉ có thể được sử dụng để import tất cả các lớp và giao diện trong một gói cụ thể. Bạn không thể sử dụng ký tự wildcard để chỉ định một tập hợp con của các lớp trong gói đó. Ví dụ, bạn không thể sử dụng ký tự wildcard để import chỉ các lớp bắt đầu bằng chữ 'A'.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Ví dụ Sai&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// Không hợp lệ - Sẽ tạo ra lỗi biên dịch
import graphics.A*;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;Câu lệnh import graphics.A*; sẽ tạo ra lỗi biên dịch vì Java không hỗ trợ việc import một tập hợp con của các lớp theo tên.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Câu lệnh import static&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Trong một số trường hợp, bạn cần truy cập thường xuyên đến các hằng số tĩnh (static final field) và các phương thức tĩnh (static method) từ một hoặc hai lớp. Việc thêm tiền tố tên của các lớp này nhiều lần có thể khiến code trở nên lộn xộn. Câu lệnh static import cung cấp cho bạn một cách để import các hằng số và phương thức tĩnh mà bạn muốn sử dụng để không cần thêm tiền tố tên lớp của chúng.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Lớp java.lang.Math định nghĩa hằng số PI (số Pi) và nhiều phương thức tĩnh, bao gồm các phương thức tính sin, cos, tan, căn bậc hai, giá trị lớn nhất, giá trị nhỏ nhất, lũy thừa và nhiều hơn nữa. Thông thường, để sử dụng các đối tượng này từ một lớp khác, bạn thêm tiền tố tên lớp, như sau:&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Cú Pháp&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;double r = Math.cos(Math.PI * theta);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;Bạn có thể sử dụng câu lệnh static import để import các thành phần tĩnh của java.lang.Math để không cần thêm tiền tố tên lớp Math. Các thành phần tĩnh của Math có thể được import riêng lẻ:&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Cú Pháp&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import static java.lang.Math.PI;
import static java.lang.Math.cos; 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;Hoặc bạn có thể import tất cả các thành phần tĩnh của lớp Math:&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Cú Pháp&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import static java.lang.Math.*;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;Sau khi được import, các thành phần tĩnh có thể được sử dụng mà không cần thêm tiền tố. Ví dụ, đoạn code mẫu trước đó sẽ trở thành:&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Cú Pháp&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;double r = cos(PI * theta);
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;&lt;span&gt;Ví dụ cụ thể khác&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Bạn cũng có thể tạo các lớp riêng của mình chứa các hằng số và phương thức tĩnh mà bạn sử dụng thường xuyên. Giả sử bạn có lớp MyConstants trong gói mypackage như sau:&lt;/span&gt;&lt;/p&gt;
&lt;b&gt;MyConstants.java&lt;/b&gt;

&lt;pre&gt;&lt;code&gt;package mypackage;

public class MyConstants {
    public static final double MY_CONSTANT = 3.14;
    public static double myMethod(double x) {
        return x * x;
    }
}&lt;/code&gt;&lt;/pre&gt;


&lt;h3&gt;&lt;span&gt;&lt;b&gt;Bạn có thể import các thành phần tĩnh từ lớp MyConstants:&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;&lt;b&gt;Cú Pháp&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import static mypackage.MyConstants.MY_CONSTANT;
import static mypackage.MyConstants.myMethod;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;&lt;span&gt;&lt;b&gt;Hoặc import tất cả các thành phần tĩnh:&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;&lt;b&gt;Cú Pháp&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import static mypackage.MyConstants.*;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;&lt;span&gt;Bây giờ bạn có thể sử dụng chúng mà không cần thêm tiền tố tên lớp:&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;&lt;b&gt;Cú Pháp&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;double value = myMethod(MY_CONSTANT);
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Lưu ý: &lt;/span&gt;&lt;span&gt;Sử dụng static import một cách hạn chế. Lạm dụng static import có thể dẫn đến code khó đọc và khó bảo trì, vì người đọc code sẽ không biết lớp nào định nghĩa một đối tượng&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;Gói con (Subpackage) trong Java&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Một gói nằm trong một gói khác được gọi là gói con. Gói con được tạo ra để phân loại các gói theo một cách chi tiết hơn.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Ví dụ: &lt;/span&gt;&lt;span&gt;Sun Microsystems đã định nghĩa một gói có tên là java chứa nhiều lớp như System, String, Reader, Writer, Socket, v.v. Các lớp này đại diện cho các nhóm chức năng cụ thể. Ví dụ, các lớp Reader và Writer được sử dụng cho các hoạt động nhập/xuất (Input/Output), các lớp Socket và ServerSocket được sử dụng cho các hoạt động mạng (networking), v.v.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Để quản lý và tổ chức các lớp này một cách hợp lý, Sun Microsystems đã phân loại gói java thành các gói con như lang, net, io, v.v. Các lớp liên quan đến nhập/xuất (Input/Output) được đặt trong gói io, các lớp Socket và ServerSocket được đặt trong gói net, v.v. Ví dụ về cấu trúc gói và gói con:&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Gói (Package) trong Java&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Gói con java.lang chứa các lớp cơ bản như String, System.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Gói con java.io chứa các lớp liên quan đến nhập/xuất như Reader, Writer.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Gói con java.net chứa các lớp liên quan đến mạng như Socket, ServerSocket.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Bằng cách sử dụng gói con, chúng ta có thể tổ chức mã nguồn một cách logic và dễ quản lý hơn, giúp người lập trình dễ dàng tìm kiếm và sử dụng các lớp cần thiết cho dự án của mình.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;

</description>
      <category>cáchtạopackagetrongjava</category>
      <category>cấutrúcchươngtrìnhjava</category>
      <category>góitrongjava</category>
      <category>tieushare</category>
    </item>
    <item>
      <title>Tính Trừu Tượng (Abstraction) trong Java | Ví dụ dễ hiểu</title>
      <dc:creator>Tiểu Share</dc:creator>
      <pubDate>Wed, 11 Nov 2026 12:47:43 +0000</pubDate>
      <link>https://dev.to/tieushare/tinh-truu-tuong-abstraction-trong-java-vi-du-de-hieu-3dog</link>
      <guid>https://dev.to/tieushare/tinh-truu-tuong-abstraction-trong-java-vi-du-de-hieu-3dog</guid>
      <description>&lt;p&gt;&lt;span id="docs-internal-guid-97c1f414-7fff-875c-7b18-e0f1dbf81fdc"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;"Trong lập trình hướng đối tượng, &lt;b&gt;&lt;a href="https://www.tieushare.com/2026/10/tinh-truu-tuong-abstraction-trong-java.html" rel="noopener noreferrer"&gt;tính trừu tượng (Abstraction)&lt;/a&gt;&lt;/b&gt; là một nguyên lý quan trọng giúp ẩn đi những chi tiết phức tạp và chỉ hiển thị những thông tin cần thiết của đối tượng. Điều này không chỉ làm cho chương trình dễ sử dụng hơn mà còn cải thiện khả năng bảo trì và mở rộng. Dưới đây là những điều cơ bản bạn cần biết về tính trừu tượng trong Java."&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅰ. Trừu tượng (Abstraction) là gì?&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Trừu tượng (Abstraction) là quá trình ẩn đi chi tiết triển khai và chỉ hiển thị chức năng cho người dùng. Nói cách khác, nó chỉ cho người dùng thấy những phần quan trọng và giấu đi các chi tiết bên trong. Trừu tượng giúp bạn tập trung vào những gì đối tượng làm thay vì cách nó làm.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Hiểu đơn giản về tính trừu tượng (Abstraction)&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Hãy tưởng tượng bạn đang sử dụng một chiếc xe hơi. Bạn biết cách lái xe, bạn biết cách đổ xăng, nhưng bạn không cần biết chi tiết về cách động cơ hoạt động, hệ thống phanh hoạt động như thế nào. Đó chính là tính trừu tượng. Bạn chỉ cần biết cách sử dụng chiếc xe mà không cần quan tâm đến cấu tạo bên trong của nó.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Trong Java, tính trừu tượng trong Java chủ yếu được áp dụng cho các phương thức. đặc biệt được thực hiện thông qua các lớp trừu tượng (abstract class) và giao diện (interface).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9cjBXZGV31WTbq9aHVdCVuN2NRi07PzaDZZaxka9nfZB37f3TXzwNjB6P8_PJSO2_JLeaAClWtjjIzg6PPV8wjGodeIQFFKhyphenhyphen2OH9D26uwx6i5ZdPfG_rbD8HVcN-AhGvfQekWZj_NJ4zf2371_Lzy3wWgHEapwE4ESsAs6CCzFMwZhvt6Eo20IJb5zQ/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả cách thực hiện tính trừu tượng." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEi9cjBXZGV31WTbq9aHVdCVuN2NRi07PzaDZZaxka9nfZB37f3TXzwNjB6P8_PJSO2_JLeaAClWtjjIzg6PPV8wjGodeIQFFKhyphenhyphen2OH9D26uwx6i5ZdPfG_rbD8HVcN-AhGvfQekWZj_NJ4zf2371_Lzy3wWgHEapwE4ESsAs6CCzFMwZhvt6Eo20IJb5zQ%2Fw640-h360%2Fimage.png" title="Ảnh mô tả cách thực hiện tính trừu tượng." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span&gt;Ảnh mô tả cách thực hiện tính trừu tượng.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Các thuật ngữ quan trọng trong tính trừu tượng (Abstraction)&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;↳ Lớp trừu tượng (Abstract Class): &lt;/span&gt;&lt;span&gt;Một lớp không thể được khởi tạo trực tiếp. Nó có thể chứa các phương thức trừu tượng (không có phần thân) và phương thức không trừu tượng (có phần thân).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Phương thức trừu tượng (Abstract Method): &lt;/span&gt;&lt;span&gt;Một phương thức không có phần thân trong lớp trừu tượng. Các lớp con bắt buộc phải triển khai phương thức này.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Giao diện (Interface): &lt;/span&gt;&lt;span&gt;Một cấu trúc hoàn toàn trừu tượng, chỉ chứa các phương thức trừu tượng (trước Java 8) hoặc có thể chứa phương thức mặc định, tĩnh và riêng tư (từ Java 8 trở đi).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Phương thức mặc định (Default Method): &lt;/span&gt;&lt;span&gt;Một phương thức trong giao diện có phần thân và được gắn từ khóa default.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Phương thức tĩnh (Static Method): &lt;/span&gt;&lt;span&gt;Một phương thức có thể được gọi mà không cần khởi tạo đối tượng của lớp hoặc giao diện.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Phương thức riêng tư (Private Method):&lt;/span&gt;&lt;span&gt;Một phương thức trong giao diện không thể truy cập từ bên ngoài giao diện, chỉ có thể được sử dụng bên trong giao diện đó.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Kế thừa (Inheritance): &lt;/span&gt;&lt;span&gt;Một cơ chế cho phép một lớp con kế thừa các thuộc tính và phương thức từ một lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Ghi đè phương thức (Method Overriding): &lt;/span&gt;&lt;span&gt;Quá trình mà một lớp con cung cấp phần thân cụ thể cho một phương thức đã được khai báo trong lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Nạp chồng phương thức (Method Overloading): &lt;/span&gt;&lt;span&gt;Quá trình định nghĩa nhiều phương thức có cùng tên nhưng khác nhau về danh sách tham số trong cùng một lớp.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;Tại sao cần tính trừu tượng (Abstraction)?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;↳ Đơn giản hóa sự phức tạp: &lt;/span&gt;&lt;span&gt;Tính trừu tượng giúp ẩn đi các chi tiết cài đặt phức tạp, chỉ hiển thị các khía cạnh cần thiết. Điều này giúp lập trình viên tập trung vào cách sử dụng một lớp hoặc đối tượng mà không cần biết chi tiết nội bộ của nó.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tăng tính bảo trì: &lt;/span&gt;&lt;span&gt;Khi các chi tiết cài đặt được ẩn đi, việc thay đổi các chi tiết này sẽ không ảnh hưởng đến các phần khác của chương trình. Điều này giúp cho việc bảo trì và nâng cấp hệ thống trở nên dễ dàng hơn.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tái sử dụng và mở rộng: &lt;/span&gt;&lt;span&gt;Các lớp trừu tượng và giao diện định nghĩa các hành vi chung mà các lớp con có thể triển khai lại. Điều này giúp tái sử dụng mã nguồn và dễ dàng mở rộng chức năng của hệ thống mà không cần viết lại mã.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Mô-đun hóa: &lt;/span&gt;&lt;span&gt;Tính trừu tượng hỗ trợ việc phát triển phần mềm theo mô-đun, nơi các mô-đun hoặc thành phần của phần mềm có thể được phát triển, kiểm tra và bảo trì độc lập với nhau.&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅱ. &lt;a href="https://www.tieushare.com/2026/10/tinh-truu-tuong-abstraction-trong-java.html" rel="noopener noreferrer"&gt;Lớp trừu tượng (Abstract Class)&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Lớp trừu tượng (abstract class) là một lớp đặc biệt trong Java được đánh dấu bằng từ khóa abstract. Nó không thể được khởi tạo trực tiếp và thường được sử dụng để biểu diễn các khái niệm trừu tượng trong mô hình đối tượng. Lớp này có thể chứa cả phương thức trừu tượng (abstract methods) và phương thức không trừu tượng (non-abstract methods) cụ thể mà các lớp con có thể kế thừa hoặc ghi đè.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;Những điểm cần phải lưu ý khi sử dụng lớp trừu tượng:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Được khai báo bằng từ khóa abstract.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Không thể khởi tạo đối tượng: &lt;/span&gt;&lt;span&gt;Mặc dù lớp trừu tượng có constructor nhưng bạn không thể tạo đối tượng trực tiếp từ lớp trừu tượng. Thay vào đó, lớp con phải kế thừa lớp trừu tượng và có thể sử dụng constructor của lớp trừu tượng thông qua từ khóa super.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Có thể chứa phương thức trừu tượng và phương thức cụ thể: &lt;/span&gt;&lt;span&gt;Một lớp trừu tượng có thể chứa cả phương thức trừu tượng (không có thân phương thức) và phương thức cụ thể (có thân phương thức).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Kế thừa: &lt;/span&gt;&lt;span&gt;Các lớp con kế thừa từ lớp trừu tượng phải triển khai tất cả các phương thức trừu tượng của lớp cha, trừ khi lớp con cũng là lớp trừu tượng.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Có thể có phương thức final, điều này có nghĩa là lớp con không thể ghi đè (override) phương thức này.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Các lớp trừu tượng (abstract class) có thể có các công cụ sửa đổi truy cập (Access Modifiers), các biến và constructors giống như các lớp thông thường.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Một lớp trừu tượng cũng có thể chứa các trường static (static field) và phương thức static (static method). Bạn có thể sử dụng các thành phần static này bằng cách tham chiếu đến tên lớp (ví dụ: TenLopTruuTuong.phuongThucStatic()) giống như với bất kỳ lớp nào khác.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqXfMmKXPbjPhl-0DU-2Vdyze7gVgs8QmwU4ktlZWtDAFfrxB_0OrFRwwGbumnz3A8o9h1DhJKpUeEwHomrsWTla3Xg1CFWMdVjTyCX-Rr8JMyH9E2XzZ4H33A3uyuAukWVnzeYRL-46i17EwtIobR1uP1J-FaIUlnCosesSInmF0Fjmd5JWU6Bfzo1KA/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả những điểm cần lưu ý khi sử dụng lớp trừu tượng." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEhqXfMmKXPbjPhl-0DU-2Vdyze7gVgs8QmwU4ktlZWtDAFfrxB_0OrFRwwGbumnz3A8o9h1DhJKpUeEwHomrsWTla3Xg1CFWMdVjTyCX-Rr8JMyH9E2XzZ4H33A3uyuAukWVnzeYRL-46i17EwtIobR1uP1J-FaIUlnCosesSInmF0Fjmd5JWU6Bfzo1KA%2Fw640-h360%2Fimage.png" title="Ảnh mô tả những điểm cần lưu ý khi sử dụng lớp trừu tượng." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span&gt;Ảnh mô tả những điểm cần lưu ý khi sử dụng lớp trừu tượng.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;&lt;span&gt;Cú pháp của lớp trừu tượng trong Java&lt;/span&gt;&lt;/h2&gt;
&lt;br&gt;
      &lt;b&gt;Cú Pháp&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;abstract class Tên_Lớp_Trừu_Tượng {&lt;br&gt;
    // Các thuộc tính&lt;br&gt;
    // Các phương thức thông thường&lt;br&gt;
    // Các phương thức trừu tượng&lt;br&gt;
}&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;&lt;b&gt;Giải thích từng phần:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ abstract class: &lt;/span&gt;&lt;span&gt;Từ khóa abstract dùng để khai báo một lớp là trừu tượng.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tên_Lớp_Trừu_Tượng: &lt;/span&gt;&lt;span&gt;Đây là tên bạn đặt cho lớp trừu tượng của mình.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Các thuộc tính: &lt;/span&gt;&lt;span&gt;Giống như các lớp thông thường, lớp trừu tượng có thể có các thuộc tính (biến).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Các phương thức thông thường: &lt;/span&gt;&lt;span&gt;Đây là những phương thức có đầy đủ thân hàm, chúng cung cấp hành vi cụ thể.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Các phương thức trừu tượng: &lt;/span&gt;&lt;span&gt;Được khai báo bằng từ khóa abstract và không có thân hàm. Các lớp con phải ghi đè các phương thức này.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;&lt;a href="https://www.tieushare.com/2026/10/tinh-truu-tuong-abstraction-trong-java.html" rel="noopener noreferrer"&gt;Phương thức trừu tượng trong Java&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Phương thức trừu tượng (abstract method) là một phương thức mà chỉ có khai báo mà không có phần thực thi (body). Phương thức trừu tượng được khai báo bằng cách sử dụng từ khóa abstract và nó chỉ có thể tồn tại trong các lớp trừu tượng (abstract class) hoặc trong các interface.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Đặc điểm của phương thức trừu tượng&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Phương thức trừu tượng được khai báo bằng từ khóa abstract mà không cần triển khai (không có dấu ngoặc nhọn và theo sau là dấu chấm phẩy).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Phần triển khai (implementation) của phương thức trừu tượng phải nằm ở các lớp con, giúp cụ thể hóa các hành vi trừu tượng đã được định nghĩa trong lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Bắt buộc ghi đè: Nếu một lớp con kế thừa từ một lớp trừu tượng mà không ghi đè tất cả các phương thức trừu tượng đó, thì chính lớp con đó cũng sẽ tự động trở thành một lớp trừu tượng.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Phương thức cụ thể trong lớp trừu tượng&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Những phương thức có đầy đủ phần thân trong lớp trừu tượng không cần phải bắt buộc ghi đè lại.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Những phương thức trong một lớp trừu tượng mà đã có phần thân (body) cụ thể không cần phải được ghi đè lại trong các lớp con. Điều này có nghĩa rằng các lớp con có thể sử dụng trực tiếp phần thân đã được cung cấp trong lớp trừu tượng mà không cần triển khai lại.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Cú pháp phương thức trừu tượng trong Java&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
      &lt;b&gt;Cú Pháp&lt;/b&gt;
    

  &lt;pre&gt;&lt;code&gt;abstract return_type tên_phương_thức(danh_sách_tham_số);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;b&gt;Giải thích từng phần:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ abstract: &lt;/span&gt;&lt;span&gt;Từ khóa này dùng để chỉ rõ rằng phương thức này là trừu tượng.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ return_type: &lt;/span&gt;&lt;span&gt;Kiểu dữ liệu mà phương thức trả về.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ tên_phương_thức: &lt;/span&gt;&lt;span&gt;Tên bạn đặt cho phương thức.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ danh_sách_tham_số: &lt;/span&gt;&lt;span&gt;Danh sách các tham số truyền vào phương thức.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;So sánh phương thức và phương thức trừu tượng&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
  
  &lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tính năng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Phương thức&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Phương thức trừu tượng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Định nghĩa&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Đoạn code thực hiện một tác vụ&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Khai báo một hành động mà các lớp con phải thực hiện&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Phần thân&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Không có&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Mục đích&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Thực hiện một hành động cụ thể&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Định nghĩa một hành vi chung&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Sử dụng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Được gọi trực tiếp&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Phải được định nghĩa lại trong các lớp con&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h4&gt;&lt;span&gt;&lt;b&gt;Dưới đây là một ví dụ về lớp trừu tượng và phương thức trừu tượng, cùng với phương thức không trừu tượng trong đơn kế thừa trong Java:&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
      &lt;b&gt;Example.java&lt;/b&gt;


  &lt;pre&gt;&lt;code&gt;abstract class Hinh {
    private String color;  // Màu sắc của hình

    // Constructor của lớp Hình
    public Hinh(String color) {
        this.color = color;
    }

    // Phương thức cụ thể với phần thân đã được định nghĩa
    public void displayColor() {
        System.out.println("Màu của hình: " + color);  // Hiển thị màu của hình
    }

    // Phương thức trừu tượng để tính diện tích, sẽ được triển khai ở lớp con
    public abstract double DienTich();
}

// Lớp Hình Tròn kế thừa từ lớp Hình
class HinhTron extends Hinh {
    private double radius;  // Bán kính của hình tròn

    // Constructor của lớp Hình Tròn
    public HinhTron(String color, double radius) {
        super(color);  // Gọi constructor của lớp cha để khởi tạo màu sắc
        this.radius = radius;  // Khởi tạo bán kính
    }

    // Override phương thức trừu tượng để tính diện tích của hình tròn
    @Override
    public double DienTich() {
        return Math.PI * radius * radius;  // Diện tích hình tròn
    }
}

// Lớp Example để thử nghiệm các lớp trên
public class Example {
    public static void main(String[] args) {
        // Tạo một đối tượng Hình Tròn
        HinhTron hinhtron = new HinhTron("Xanh Dương", 10);

        // Gọi phương thức hiển thị màu sắc từ lớp Hình
        hinhtron.displayColor();

        // Gọi phương thức tính diện tích từ lớp Hình Tròn
        System.out.println("Diện tích Hình Tròn: " + hinhtron.DienTich());
    }
}&lt;/code&gt;&lt;/pre&gt;
  
   
  &lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;Màu của hình: Xanh Dương&lt;br&gt;
Diện tích Hình Tròn: 314.1592653589793&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong ví dụ này, lớp HinhTron kế thừa từ Hinh và triển khai phương thức DienTich(). Tuy nhiên, nó không cần triển khai lại phương thức displayColor() vì phương thức này đã có phần thân cụ thể trong lớp Hinh. Do đó, những phương thức trong lớp trừu tượng mà đã có phần thân cụ thể không bắt buộc các lớp con phải ghi đè lại, chúng có thể được sử dụng trực tiếp từ lớp trừu tượng.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;&lt;b&gt;Dưới đây là một ví dụ về lớp trừu tượng và phương thức trừu tượng, cùng với phương thức không trừu tượng trong kế thừa nhiều cấp trong Java:&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
      &lt;b&gt;Example.java&lt;/b&gt;


  &lt;pre&gt;&lt;code&gt;abstract class Hinh {
    private String color;  // Màu sắc của hình

    // Constructor của lớp Hình
    public Hinh(String color) {
        this.color = color;
    }

    // Phương thức cụ thể với phần thân đã được định nghĩa
    public void displayColor() {
        System.out.println("Màu của hình: " + color);  // Hiển thị màu của hình
    }

    // Phương thức trừu tượng để tính diện tích, sẽ được triển khai ở lớp con
    public abstract double DienTich();
}

// Lớp Hình Tròn kế thừa từ lớp Hình
class HinhTron extends Hinh {
    private double radius;  // Bán kính của hình tròn

    // Constructor của lớp Hình Tròn
    public HinhTron(String color, double radius) {
        super(color);  // Gọi constructor của lớp cha để khởi tạo màu sắc
        this.radius = radius;  // Khởi tạo bán kính
    }

    // Override phương thức trừu tượng để tính diện tích của hình tròn
    @Override
    public double DienTich() {
        return Math.PI * radius * radius;  // Diện tích hình tròn
    }
}
// Lớp hình chữ nhật kế thừa từ lớp Hinh và triển khai phương thức DienTich()
class HinhChuNhat extends Hinh {
    private double width;  // Chiều rộng của hình chữ nhật
    private double height;  // Chiều cao của hình chữ nhật

    public HinhChuNhat(String color, double width, double height) {
        super(color);
        this.width = width;
        this.height = height;
    }
    // Override phương thức trừu tượng để tính diện tích của hình chữ nhật
    @Override
    public double DienTich() {
        return width * height; // Diện tích hình chữ nhật
    }
}

// Lớp Example để thử nghiệm các lớp trên
public class Example {
    public static void main(String[] args) {
        // Tạo một đối tượng Hình Tròn
        HinhTron hinhtron = new HinhTron("Xanh Dương", 10);
        // Gọi phương thức hiển thị màu sắc từ lớp Hình
        hinhtron.displayColor();
        // Gọi phương thức tính diện tích từ lớp Hình Tròn
        System.out.println("Diện tích Hình Tròn: " + hinhtron.DienTich());

        System.out.println();
        // Tạo một đối tượng Hình chữ nhật
        HinhChuNhat hinhChuNhat = new HinhChuNhat("Xanh Dương", 10,20);
        // Gọi phương thức hiển thị màu sắc từ lớp Hình
        hinhChuNhat.displayColor();
        // Gọi phương thức tính diện tích từ lớp Hình chữ nhật
        System.out.println("Diện tích Hình Chữ Nhật: " + hinhChuNhat.DienTich());

    }
}&lt;/code&gt;&lt;/pre&gt;
  
   
  &lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;Màu của hình: Xanh Dương&lt;br&gt;
Diện tích Hình Tròn: 314.1592653589793

&lt;/code&gt;&lt;p&gt;&lt;code&gt;Màu của hình: Xanh Dương&lt;br&gt;&lt;br&gt;
Diện tích Hình Chữ Nhật: 200.0&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong ví dụ này, mỗi lớp con (HinhTrong, HinhChuNhat) kế thừa và triển khai phương thức trừu tượng DienTich() theo cách riêng biệt tùy thuộc vào loại hình học tương ứng. Lớp Hinh cung cấp tính năng chung như là tính diện tích và hiển thị màu sắc, đó là một ví dụ rõ ràng về tính trừu tượng và kế thừa nhiều cấp trong Java.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;Dưới đây là một ví dụ về lớp trừu tượng và phương thức trừu tượng, cùng với phương thức không trừu tượng trong kế thừa thứ bậc trong Java:&lt;/span&gt;&lt;/h4&gt;
      &lt;b&gt;Example.java&lt;/b&gt;

  &lt;pre&gt;&lt;code&gt;// Lớp trừu tượng Animal đại diện cho động vật
abstract class Animal {
    protected String name;

    public Animal(String name) {
        this.name = name;
    }

    // Phương thức trừu tượng để phát ra tiếng kêu của động vật
    public abstract void makeSound();

    // Phương thức không trừu tượng để hiển thị thông tin chung của động vật
    public void displayInfo() {
        System.out.println("Động vật: " + name);
    }
}

// Lớp con Dog kế thừa từ lớp Animal và triển khai phương thức makeSound()
class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println(name + " kêu: Gâu gâu");
    }
}

// Lớp con Cat kế thừa từ lớp Animal và triển khai phương thức makeSound()
class Cat extends Animal {
    public Cat(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println(name + " kêu: Meo meo");
    }
}

// Lớp con Cow kế thừa từ lớp Animal và triển khai phương thức makeSound()
class Cow extends Animal {
    public Cow(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println(name + " kêu: Moo moo");
    }
}

// Lớp Example để kiểm tra các lớp trên
public class Example {
    public static void main(String[] args) {
        Dog dog = new Dog("Bobby");
        Cat cat = new Cat("Kitty");
        Cow cow = new Cow("Mooey");

        dog.displayInfo();
        dog.makeSound();

        cat.displayInfo();
        cat.makeSound();

        cow.displayInfo();
        cow.makeSound();
    }
}&lt;/code&gt;&lt;/pre&gt;
  
   
  &lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;Động vật: Bobby&lt;br&gt;
Bobby kêu: Gâu gâu&lt;br&gt;
Động vật: Kitty&lt;br&gt;
Kitty kêu: Meo meo&lt;br&gt;
Động vật: Mooey&lt;br&gt;
Mooey kêu: Moo moo&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong ví dụ trên, mỗi lớp con (Dog, Cat, Cow) kế thừa và triển khai phương thức trừu tượng makeSound() để cung cấp âm thanh phát ra của từng loại động vật. Lớp Animal cung cấp tính năng chung như hiển thị thông tin và yêu cầu các lớp con cung cấp cách thức cụ thể cho việc phát ra tiếng kêu.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;&lt;b&gt;Dưới đây là một ví dụ khi một lớp trừu tượng triển khai một giao diện (interface) trong Java:&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;Thông thường, một lớp sử dụng giao diện (interface) thì phải triển khai tất cả phương thức của giao diện đó.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Trường hợp ngoại lệ: một lớp trừu tượng (Abstract class) có thể không triển khai hết các phương thức của giao diện, nhưng các lớp con của nó phải chịu trách nhiệm triển khai đầy đủ.&lt;/span&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      &amp;lt;b class="syntax-title"&amp;gt;Example.java&amp;lt;/b&amp;gt;

  &amp;lt;pre style="margin-top: 0px; padding-top: 0px;"&amp;gt;&amp;lt;code class="language-java"&amp;gt;interface VeHinh {
void Ve(); // Phương thức trừu tượng
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;abstract class Hinh implements VeHinh {&lt;br&gt;
    private String color;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public Hinh(String color) {
    this.color = color;
}

public String getColor() {
    return color;
}

// Phương thức cụ thể
public void displayColor() {
    System.out.println("Màu: " + color);
}
// Lớp trừu tượng không cần triển khai phương thức Ve() ở đây
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;class HinhTron extends Hinh {&lt;br&gt;
    private double BanKinh;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public HinhTron(String color, double BanKinh) {
    super(color);
    this.BanKinh = BanKinh;
}

@Override
public void Ve() {
    System.out.println("Vẽ đường tròn có bán kính: " + BanKinh);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;public class Example {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        HinhTron hinhtron = new HinhTron("Xanh", 5.0);&lt;br&gt;
        hinhtron.displayColor();&lt;br&gt;
        hinhtron.Ve();&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;p dir="ltr" style="line-height: 1.8; margin-bottom: 0pt; margin-top: 0pt;"&amp;gt;&amp;lt;span style="font-family: &amp;amp;quot;Times New Roman&amp;amp;quot;, serif; font-size: 16pt; font-variant: normal; vertical-align: baseline; white-space: pre-wrap;"&amp;gt;&amp;lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&amp;gt;&amp;lt;span style="font-size: 14pt; font-variant: normal; vertical-align: baseline;"&amp;gt;&amp;lt;b&amp;gt;Kết quả của chương trình là: &amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;

  &amp;lt;pre style="margin-top: 0px; padding-top: 0px;"&amp;gt;&amp;lt;code class="language-java"&amp;gt;Màu: Xanh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Vẽ đường tròn có bán kính: 5.0&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Trong ví dụ này khi chạy mã, Lớp HinhTron kế thừa từ lớp trừu tượng Hinh và triển khai phương thức Ve(). bạn sẽ thấy rằng phương thức Ve() được gọi cho cả đối tượng HinhTron mà không gặp lỗi biên dịch.&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅲ. &lt;a href="https://www.tieushare.com/2026/10/tinh-truu-tuong-abstraction-trong-java.html" rel="noopener noreferrer"&gt;Lớp trừu tượng lồng nhau (Abstract nested class)&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Bạn có thể có các lớp trừu tượng lồng nhau, tức là một lớp trừu tượng chứa một lớp trừu tượng khác bên trong nó. Kế thừa trong các lớp trừu tượng lồng nhau hoạt động tương tự như trong các lớp thông thường. Bạn có thể kế thừa một lớp trừu tượng lồng bên trong từ một lớp khác, để sử dụng đầy đủ các phương thức và lớp trừu tượng bên trong, lớp con bắt buộc phải triển khai tất cả các phương thức trừu tượng của lớp trừu tượng lồng bên trong.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Đây là một ví dụ về cách sử dụng lớp trừu tượng lồng nhau:&lt;/span&gt;&lt;/h3&gt;
          &lt;b&gt;Example.java&lt;/b&gt;
    

      &lt;pre&gt;&lt;code&gt;abstract class Animal {
    private String name;

    public Animal(String name) {
        this.name = name;
    }

    public void display() {
        System.out.println("Tên Động Vật: " + name);
    }

    public abstract void sound();

    // Lớp trừu tượng lồng bên trong
    abstract class Leg {
        public abstract void walk();
    }
}
class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }

    @Override
    public void sound() {
        System.out.println("Chú Chó Sủa Gâu Gâu");
    }

    // Triển khai lớp trừu tượng lồng bên trong
    class DogLeg extends Leg {
        @Override
        public void walk() {
            System.out.println("Chó đi bằng bốn chân");
        }
    }
}

public class Example {
    public static void main(String[] args) {
        Dog dog = new Dog("Buddy");
        dog.display();
        dog.sound();

        // Tạo một đối tượng của lớp lồng bên trong Dog
        Dog.DogLeg dogLeg = dog.new DogLeg();
        dogLeg.walk();
    }
}&lt;/code&gt;&lt;/pre&gt;
      
       
      &lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;pre style="margin-top: 0px; padding-top: 0px;"&amp;gt;&amp;lt;code class="language-java"&amp;gt;Tên Động Vật: Buddy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Chú Chó Sủa Gâu Gâu&lt;br&gt;
Chó đi bằng bốn chân&lt;/p&gt;

&lt;h4&gt;&lt;span&gt;Đây là một ví dụ nếu bạn cố gắng tạo một đối tượng hoặc sử dụng phương thức của lớp trừu tượng lồng bên trong mà không triển khai nó, sẽ gặp lỗi:&lt;/span&gt;&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      &amp;lt;b class="syntax-title"&amp;gt;Example.java&amp;lt;/b&amp;gt;


  &amp;lt;pre style="margin-top: 0px; padding-top: 0px;"&amp;gt;&amp;lt;code class="language-java"&amp;gt;abstract class Animal {
private String name;

public Animal(String name) {
    this.name = name;
}

public void display() {
    System.out.println("Tên Động Vật: " + name);
}

public abstract void sound();

// Lớp trừu tượng lồng bên trong
abstract class Leg {
    public abstract void walk();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
class Dog extends Animal {&lt;br&gt;
    public Dog(String name) {&lt;br&gt;
        super(name);&lt;br&gt;
    }&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override
public void sound() {
    System.out.println("Chú Chó Sủa Gâu Gâu");
}

// Nếu không triển khai lớp trừu tượng lồng bên trong, sẽ không có lỗi biên dịch
// Nhưng nếu bạn cố gắng tạo một đối tượng hoặc sử dụng phương thức của lớp trừu tượng lồng bên trong mà không triển khai nó, sẽ gặp lỗi
/*
class DogLeg extends Leg {
    @Override
    public void walk() {
        System.out.println("Dog walks on four legs");
    }
}
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;public class Example {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        Dog dog = new Dog("Buddy");&lt;br&gt;
        dog.display();&lt;br&gt;
        dog.sound();&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Tạo một đối tượng của lớp lồng bên trong Dog
    Dog.DogLeg dogLeg = dog.new DogLeg();
    dogLeg.walk();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;p dir="ltr" style="line-height: 1.8; margin-bottom: 0pt; margin-top: 0pt;"&amp;gt;&amp;lt;span style="font-family: &amp;amp;quot;Times New Roman&amp;amp;quot;, serif; font-size: 16pt; font-variant: normal; vertical-align: baseline; white-space: pre-wrap;"&amp;gt;&amp;lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&amp;gt;&amp;lt;span style="font-size: 14pt; font-variant: normal; vertical-align: baseline;"&amp;gt;&amp;lt;b&amp;gt;Kết quả của chương trình là: &amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;

  &amp;lt;pre style="margin-top: 0px; padding-top: 0px;"&amp;gt;&amp;lt;code class="language-java"&amp;gt;Exception in thread "main" java.lang.Error: Unresolved compilation problems: Dog.DogLeg cannot be resolved to a type Dog.DogLeg cannot be resolved to a type at Example.main(Example.java:48)&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;span&gt;Như Vậy, nếu lớp con kế thừa từ một lớp trừu tượng bên ngoài và muốn sử dụng lớp trừu tượng lồng bên trong thì bắt buộc phải triển khai tất cả các phương thức trừu tượng của lớp trừu tượng lồng bên trong. Nếu không, lớp con đó cũng phải được khai báo là lớp trừu tượng.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;Dưới đây là một ví dụ khi một lớp trừu tượng kế thừa từ một lớp trừu tượng khác&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;Khi một lớp trừu tượng kế thừa từ một lớp trừu tượng khác, nó kế thừa tất cả các phương thức và biến thành viên từ lớp cha. Lớp con trừu tượng có thể ghi đè các phương thức trừu tượng của lớp cha hoặc để các lớp con kế thừa từ nó triển khai các phương thức này.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Example.java&lt;/b&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;pre style="margin-top: 0px; padding-top: 0px;"&amp;gt;&amp;lt;code class="language-java"&amp;gt;// Lớp trừu tượng cơ bản
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;abstract class Animal {&lt;br&gt;
    private String name;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public Animal(String name) {
    this.name = name;
}

// Phương thức trừu tượng
public abstract void sound();

// Phương thức cụ thể
public void sleep() {
    System.out.println(name + " đang ngủ.");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// Lớp trừu tượng kế thừa từ lớp Animal&lt;br&gt;
abstract class Mammal extends Animal {&lt;br&gt;
    public Mammal(String name) {&lt;br&gt;
        super(name);&lt;br&gt;
    }&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Phương thức trừu tượng mới
public abstract void walk();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// Lớp cụ thể kế thừa từ lớp Mammal&lt;br&gt;
class Dog extends Mammal {&lt;br&gt;
    public Dog(String name) {&lt;br&gt;
        super(name);&lt;br&gt;
    }&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override
public void sound() {
    System.out.println("Chú chó đang sủa");
}

@Override
public void walk() {
    System.out.println("chú chó đang đi");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;public class Example {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        Dog dog = new Dog("Buddy");&lt;br&gt;
        dog.sound(); // Gọi phương thức ghi đè từ lớp Dog&lt;br&gt;
        dog.walk();  // Gọi phương thức ghi đè từ lớp Dog&lt;br&gt;
        dog.sleep(); // Gọi phương thức cụ thể từ lớp Animal&lt;br&gt;
    }&lt;br&gt;
} &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;p dir="ltr" style="line-height: 1.8; margin-bottom: 0pt; margin-top: 0pt;"&amp;gt;&amp;lt;span style="font-family: &amp;amp;quot;Times New Roman&amp;amp;quot;, serif; font-size: 16pt; font-variant: normal; vertical-align: baseline; white-space: pre-wrap;"&amp;gt;&amp;lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&amp;gt;&amp;lt;span style="font-size: 14pt; font-variant: normal; vertical-align: baseline;"&amp;gt;&amp;lt;b&amp;gt;Kết quả của chương trình là: &amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;

  &amp;lt;pre style="margin-top: 0px; padding-top: 0px;"&amp;gt;&amp;lt;code class="language-java"&amp;gt;Chú chó đang sủa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;chú chó đang đi&lt;br&gt;
Buddy đang ngủ.&lt;/p&gt;


&lt;p&gt;&lt;span&gt;Trong ví dụ này, lớp Dog phải triển khai tất cả các phương thức trừu tượng từ cả lớp Animal và Mammal. Tuy nhiên, nếu lớp Mammal không triển khai các phương thức trừu tượng của lớp Animal, lớp Dog phải triển khai tất cả các phương thức trừu tượng từ cả hai lớp cha trừu tượng.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;Mối quan hệ giữa class và Abstract class trong Java&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Lớp con của lớp trừu tượng phải triển khai tất cả các phương thức trừu tượng của lớp trừu tượng cha hoặc trở thành lớp trừu tượng.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Lớp trừu tượng không thể được khởi tạo trực tiếp; chỉ có các lớp con cụ thể của lớp trừu tượng mới có thể được khởi tạo.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Lớp trừu tượng thường được sử dụng để định nghĩa một cấu trúc cơ bản và các lớp con cụ thể sẽ kế thừa(extends) cấu trúc đó và thực hiện các hành vi cụ thể.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHrmC8D9-oWn19D5maL5bBvEZ8-17uN_JeG8KhCixrdGaHBlEaZ1JEATKAXQDmna9sLlMbua_OUYlISFdeWEubzC9rYy5KPlN0Bqfg5VcAQ_EtzDJedQ-GaB5mBWKhb9-guppNLbC9kOGN-heA2NDyor7qWFA03O7Awgu2Lr3t5k-SKjWX892dfC1lQY4/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả mối quan hệ giữa class và abstract class." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEgHrmC8D9-oWn19D5maL5bBvEZ8-17uN_JeG8KhCixrdGaHBlEaZ1JEATKAXQDmna9sLlMbua_OUYlISFdeWEubzC9rYy5KPlN0Bqfg5VcAQ_EtzDJedQ-GaB5mBWKhb9-guppNLbC9kOGN-heA2NDyor7qWFA03O7Awgu2Lr3t5k-SKjWX892dfC1lQY4%2Fw640-h360%2Fimage.png" title="Ảnh mô tả mối quan hệ giữa class và abstract class." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span&gt;Ảnh mô tả mối quan hệ giữa class và abstract class.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;So sánh chi tiết giữa class và abstract class&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tính năng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Class&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Abstract Class&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Khả năng tạo đối tượng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có thể&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Không thể trực tiếp&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Phương thức&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có thể có cả phương thức thông thường và trừu tượng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có thể có cả phương thức thông thường và trừu tượng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Phương thức trừu tượng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Không có&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Mục đích&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Là bản thiết kế cho các đối tượng cụ thể&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Là lớp cha chung, cung cấp các đặc tính và hành vi chung cho các lớp con&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Sử dụng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Để tạo ra các đối tượng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Để tạo ra một cấu trúc phân cấp lớp, định nghĩa các khái niệm chung&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Khi nào nên sử dụng Abstract Class?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Khi muốn tạo một lớp cha chung: Để định nghĩa các thuộc tính và phương thức chung cho một nhóm các lớp con.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Khi có một số phương thức mà các lớp con phải cài đặt: Phương thức trừu tượng đảm bảo rằng các lớp con phải cung cấp triển khai cụ thể.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Khi muốn tạo ra một hệ thống phân cấp lớp rõ ràng: Abstract class giúp tổ chức code một cách hợp lý và dễ hiểu.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;

</description>
      <category>4tínhchấtooptrongjava</category>
      <category>abstractclassjava</category>
      <category>abstractiontrongjava</category>
      <category>tieushare</category>
    </item>
    <item>
      <title>Tính Đa Hình (Polymorphism) Trong Java | Ví Dụ Chi Tiết</title>
      <dc:creator>Tiểu Share</dc:creator>
      <pubDate>Tue, 10 Nov 2026 06:10:18 +0000</pubDate>
      <link>https://dev.to/tieushare/tinh-da-hinh-polymorphism-trong-java-vi-du-chi-tiet-4hkb</link>
      <guid>https://dev.to/tieushare/tinh-da-hinh-polymorphism-trong-java-vi-du-chi-tiet-4hkb</guid>
      <description>&lt;p&gt;&lt;span id="docs-internal-guid-9fd4de36-7fff-9195-6f78-d9e43d2575f8"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;"Trong lập trình hướng đối tượng, tính đa hình (Polymorphism) là một nguyên lý quan trọng cho phép một đối tượng thể hiện các hành vi khác nhau tùy thuộc vào ngữ cảnh. Điều này giúp tăng tính linh hoạt và mở rộng khả năng của chương trình. Dưới đây là những điều cơ bản bạn cần biết về tính đa hình trong Java."&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅰ. &lt;a href="https://www.tieushare.com/2026/10/tinh-da-hinh-polymorphism-trong-java.html" rel="noopener noreferrer"&gt;Đa hình (Polymorphism) là gì?&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Tính đa hình (polymorphism) là một trong bốn tính chất cơ bản của lập trình hướng đối tượng (OOP) trong Java, bên cạnh tính đóng gói (encapsulation), tính kế thừa (inheritance) và tính trừu tượng (abstraction). Tính đa hình cho phép một đối tượng có thể thực hiện các hành động (phương thức) theo nhiều cách khác nhau. Điều này có nghĩa là cùng một giao diện hoặc phương thức, nhưng các đối tượng khác nhau có thể triển khai và thực hiện hành động đó theo cách riêng của mình.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Từ nguyên:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;"Poly" trong tiếng Hy Lạp nghĩa là "nhiều".&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;"Morphs" trong tiếng Hy Lạp nghĩa là "hình dạng".&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Vì vậy, đa hình nghĩa đen là "nhiều hình dạng".&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Các thuật ngữ trong đa hình (Polymorphism)&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Nạp chồng phương thức (Method Overloading): &lt;/span&gt;&lt;span&gt;Cùng một tên phương thức nhưng với các danh sách tham số khác nhau.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Nạp chồng hàm tạo (Constructor Overloading): &lt;/span&gt;&lt;span&gt;Cùng một tên hàm tạo nhưng với các danh sách tham số khác nhau.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Ghi đè phương thức (Method Overriding): &lt;/span&gt;&lt;span&gt;Lớp con định nghĩa lại một phương thức đã có trong lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Kế thừa: &lt;/span&gt;&lt;span&gt;Cơ chế cho phép một lớp con kế thừa các thuộc tính và phương thức từ lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Giao diện (Interface): &lt;/span&gt;&lt;span&gt;Một bản hợp đồng quy định các phương thức mà một lớp phải thực hiện.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Lớp trừu tượng (Abstract class): &lt;/span&gt;&lt;span&gt;Một lớp không thể tạo đối tượng trực tiếp, thường chứa các phương thức trừu tượng (chỉ khai báo, không có triển khai).&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Các loại đa hình trong Java&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;&lt;b&gt;1. Đa hình thời gian biên dịch (Compile-time polymorphism):&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Nạp chồng phương thức (Method Overloading)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Nạp chồng hàm tạo (Constructor Overloading)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;b&gt;2. Đa hình thời gian chạy (Runtime polymorphism):&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Ghi đè phương thức (Method Overriding):&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYvOCYdzDSLBgAGhBD0QjCNX1zkudFnS2uWuMp6gM8G9D4YkWZOyoeD-fuP8xTkJ7GXq7kPajOQCXt3UyCI617MYzsvO-fWOLxwRbJG-DMfoH83Hzt0cTzjceHcPrfK7Bdplu9mjByKwfZgwP4iGM9r4oe2YA5rX0L9nrnm9gZ_QI3j-plGc8h0lMyAoA/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả các loại đa hình trong java." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEiYvOCYdzDSLBgAGhBD0QjCNX1zkudFnS2uWuMp6gM8G9D4YkWZOyoeD-fuP8xTkJ7GXq7kPajOQCXt3UyCI617MYzsvO-fWOLxwRbJG-DMfoH83Hzt0cTzjceHcPrfK7Bdplu9mjByKwfZgwP4iGM9r4oe2YA5rX0L9nrnm9gZ_QI3j-plGc8h0lMyAoA%2Fw640-h360%2Fimage.png" title="Ảnh mô tả các loại đa hình trong java." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span&gt;Ảnh mô tả các loại đa hình trong java.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅱ. Đa hình thời gian biên dịch (Compile-time polymorphism)&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;&lt;b&gt;&lt;a href="https://www.tieushare.com/2026/10/tinh-da-hinh-polymorphism-trong-java.html" rel="noopener noreferrer"&gt;Đa hình thời gian biên dịch (Compile-time polymorphism)&lt;/a&gt;&lt;/b&gt; hay còn gọi là đa hình tĩnh (static polymorphism), là một khái niệm trong lập trình hướng đối tượng (OOP) mà trong đó việc xác định phương thức nào sẽ được gọi diễn ra ngay tại thời điểm biên dịch chương trình. Nói cách khác, trình biên dịch sẽ quyết định phương thức nào sẽ được thực thi dựa trên kiểu dữ liệu của các đối số truyền vào hàm.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Đa hình thời gian biên dịch chủ yếu được thực hiện thông qua nạp chồng phương thức (method overloading) và nạp chồng hàm tạo (constructor overloading). Dưới đây sẽ giải thích chi tiết hơn về hai khái niệm này:&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;1. Nạp chồng phương thức (Method Overloading)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Định nghĩa: &lt;/span&gt;&lt;span&gt;Là khả năng định nghĩa nhiều phương thức có cùng tên trong một lớp, nhưng khác nhau về số lượng hoặc kiểu dữ liệu của các tham số. Giúp đơn giản hóa cú pháp gọi phương thức, dễ dàng truy cập và sử dụng.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Có 2 cách nạp chồng phương thức (Method Overloading) trong java:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;↳ Thay đổi số lượng các tham số.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Thay đổi kiểu dữ liệu của các tham số.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMV0iIA1u7Ok_dnMHyQrFq4KjBa-7sbmuNStZKAxTWURj6Y1ITOkio51LghwqbJzto28xiG8lMa1bUPug7-C2u6wJXworB7KrH52r13DIJ05Df-jzazBF09c8WVFvaIOWsXHtzMVL36RdQiP3zao_v4QnMrWFNwl8l8vn5tkj2EXBMieOb-dgENt2uqIw/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả hai cách nạp chồng phương thức." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEjMV0iIA1u7Ok_dnMHyQrFq4KjBa-7sbmuNStZKAxTWURj6Y1ITOkio51LghwqbJzto28xiG8lMa1bUPug7-C2u6wJXworB7KrH52r13DIJ05Df-jzazBF09c8WVFvaIOWsXHtzMVL36RdQiP3zao_v4QnMrWFNwl8l8vn5tkj2EXBMieOb-dgENt2uqIw%2Fw640-h360%2Fimage.png" title="Ảnh mô tả hai cách nạp chồng phương thức." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Ảnh mô tả hai cách nạp chồng phương thức.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;b&gt;Example.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;class TinhTong {&lt;br&gt;
    // Phương thức tính tổng với hai số nguyên&lt;br&gt;
    public int add(int a, int b) {&lt;br&gt;
        return a + b;&lt;br&gt;
    }

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Nạp chồng phương thức tính tổng với ba số nguyên
public int add(int a, int b, int c) {
    return a + b + c;
}

// Nạp chồng phương thức tính tổng với hai số double
public double add(double a, double b) {
    return a + b;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;public class Example {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        TinhTong tong = new TinhTong();&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Gọi các phương thức add với các số khác nhau

    System.out.println("Tổng hai số Nguyên: "+tong.add(1, 2));         // Gọi add(int, int)
    System.out.println("Tổng ba số Nguyên: "+tong.add(1, 2, 3));      // Gọi add(int, int, int)
    System.out.println("Tổng hai số Thực: "+tong.add(1.5, 2.5));     // Gọi add(double, double)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Tổng hai số Nguyên: 3&lt;br&gt;
Tổng ba số Nguyên: 6&lt;br&gt;
Tổng hai số Thực: 4.0&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong ví dụ này, phương thức add trong lớp TinhTong được nạp chồng ba lần với các tham số khác nhau: hai số nguyên, ba số nguyên và hai số double.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Cơ chế hoạt động: &lt;/span&gt;&lt;span&gt;Khi gọi phương thức add, trình biên dịch sẽ dựa vào kiểu dữ liệu của các đối số truyền vào để chọn phương thức phù hợp.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Các câu hỏi về nạp chồng phương thức trong java&lt;/span&gt;&lt;/h3&gt;
&lt;h4&gt;&lt;span&gt;&lt;b&gt;Câu hỏi 1: Tại sao không thể nạp chồng phương thức chỉ bằng cách thay đổi kiểu trả về?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ Trả lời: &lt;/span&gt;&lt;span&gt;Trong Java, không thể nạp chồng phương thức chỉ bằng cách thay đổi kiểu trả về vì nếu chỉ khác nhau bởi kiểu trả về, hai phương thức có thể có cùng tên và cùng các tham số. Điều này dẫn đến sự mơ hồ khi gọi phương thức, vì không rõ được phương thức nào sẽ được sử dụng.&lt;/span&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;b class="syntax-title"&amp;gt;Example.java&amp;lt;/b&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;pre&gt;&lt;code&gt;class TinhTong {&lt;br&gt;
    // Phương thức tính tổng với hai số nguyên&lt;br&gt;
    public int add(int a, int b) {&lt;br&gt;
        return a + b;&lt;br&gt;
    }&lt;br&gt;
    // Nạp chồng phương thức tính tổng với hai số double&lt;br&gt;
    public double add(int a, int b) {&lt;br&gt;
        return a + b;&lt;br&gt;
    }&lt;br&gt;
}

&lt;p&gt;public class Example {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        TinhTong tong = new TinhTong();&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Gọi các phương thức add với các số khác nhau
    System.out.println("Tổng hai số Nguyên: "+tong.add(1, 2));         // Gọi add(int, int)
    System.out.println("Tổng hai số Thực: "+tong.add(1.5, 2.5));     // Gọi add(double, double)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;} &lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Exception in thread "main" java.lang.Error: Unresolved compilation problem: The method add(int, int) in the type TinhTong is not applicable for the arguments (double, double) at Example.main(Example.java:20)&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong ví dụ này, hai phương thức add cố gắng có cùng tên và cùng số lượng tham số, chỉ khác nhau bởi kiểu trả về (int và double). Điều này không được phép trong Java vì trình biên dịch không thể xác định được phương thức nào sẽ được gọi khi gọi add(2, 3), do cả hai phương thức đều có thể phù hợp với việc truyền vào hai số nguyên.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;&lt;b&gt;Câu hỏi 2: Có thể nạp chồng phương thức main() không?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ Trả lời: &lt;/span&gt;&lt;span&gt;Có, bạn có thể nạp chồng (overload) phương thức main() có cùng tên trong một lớp, nhưng chỉ có một phương thức main() có chữ ký chuẩn để JVM (Java Virtual Machine) có thể chạy khi bạn thực thi chương trình Java.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Thông thường, chúng ta sử dụng một phương thức main() với chữ ký như sau:&lt;/span&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;b class="syntax-title"&amp;gt;Cú Pháp&amp;lt;/b&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;pre&gt;&lt;code&gt;public static void main(String[] args) {&lt;br&gt;
    // Code ở đây&lt;br&gt;
}&lt;/code&gt;&lt;/pre&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;b class="syntax-title"&amp;gt;OverloadingMain.java&amp;lt;/b&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;pre&gt;&lt;code&gt;public class OverloadingMain {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        System.out.println("Phương thức main chính");&lt;br&gt;
    }

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static void main(int[] args) {
    System.out.println("Phương thức main với mảng số nguyên");
}

public static void main(String arg) {
    System.out.println("Phương thức main với một chuỗi");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Phương thức main chính&lt;/code&gt;&lt;/pre&gt;


&lt;h3&gt;&lt;span&gt;&lt;b&gt;Lưu ý:&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Phương thức main() chính: &lt;/span&gt;&lt;span&gt;Mặc dù có thể nạp chồng main(), nhưng luôn phải có một phương thức main() với chữ ký chuẩn (public static void main(String[] args)) để JVM có thể bắt đầu thực thi chương trình.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ JVM chỉ gọi một phương thức main(): &lt;/span&gt;&lt;span&gt;Khi bạn chạy chương trình, JVM chỉ gọi một phương thức main() duy nhất, đó là phương thức main() có chữ ký chuẩn.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Phân tích về nạp chồng phương thức và sự thay đổi kiểu dữ liệu&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Chúng ta cần xem xét cách trình biên dịch Java quyết định phương thức nào sẽ được gọi khi có nhiều phương thức cùng tên (nạp chồng):&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tìm kiếm phương thức phù hợp: &lt;/span&gt;&lt;span&gt;Trình biên dịch sẽ tìm kiếm một phương thức có cùng tên và số lượng tham số với cuộc gọi phương thức.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ So sánh kiểu dữ liệu của tham số: &lt;/span&gt;&lt;span&gt;Nếu có nhiều phương thức thỏa mãn điều kiện trên, trình biên dịch sẽ so sánh kiểu dữ liệu của các tham số truyền vào với kiểu dữ liệu của các tham số trong định nghĩa phương thức.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Ép kiểu ngầm định: &lt;/span&gt;&lt;span&gt;Nếu có sự khác biệt về kiểu dữ liệu, trình biên dịch sẽ cố gắng thực hiện ép kiểu ngầm định (implicit casting) để các đối số truyền vào phù hợp với kiểu dữ liệu của các tham số trong định nghĩa phương thức.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Ưu tiên phương thức không cần ép kiểu: &lt;/span&gt;&lt;span&gt;Nếu có nhiều phương thức đều có thể được gọi sau khi ép kiểu, trình biên dịch sẽ ưu tiên chọn phương thức không cần ép kiểu.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Cơ chế tự động ép kiểu trong nạp chồng phương thức&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Khi bạn gọi một phương thức, trình biên dịch sẽ tìm kiếm phương thức phù hợp nhất dựa trên các đối số truyền vào. Nếu không tìm thấy một phương thức khớp chính xác, trình biên dịch sẽ cố gắng ép kiểu các đối số để tìm một phương thức phù hợp.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Quy tắc ép kiểu: &lt;/span&gt;&lt;span&gt;Java có một hệ thống quy tắc rõ ràng về việc ép kiểu các kiểu dữ liệu nguyên thủy (primitive data types). Các kiểu dữ liệu có phạm vi giá trị nhỏ hơn có thể được tự động ép lên các kiểu dữ liệu có phạm vi giá trị lớn hơn. Ví dụ: một byte có thể được ép lên int, long, float hoặc double.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPgI4Wz2xKpUGSs-ia_xk7uJV4AVLx-tFSy05W-MAXd38Cvsfm4OePZg66trqh1dNu-60fIshyphenhyphenTKcqdFqx4x1sB2r8Z0pCaqLUSFyd8i0wFi_5VzXDIxyqomyEoRK4ob_yejDCcoaMSk1s4msdY4VjKhYHXh702f4p5C6MW34aWGoDAzMMe2_pA4iP6Us/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả cơ chế tự động ép kiểu trong nạp chồng phương thức." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEhPgI4Wz2xKpUGSs-ia_xk7uJV4AVLx-tFSy05W-MAXd38Cvsfm4OePZg66trqh1dNu-60fIshyphenhyphenTKcqdFqx4x1sB2r8Z0pCaqLUSFyd8i0wFi_5VzXDIxyqomyEoRK4ob_yejDCcoaMSk1s4msdY4VjKhYHXh702f4p5C6MW34aWGoDAzMMe2_pA4iP6Us%2Fw640-h360%2Fimage.png" title="Ảnh mô tả cơ chế tự động ép kiểu trong nạp chồng phương thức." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span&gt;Ảnh mô tả cơ chế tự động ép kiểu trong nạp chồng phương thức.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;span&gt;&lt;br&gt;&lt;/span&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Ví dụ 1: Java sẽ tự động ép kiểu trước khi thực hiện phép cộng.&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;b class="syntax-title"&amp;gt;Example.java&amp;lt;/b&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;pre&gt;&lt;code&gt;public class Example {

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Phương thức nạp chồng với một số thực và một số nguyên
public void sum(double a,long b) {
    System.out.println("Tổng một số thực và một số nguyên: " + (a + b));
    }
// Phương thức nạp chồng với một số nguyên và một số thực
public void sum(double a, double b,double c) {
    System.out.println("Tổng ba số thực: " + (a + b + c));
}

public static void main(String[] args) {
    Example example = new Example();
    //Java sẽ tự động nâng cấp biến b lên kiểu double trước khi thực hiện phép cộng.
    example.sum(10,10);
    example.sum(10, 10, 10);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Tổng một số thực và một số nguyên: 20.0&lt;br&gt;
Tổng ba số thực: 30.0&lt;/code&gt;&lt;/pre&gt;



&lt;h4&gt;&lt;span&gt;Trong trường hợp này:&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Biến b kiểu long có phạm vi hẹp hơn so với biến a kiểu double.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Khi thực hiện phép cộng a + b, Java sẽ tự động nâng cấp biến b lên kiểu double trước khi thực hiện phép cộng.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Kết quả của phép cộng sẽ là một số có kiểu double.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Ví dụ 2: Nạp chồng hai phương thức những có kiểu đối số khác nhau&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;br&gt;
      &lt;b&gt;Example.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;public class Example {

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Phương thức nạp chồng với hai int
public void sum(int a, int b) {
    System.out.println("Tổng của 2 số int : " + (a + b));
}
// Phương thức nạp chồng với hai long
public void sum(long a, long b) {
    System.out.println("Tổng của 2 số long: " + (a + b));
}
public static void main(String[] args) {
    Example example = new Example();
  // phương thứ sum() có đối số int sẽ được gọi 
    example.sum(10, 10);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Tổng của 2 số int: 20 &lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong trường hợp này, phương thức sum(int a, int b) sẽ được gọi vì các đối số 10 và 10 đều là int và khớp chính xác với phương thức sum đầu tiên.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Lưu ý:&lt;/span&gt;&lt;span&gt; Nếu bạn gọi example.sum(10, 20L), với 20L là một số long, thì phương thức sum(long a, long b) sẽ được gọi vì đối số thứ hai là kiểu long.&lt;/span&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;b class="syntax-title"&amp;gt;Example.java&amp;lt;/b&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;pre&gt;&lt;code&gt;public class Example {

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Phương thức nạp chồng với hai int
public void sum(int a, int b) {
    System.out.println("Tổng của 2 số int: " + (a + b));
}
    // Phương thức nạp chồng với hai long
    public void sum(long a, long b) {
        System.out.println("Tổng của 2 số long: " + (a + b));
    }
public static void main(String[] args) {
    Example example = new Example();
    // phương thứ sum() có đối số long sẽ được gọi 
    example.sum(10, 10L);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Tổng của 2 số long: 20&lt;/code&gt;&lt;/pre&gt;


&lt;h3&gt;&lt;span&gt;&lt;b&gt;Ví dụ 3: Nạp chồng hai phương thức tổng một số nguyên một số thực và ngược lại&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;b class="syntax-title"&amp;gt;Example.java&amp;lt;/b&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;pre&gt;&lt;code&gt;public class Example {

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Phương thức nạp chồng với một số thực và một số nguyên
public void sum(double  a, int b) {
    System.out.println("Tổng một số thực và một số nguyên: " + (a + b));
    }
// Phương thức nạp chồng với một số nguyên và một số thực
public void sum(int a, double b) {
    System.out.println("Tổng một số nguyên và một số thực: " + (a + b));
}

public static void main(String[] args) {
    Example example = new Example();
    example.sum(10,10);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Exception in thread "main" java.lang.Error: Unresolved compilation problem: The method sum(double, int) is ambiguous for the type Example at Example.main(Example.java:14)&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong trường hợp này, vì cả hai phương thức đều yêu cầu một ép kiểu tương tự (ép int thành double), không có sự ưu tiên rõ ràng dựa trên độ chính xác của kiểu. Trong các trường hợp mâu thuẫn như vậy, trình biên dịch sẽ báo lỗi vì không thể quyết định rõ ràng phương thức nào cần gọi.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Lưu ý: &lt;/span&gt;&lt;span&gt;Nếu bạn gọi example.sum(10d, 20), với 10d là một số thực, thì phương thức sum(double a, int b) sẽ được gọi vì đối số thứ nhất là kiểu double.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Lưu ý: &lt;/span&gt;&lt;span&gt;Trong Java, một kiểu dữ liệu không thể tự động ép kiểu sang một kiểu dữ liệu nhỏ hơn. Cụ thể, kiểu double không thể tự động ép kiểu sang bất kỳ kiểu nào khác như float, long, int, short, hay byte. Điều này là do việc ép kiểu từ một kiểu lớn hơn sang kiểu nhỏ hơn có thể dẫn đến mất mát dữ liệu và cần phải được thực hiện rõ ràng bằng cách sử dụng ép kiểu tường minh (explicit casting).&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;2. Nạp chồng Constructor (Constructor Overloading)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;↳ Định nghĩa:&lt;/span&gt;&lt;span&gt; Là khả năng định nghĩa nhiều hàm tạo có cùng tên trong một lớp, nhưng khác nhau về số lượng hoặc kiểu dữ liệu của các tham số. Nạp chồng constructor đã được chúng tôi trình bày chi tiết trong phần về Constructor.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;Tại sao cần nạp chồng hàm tạo?&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;↳ Khởi tạo đối tượng linh hoạt: &lt;/span&gt;&lt;span&gt;Cho phép tạo đối tượng với các giá trị ban đầu khác nhau, tùy thuộc vào yêu cầu của từng trường hợp sử dụng.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tăng tính đọc hiểu: &lt;/span&gt;&lt;span&gt;Làm cho code dễ đọc và dễ hiểu hơn, đặc biệt khi có nhiều cách khác nhau để khởi tạo một đối tượng.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Hỗ trợ các kiểu thiết kế khác nhau: &lt;/span&gt;&lt;span&gt;Ví dụ, pattern Builder thường sử dụng nạp chồng hàm tạo để xây dựng các đối tượng phức tạp một cách tuần tự.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Dưới đây là ví dụ về nạp chồng hàm tạo với một lớp Book:&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
      &lt;b&gt;Book.java&lt;/b&gt;
    

  &lt;pre&gt;&lt;code&gt;public class Book {
    private String title;
    private String author;
    private double price;

    // Hàm tạo không tham số (default constructor)
    public Book() {
        this.title = "Unknown";
        this.author = "Unknown";
        this.price = 0.0;
    }

    // Hàm tạo với một tham số
    public Book(String title) {
        this.title = title;
        this.author = "Unknown";
        this.price = 0.0;
    }

    // Hàm tạo với hai tham số
    public Book(String title, String author) {
        this.title = title;
        this.author = author;
        this.price = 0.0;
    }

    // Hàm tạo với ba tham số
    public Book(String title, String author, double price) {
        this.title = title;
        this.author = author;
        this.price = price;
    }

    // Phương thức hiển thị thông tin sách
    public void display() {
        System.out.println("Tên sách: " + title);
        System.out.println("Tác giả: " + author);
        System.out.println("Giá: $" + price);
    }

    public static void main(String[] args) {
        // Sử dụng các hàm tạo khác nhau để khởi tạo các đối tượng Book
        Book book1 = new Book();
        Book book2 = new Book("Java Programming");
        Book book3 = new Book("Java Programming", "Java");
        Book book4 = new Book("Java Programming", "Java", 39.99);

        // Hiển thị thông tin các sách
        book1.display();
        book2.display();
        book3.display();
        book4.display();
    }
}&lt;/code&gt;&lt;/pre&gt;
  
   
  &lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;Tên sách: Unknown&lt;br&gt;
Tác giả: Unknown&lt;br&gt;
Giá: $0.0&lt;br&gt;
Tên sách: Java Programming&lt;br&gt;
Tác giả: Unknown&lt;br&gt;
Giá: $0.0&lt;br&gt;
Tên sách: Java Programming&lt;br&gt;
Tác giả: Java&lt;br&gt;
Giá: $0.0&lt;br&gt;
Tên sách: Java Programming&lt;br&gt;
Tác giả: Java&lt;br&gt;
Giá: $39.99&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Như vậy, nạp chồng hàm tạo cho phép tạo các đối tượng với nhiều cách khởi tạo khác nhau tùy thuộc vào tham số được cung cấp.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Lưu ý:&lt;/span&gt;&lt;span&gt; Nạp chồng constructor đã được chúng tôi trình bày chi tiết trong phần về Constructor.&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅲ. Đa hình thời gian chạy (Runtime polymorphism)&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;&lt;b&gt;&lt;a href="https://www.tieushare.com/2026/10/tinh-da-hinh-polymorphism-trong-java.html" rel="noopener noreferrer"&gt;Đa hình thời gian chạy (Runtime polymorphism)&lt;/a&gt;&lt;/b&gt;, hay còn gọi là gọi phương thức động (Dynamic Method Dispatch), là một tính năng quan trọng trong lập trình hướng đối tượng. Nó cho phép các đối tượng của các lớp con khác nhau có thể thực hiện các hành động (phương thức) khác nhau như thể chúng là các đối tượng của lớp cha. Điều này chủ yếu được đạt được thông qua ghi đè phương thức (method overriding).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Nói cách khác, cùng một đoạn mã có thể hoạt động trên các đối tượng khác nhau nhưng lại có hành vi khác nhau tùy thuộc vào kiểu thực tế của đối tượng đó tại thời điểm chạy. Đây là một khía cạnh quan trọng của tính đa hình, giúp các chương trình trở nên linh hoạt và dễ bảo trì hơn.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Trước khi đi sâu vào đa hình thời gian chạy, chúng ta cần hiểu về "Upcasting".&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;1. Upcasting là gì?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Upcasting là việc gán một đối tượng của lớp con vào một biến tham chiếu có kiểu dữ liệu của lớp cha. Nói một cách đơn giản, upcasting là việc bạn gán một đối tượng của một lớp con (subclass) vào một biến tham chiếu có kiểu dữ liệu của lớp cha (superclass).&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Tại sao lại gọi là upcasting?&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Up: &lt;/span&gt;&lt;span&gt;Nghĩa là lên trên.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Casting: &lt;/span&gt;&lt;span&gt;Nghĩa là ép kiểu.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Vì vậy, upcasting nghĩa là "ép kiểu lên trên" trong hệ thống phân cấp lớp. Chúng ta đang "ép" một đối tượng của lớp con lên thành một đối tượng của lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Tại sao upcasting lại hữu ích?&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Đa hình: &lt;/span&gt;&lt;span&gt;Upcasting là cơ sở cho đa hình thời gian chạy. Nó cho phép chúng ta viết các đoạn code chung để xử lý các đối tượng thuộc các lớp khác nhau.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tính trừu tượng: &lt;/span&gt;&lt;span&gt;Upcasting giúp chúng ta tập trung vào các đặc tính chung của các đối tượng, chứ không cần quan tâm đến các chi tiết cụ thể của từng lớp con.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Dễ dàng quản lý: &lt;/span&gt;&lt;span&gt;Upcasting giúp chúng ta quản lý các đối tượng một cách dễ dàng hơn, đặc biệt khi chúng ta có một hệ thống phân cấp lớp phức tạp.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Ví dụ đầu tiên về upcasting&lt;/span&gt;&lt;/h3&gt;
 &lt;b&gt;Ví Dụ&lt;/b&gt;

  &lt;pre&gt;&lt;code&gt;interface I {}   // Giao diện I
class A {}   // Lớp cha A
class B extends A implements I {}   // Lớp con B kế thừa từ A và implement giao diện I&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;&lt;span&gt;&lt;b&gt;Các mối quan hệ lớp:&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ B IS-A A: &lt;/span&gt;&lt;span&gt;Lớp B kế thừa từ lớp A, do đó B "là một loại" của A.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ B IS-A I: &lt;/span&gt;&lt;span&gt;Lớp B implements interface I, do đó B "là một loại" thỏa mãn các yêu cầu của I.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ B IS-A Object: &lt;/span&gt;&lt;span&gt;Tất cả các lớp trong Java đều kế thừa trực tiếp hoặc gián tiếp từ lớp Object, vì vậy B cũng "là một loại" của Object.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Hãy xem xét một ví dụ cụ thể để giúp bạn hiểu rõ hơn về upcasting và mối quan hệ với đa hình thời gian chạy trong Java:&lt;/span&gt;&lt;/h3&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Giả sử chúng ta có các lớp sau:&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
      &lt;b&gt;Ví Dụ&lt;/b&gt;


  &lt;pre&gt;&lt;code&gt;class Animal {
    void sound() {
        System.out.println("Con vật phát ra âm thanh");
    }
}

class Dog extends Animal {
    void sound() {
        System.out.println("Chú Chó sủa gâu...gâu...");
    }

    void play() {
        System.out.println("Chú chó chơi trò nhặt đồ");
    }
}&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Bây giờ, chúng ta sẽ sử dụng upcasting để tạo một đối tượng của lớp Dog và gán cho một biến tham chiếu của lớp Animal:&lt;/span&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;b class="syntax-title"&amp;gt;Example.java&amp;lt;/b&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;pre&gt;&lt;code&gt;public class Example {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        Animal animal = new Dog(); // Upcasting&lt;br&gt;
        animal.sound(); // Phương thức sound() của lớp Dog được gọi&lt;br&gt;&lt;br&gt;
    }&lt;br&gt;
}&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Chú Chó sủa gâu...gâu...&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Tuy nhiên, không thể gọi animal.play(); vì biến animal chỉ được coi là Animal, và không biết đối tượng thực tế là Dog.&lt;/span&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;b class="syntax-title"&amp;gt;Example.java&amp;lt;/b&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;pre&gt;&lt;code&gt;public class Example {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        Animal animal = new Dog(); // Upcasting

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    animal.play(); // Lỗi biên dịch, vì phương thức play() không tồn tại trong Animal

    // Vì biến tham chiếu là Animal, nên không thể gọi các phương thức hay thuộc tính chỉ có trong Dog
    // Tuy nhiên, nếu animal thực sự là đối tượng của Dog thì các phương thức của Dog sẽ được thực thi khi chạy
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Exception in thread "main" java.lang.Error: Unresolved compilation problem: The method play() is undefined for the type Animal at Example.main(Example.java:22)&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Tuy nhiên, để truy cập các phương thức và thuộc tính đặc biệt của lớp con, chúng ta cần sử dụng downcasting.&lt;/span&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;b class="syntax-title"&amp;gt;Example.java&amp;lt;/b&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;pre&gt;&lt;code&gt;public class Example {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        Animal animal = new Dog(); // Upcasting&lt;br&gt;
        animal.sound(); // Phương thức sound() của lớp Dog được gọi

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Nếu cần truy cập các phương thức đặc biệt của Dog hoặc Cat, ta cần downcasting
    Dog dog = (Dog) animal; // Downcasting an toàn
    dog.play(); // Đây là cách sử dụng phương thức run() của lớp Dog sau khi downcasting
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Chú Chó sủa gâu...gâu...&lt;br&gt;
Chú chó chơi trò nhặt đồ&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;↳ Lưu ý: &lt;/span&gt;&lt;span&gt;Trong downcasting (Dog dog = (Dog) animal;), biến animal được coi là Dog tạm thời để có thể gọi phương thức play() của lớp Dog.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;2. Ghi đè phương thức (Method Overriding)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;&lt;b&gt;&lt;a href="https://www.tieushare.com/2026/10/tinh-da-hinh-polymorphism-trong-java.html" rel="noopener noreferrer"&gt;Ghi đè phương thức (Method Overriding) &lt;/a&gt;&lt;/b&gt;là quá trình một lớp con cung cấp triển khai (implementation) lại một phương thức đã được định nghĩa trong lớp cha của nó. Khi lớp con ghi đè một phương thức của lớp cha, nó cung cấp một triển khai mới cho phương thức đó, thay thế triển khai mặc định của lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Trong Java, bạn có thể ghi đè (override) các phương thức của lớp cha trong lớp con nhưng không thể ghi đè các biến trường (fields), constructors và static methods. Dưới đây là các điểm quan trọng cần nhớ:&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;&lt;b&gt;1. Ghi đè phương thức (Method overriding):&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Cho phép lớp con cung cấp một triển khai mới cho một phương thức đã được định nghĩa trong lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Các phương thức ghi đè phải có cùng tên, cùng số lượng đối số và cùng kiểu trả về như phương thức mà nó ghi đè.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Cung cấp tính đa hình và cho phép lập trình linh hoạt hơn.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;&lt;b&gt;2. Không thể ghi đè các biến trường (fields):&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Các biến trường (instance variables) trong lớp cha không thể được ghi đè trong lớp con.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Lớp con có thể sử dụng các biến trường của lớp cha nếu chúng được khai báo là protected hoặc public, nhưng không thể thay đổi giá trị của chúng.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;&lt;b&gt;3. Không thể ghi đè constructors:&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Constructors (hàm khởi tạo) không được phép ghi đè trong Java.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Lớp con có thể gọi hàm khởi tạo của lớp cha bằng cách sử dụng super() nhưng không thể thay đổi hoặc ghi đè chúng.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;&lt;b&gt;4. Không thể ghi đè static methods:&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Static methods (phương thức tĩnh) không thể được ghi đè trong Java.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Chúng không liên quan đến đối tượng cụ thể nào mà liên quan đến lớp chứa chúng, do đó không thể thay đổi hoặc ghi đè chúng từ các lớp con.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Ví dụ về đơn kế thừa trong Java khi sử dụng ghi đè phương thức (method overriding):&lt;/span&gt;&lt;/h3&gt;
      &lt;b&gt;Example.java&lt;/b&gt;

  &lt;pre&gt;&lt;code&gt;// Lớp cha Person
class Person {
    String name;
    int age;

    // Constructor của lớp Person
    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Phương thức in thông tin
    void displayInfo() {
        System.out.println("Tên: " + name);
        System.out.println("Tuổi: " + age);
    }
}

// Lớp con Student kế thừa từ lớp Person
class Student extends Person {
    String major;

    // Constructor của lớp Student
    Student(String name, int age, String major) {
        super(name, age); // Gọi constructor của lớp cha
        this.major = major;
    }

    // Ghi đè phương thức displayInfo từ lớp cha
    @Override
    void displayInfo() {
        super.displayInfo(); // Gọi phương thức của lớp cha
        System.out.println("Chuyên Ngành: " + major);
    }
}

// Class Example sử dụng lớp Student
public class Example {
    public static void main(String[] args) {
        Student student = new Student("Vương", 20, "Lập trình");
        student.displayInfo(); // Gọi phương thức displayInfo của Student
    }
}&lt;/code&gt;&lt;/pre&gt;
  
   
  &lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;Tên: Vương&lt;br&gt;
Tuổi: 20&lt;br&gt;
Chuyên Ngành: Lập trình&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Đoạn code, trên ví dụ cơ bản về đơn kế thừa và ghi đè phương thức trong Java, cho thấy cách mà lớp con có thể mở rộng và thay đổi hành vi của lớp cha theo nhu cầu của nó.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Ví dụ về kế thừa nhiều cấp trong Java khi sử dụng ghi đè phương thức (method overriding):&lt;/span&gt;&lt;/h3&gt;
      &lt;b&gt;Example.java&lt;/b&gt;


  &lt;pre&gt;&lt;code&gt;// Lớp cơ bản Vehicle
class Vehicle {
    void display() {
        System.out.println("Đây là một phương tiện.");
    }
}

// Lớp Car kế thừa từ Vehicle
class Car extends Vehicle {
    @Override
    void display() {
        System.out.println("Đây là một chiếc ô tô.");
    }
}

// Lớp SportsCar kế thừa từ Car
class SportsCar extends Car {
    @Override
    void display() {
        System.out.println("Đây là một chiếc xe thể thao.");
    }
}

// Lớp Example sử dụng các lớp trên
public class Example {
    public static void main(String[] args) {
        Vehicle vehicle = new Vehicle();
        vehicle.display(); // In ra: Đây là một phương tiện.

        Vehicle car = new Car();
        car.display(); // In ra: Đây là một chiếc ô tô.

        Vehicle sportsCar = new SportsCar();
        sportsCar.display(); // In ra: Đây là một chiếc xe thể thao.
    }
}&lt;/code&gt;&lt;/pre&gt;
  
   
  &lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;Đây là một phương tiện.&lt;br&gt;
Đây là một chiếc ô tô.&lt;br&gt;
Đây là một chiếc xe thể thao.&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Khi chạy ví dụ trên, các phương thức display được gọi tương ứng với đối tượng thực tế mà biến tham chiếu đang trỏ đến, cho phép ta thấy được tính đa hình trong hành vi của các đối tượng kế thừa nhiều cấp trong Java.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Ví dụ về kế thừa thứ bậc trong Java khi sử dụng ghi đè phương thức (method overriding):&lt;/span&gt;&lt;/h3&gt;

      &lt;b&gt;Example.java&lt;/b&gt;


  &lt;pre&gt;&lt;code&gt;// Lớp cơ bản Bank
class Bank {
    protected double SoDu; // Số dư trong tài khoản

    public Bank(double SoDu) {
        this.SoDu = SoDu;
    }

    // Phương thức tính lãi suất
    public double TinhLaiXuat() {
        return 0; // Mặc định không có lãi suất
    }

    public void display() {
        System.out.println("Số dư trong tài khoản là: " + SoDu);
    }
}

// Lớp con ABCBank kế thừa từ Bank
class ABCBank extends Bank {
    public ABCBank(double SoDu) {
        super(SoDu); 
    }

    // Ghi đè phương thức TinhLaiXuat để tính lãi suất cho tài khoản tiết kiệm
    @Override
    public double TinhLaiXuat() {
        return SoDu * 0.05;
    }
    // Ghi đè phương thức display để hiển thị lãi xuất hằng năm
    @Override
    public void display() {
        System.out.println("Lãi xuất hàng nằm của ABCBank: " + TinhLaiXuat());
    }
}

// Lớp con DEFBank kế thừa từ Bank
class DEFBank extends Bank {
    public DEFBank(double SoDu) {
        super(SoDu);
    }

    // Ghi đè phương thức TinhLaiXuat để tính lãi suất cho tài khoản tiết kiệm
    @Override
    public double TinhLaiXuat() {
        return SoDu * 0.06;
    }

    // Ghi đè phương thức display để hiển thị lãi xuất hằng năm
    @Override
    public void display() {
        System.out.println("Lãi xuất hàng nằm của DEFBank: " + TinhLaiXuat());
    }
}

// Lớp con IGHBank kế thừa từ Bank
class IGHBank extends Bank {
    public IGHBank(double SoDu) {
        super(SoDu);
    }

    // Ghi đè phương thức TinhLaiXuat để tính lãi suất cho tài khoản tiết kiệm
    @Override
    public double TinhLaiXuat() {
        return SoDu * 0.07;
    }

    // Ghi đè phương thức display để hiển thị lãi xuất hằng năm
    @Override
    public void display() {
        System.out.println("Lãi xuất hàng nằm của IGHBank: " + TinhLaiXuat());
    }
}

// Lớp Example sử dụng các lớp trên
public class Example {
    public static void main(String[] args) {
        ABCBank abcbank = new ABCBank(2000000);
        abcbank.display();

        DEFBank defbank = new DEFBank(3000000);
        defbank.display();

        IGHBank ighbank = new IGHBank(1000000);
        ighbank.display();
    }
}&lt;/code&gt;&lt;/pre&gt;
  
   
  &lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;Lãi xuất hàng nằm của ABCBank: 100000.0&lt;br&gt;
Lãi xuất hàng nằm của DEFBank: 180000.0&lt;br&gt;
Lãi xuất hàng nằm của IGHBank: 70000.0&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Khi chạy ví dụ trên, các phương thức display được gọi tương ứng với đối tượng thực tế mà biến tham chiếu đang trỏ đến, cho phép ta thấy được tính đa hình trong hành vi của các đối tượng kế thừa thứ bậc trong Java.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Lưu ý khi ghi đè phương thức trong kế thừa&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Khi ghi đè phương thức trong kế thừa, việc tuân thủ các quy tắc và nguyên tắc nhất định sẽ giúp code của bạn rõ ràng, dễ bảo trì và tránh các lỗi không mong muốn. Dưới đây là một số lưu ý quan trọng:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Quy tắc cơ bản:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tên phương thức: &lt;/span&gt;&lt;span&gt;Phải hoàn toàn giống với phương thức trong lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tham số: &lt;/span&gt;&lt;span&gt;Số lượng và kiểu dữ liệu của các tham số phải giống hệt.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Kiểu trả về: &lt;/span&gt;&lt;span&gt;Kiểu trả về của phương thức con phải giống hoặc là kiểu con của kiểu trả về trong lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Quyền truy cập: &lt;/span&gt;&lt;span&gt;Quyền truy cập của phương thức con không thể hẹp hơn quyền truy cập của phương thức trong lớp cha (ví dụ: nếu phương thức trong lớp cha là public thì phương thức trong lớp con cũng phải là public hoặc protected).&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Hãy cùng so sánh chi tiết giữa nạp chồng phương thức (Overloading) và ghi đè phương thức (Overriding) nhé:&lt;/span&gt;&lt;/h3&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tính năng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;span&gt;Nạp Chồng Phương Thức&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;(Overloading)&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;span&gt;Ghi Đè Phương Thức&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;(Overriding)&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Mục đích&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Cung cấp nhiều phiên bản của cùng một phương thức trong cùng một lớp, với các danh sách tham số khác nhau.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Cho phép lớp con định nghĩa lại một phương thức đã có sẵn trong lớp cha.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tên phương thức&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Cùng tên.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Cùng tên.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tham số&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Số lượng hoặc kiểu dữ liệu của tham số khác nhau.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Số lượng và kiểu dữ liệu của tham số giống nhau.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Kiểu trả về&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có thể khác nhau.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có thể giống hoặc là kiểu con của kiểu trả về trong lớp cha.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Quyền truy cập&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có thể khác nhau.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Không thể hẹp hơn quyền truy cập của phương thức trong lớp cha.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Thời điểm quyết định&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tại thời điểm biên dịch.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tại thời điểm chạy.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Mục đích&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tăng tính linh hoạt trong việc sử dụng phương thức, cho phép xử lý các dữ liệu khác nhau với cùng một tên phương thức.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Thực hiện đa hình, cho phép các đối tượng của các lớp con khác nhau thực hiện cùng một hành động theo những cách khác nhau.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Khi nào nên sử dụng:&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Nạp chồng phương thức: &lt;/span&gt;&lt;span&gt;Khi bạn muốn thực hiện cùng một hành động trên các kiểu dữ liệu khác nhau.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Ghi đè phương thức: &lt;/span&gt;&lt;span&gt;Khi bạn muốn tùy chỉnh hành vi của một phương thức trong lớp con để phù hợp với nhu cầu cụ thể.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;

</description>
      <category>tínhđahìnhtrongjava</category>
      <category>polymorphismtrongjava</category>
      <category>tinhdahinhtrongjava</category>
      <category>tieushare</category>
    </item>
    <item>
      <title>Từ khóa super (super Keywords) trong Java | Cách Sử Dụng và Ví Dụ Chi Tiết</title>
      <dc:creator>Tiểu Share</dc:creator>
      <pubDate>Mon, 09 Nov 2026 03:49:50 +0000</pubDate>
      <link>https://dev.to/tieushare/tu-khoa-super-super-keywords-trong-java-cach-su-dung-va-vi-du-chi-tiet-48ie</link>
      <guid>https://dev.to/tieushare/tu-khoa-super-super-keywords-trong-java-cach-su-dung-va-vi-du-chi-tiet-48ie</guid>
      <description>&lt;p&gt;&lt;span id="docs-internal-guid-be4203f9-7fff-f747-9921-d6826dfdffd6"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-9a0c46d8-7fff-4194-8386-5551e2d89503"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;"Trong Java, &lt;/span&gt;&lt;span&gt;&lt;b&gt;&lt;a href="https://www.tieushare.com/2026/10/tu-khoa-super-trong-java.html" rel="noopener noreferrer"&gt;từ khóa super&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;span&gt; là một công cụ quan trọng trong lập trình hướng đối tượng, cho phép một lớp con truy cập trực tiếp vào các thành phần của lớp cha. Điều này giúp bạn mở rộng chức năng một cách linh hoạt và tái sử dụng mã nguồn hiệu quả. Dưới đây là những điều cơ bản bạn cần biết về từ khóa super trong Java."&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Trong lập trình hướng đối tượng của Java, super là một từ khóa đặc biệt dùng để truy cập lớp cha (superclass) từ trong một lớp con(subclass). Nó hoạt động như một biến tham chiếu đặc biệt, giúp chúng ta truy cập các thuộc tính và phương thức của lớp cha ngay cả khi lớp con đã định nghĩa lại chúng. Từ khóa super có 3 cách sử dụng như sau:&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;↳ Từ khóa super được sử dụng để tham chiếu trực tiếp đến biến instance của lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Từ khóa super được sử dụng để gọi trực tiếp phương thức của lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Từ khóa super() được sử dụng để gọi trực tiếp Constructor của lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLKIQpbOgB2oJEw8AfeodXQZxlCw6nMU9UrsA8mxgt9I52N2fpcl69jH_8scVVFMXt78YZL2QsQXyDEVIwz1Xvs9BzfihoDenv75eoNj2AjuFvyv7oi5biyMN2COeG0TbtbDkHKJuVzvXTXSgm7ud0QAWYlyGeovrOpF5JbbRMD6ZYQeyG1LMcLDongXo/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả công dụng của từ khóa Super." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEjLKIQpbOgB2oJEw8AfeodXQZxlCw6nMU9UrsA8mxgt9I52N2fpcl69jH_8scVVFMXt78YZL2QsQXyDEVIwz1Xvs9BzfihoDenv75eoNj2AjuFvyv7oi5biyMN2COeG0TbtbDkHKJuVzvXTXSgm7ud0QAWYlyGeovrOpF5JbbRMD6ZYQeyG1LMcLDongXo%2Fw640-h360%2Fimage.png" title="Ảnh mô tả công dụng của từ khóa Super." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span&gt;Ảnh mô tả công dụng của từ khóa Super.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;span&gt;&lt;br&gt;&lt;/span&gt;
&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅰ. Từ khóa super được sử dụng để tham chiếu trực tiếp đến biến instance của lớp cha.&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Nếu lớp con và lớp cha có cùng một thuộc tính, bạn có thể dùng super để truy cập thuộc tính của lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Ví dụ: khi không sử dụng từ khóa super&lt;/span&gt;&lt;/h3&gt;
&lt;br&gt;
&lt;b&gt;Example.java&lt;/b&gt;&lt;br&gt;
  &lt;pre&gt;&lt;code&gt;class SuperClass {&lt;br&gt;
    String Money = "200 USD";&lt;br&gt;
}

&lt;p&gt;class SubClass extends SuperClass {&lt;br&gt;
    String Money = "100 USD";&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void printMoney() {
    // khi sử dụng từ khóa super
    System.out.println("Money của lớp con: "+ Money); 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;br&gt;&lt;br&gt;
public class Example {&lt;br&gt;&lt;br&gt;
    public static void main(String args[]) {&lt;br&gt;&lt;br&gt;
        SubClass sub = new SubClass();&lt;br&gt;&lt;br&gt;
        sub.printMoney();&lt;br&gt;&lt;br&gt;
    }&lt;br&gt;&lt;br&gt;
} &lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Money của lớp con: 100 USD &lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;&lt;span&gt;Ví dụ: khi sử dụng từ khóa super&lt;/span&gt;&lt;/h3&gt;
&lt;br&gt;
&lt;b&gt;Example.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;class SuperClass {&lt;br&gt;
    String Money = "200 USD";&lt;br&gt;
}

&lt;p&gt;class SubClass extends SuperClass {&lt;br&gt;
    String Money = "100 USD";&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void printMoney() {
    // khi sử dụng từ khóa super
    System.out.println("Money của lớp con: "+ super.Money); 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;br&gt;&lt;br&gt;
public class Example {&lt;br&gt;&lt;br&gt;
    public static void main(String args[]) {&lt;br&gt;&lt;br&gt;
        SubClass sub = new SubClass();&lt;br&gt;&lt;br&gt;
        sub.printMoney();&lt;br&gt;&lt;br&gt;
    }&lt;br&gt;&lt;br&gt;
} &lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Money của lớp con: 200 USD&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong ví dụ trên, cả hai lớp Superclass và Subclass đều có biến thể hiện (biến instance) chung là money. Nếu chúng ta in biến money, nó sẽ in số tiền của từng lớp hiện tại theo mặc định. Để truy cập biến từ lớp cha (Superclass), lớp con (Subclass) cần phải sử dụng từ khóa super.&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅱ. Từ khóa super được sử dụng để gọi trực tiếp phương thức của lớp cha.&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Bạn có thể sử dụng &lt;b&gt;&lt;a href="https://www.tieushare.com/2026/10/tu-khoa-super-trong-java.html" rel="noopener noreferrer"&gt;từ khóa super để gọi các phương thức được định nghĩa trong lớp cha&lt;/a&gt;&lt;/b&gt;, ngay cả khi chúng đã được ghi đè trong lớp con. Điều này cho phép bạn gọi trực tiếp phương thức của lớp cha từ lớp con, giúp truy cập và sử dụng các hành vi của lớp cha mà không bị ảnh hưởng bởi các phương thức đã được ghi đè.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Dưới đây là một ví dụ minh họa việc sử dụng từ khóa super để gọi phương thức của lớp cha từ lớp con:&lt;/span&gt;&lt;/h3&gt;
&lt;br&gt;
&lt;b&gt;Example.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;class SuperClass {&lt;br&gt;
    void Message() {&lt;br&gt;
        System.out.println("Xin chào, đây là Phương thức Message() của lớp cha");&lt;br&gt;
    }&lt;br&gt;
}

&lt;p&gt;class SubClass extends SuperClass {&lt;br&gt;
    void Message() {&lt;br&gt;
        System.out.println("Xin chào, đây là Phương thức Message() của lớp con");&lt;br&gt;
    }&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void display() {
    Message();
    super.Message();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;br&gt;&lt;br&gt;
public class Example {&lt;br&gt;&lt;br&gt;
    public static void main(String args[]) {&lt;br&gt;&lt;br&gt;
        SubClass sub = new SubClass();&lt;br&gt;&lt;br&gt;
        sub.display();&lt;br&gt;&lt;br&gt;
    }&lt;br&gt;&lt;br&gt;
} &lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Xin chào, đây là Phương thức Message() của lớp con&lt;br&gt;
Xin chào, đây là Phương thức Message() của lớp cha&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;&lt;span&gt;Lưu ý:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Bạn không thể sử dụng từ khóa super trong một phương thức tĩnh (static method). Lý do là bởi vì các phương thức tĩnh thuộc về lớp, không thuộc về đối tượng (instance) của lớp. Từ khóa super được sử dụng để tham chiếu đến lớp cha của đối tượng hiện tại, do đó không thể sử dụng trong ngữ cảnh của một phương thức tĩnh.&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅲ. Từ khóa super() được sử dụng để gọi trực tiếp constructor của lớp cha.&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;&lt;b&gt;&lt;a href="https://www.tieushare.com/2026/10/tu-khoa-super-trong-java.html" rel="noopener noreferrer"&gt;Từ khóa super&lt;/a&gt;&lt;/b&gt; thường được sử dụng trong lớp con để gọi hàm khởi tạo của lớp cha. Điều này rất quan trọng khi bạn muốn đảm bảo rằng các thành phần của lớp cha được khởi tạo đúng cách trước khi tiếp tục khởi tạo các thành phần của lớp con.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Quy tắc bắt buộc: &lt;/span&gt;&lt;span&gt;Khi sử dụng super() để gọi constructor của lớp cha, nó phải là lệnh gọi đầu tiên trong constructor của lớp con.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Lý do: &lt;/span&gt;&lt;span&gt;Constructor của lớp cha sẽ được gọi để khởi tạo các thuộc tính kế thừa trước khi lớp con tiến hành khởi tạo các thuộc tính riêng.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Main.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;class Hinh {&lt;br&gt;
    String ten;&lt;br&gt;
    String mauSac;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hinh(String ten, String mauSac) {
    this.ten = ten;
    this.mauSac = mauSac;
    System.out.println("constructor của lớp cha(Hinh)");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;class HinhChuNhat extends Hinh {&lt;br&gt;
    int chieuDai;&lt;br&gt;
    int chieuRong;&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HinhChuNhat(String ten, String mauSac, int chieuDai, int chieuRong) {
    // Gọi constructor của lớp cha để khởi tạo tên và màu sắc
    super(ten, mauSac);
    this.chieuDai = chieuDai;
    this.chieuRong = chieuRong;
    System.out.println("constructor của lớp con(HinhChuNhat)");
}
void display(){
    System.out.println("Tên hình: " + ten);
    System.out.println("Màu sắc: " + mauSac);
    System.out.println("Chiều dài: " + chieuDai);
    System.out.println("Chiều rộng: " + chieuRong);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;br&gt;&lt;br&gt;
public class Main {&lt;br&gt;&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;&lt;br&gt;
        HinhChuNhat hinh = new HinhChuNhat("Hình chữ nhật", "Đỏ", 10, 5);&lt;br&gt;&lt;br&gt;
        hinh.display();&lt;br&gt;&lt;br&gt;
    }&lt;br&gt;&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;constructor của lớp cha(Hinh)&lt;br&gt;
constructor của lớp con(HinhChuNhat)&lt;br&gt;
Tên hình: Hình chữ nhật&lt;br&gt;
Màu sắc: Đỏ&lt;br&gt;
Chiều dài: 10&lt;br&gt;
Chiều rộng: 5&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong ví dụ trên minh họa cách sử dụng từ khóa super để gọi constructor của lớp cha từ constructor của lớp con, đảm bảo rằng các thuộc tính được thừa kế từ lớp cha được khởi tạo đúng cách. Phương thức display() sau đó hiển thị thông tin của đối tượng HinhChuNhat.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Trong Java, nếu bạn không cung cấp bất kỳ constructor nào trong lớp con, thì trình biên dịch sẽ tự động thêm một constructor mặc định và gọi super() để gọi constructor mặc định của lớp cha. Điều này đảm bảo rằng lớp cha được khởi tạo đúng cách trước khi lớp con khởi tạo.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;↳ Dưới đây là một ví dụ cụ thể minh họa điều này:&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;br&gt;
&lt;b&gt;Example.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;// Lớp cha (SuperClass)&lt;br&gt;
class SuperClass {&lt;br&gt;
    // Constructor mặc định của SuperClass&lt;br&gt;
    SuperClass() {&lt;br&gt;
        System.out.println("Constructor của SuperClass đã được tạo");&lt;br&gt;
    }&lt;br&gt;
}

&lt;p&gt;// Lớp con (SubClass) không có constructor nào&lt;br&gt;
class SubClass extends SuperClass {&lt;br&gt;
    // Trình biên dịch sẽ tự động thêm constructor mặc định với super()&lt;br&gt;
    /*&lt;br&gt;
    SubClass() {&lt;br&gt;
        super(); // Gọi constructor của SuperClass&lt;br&gt;
        System.out.println("Constructor của SubClass");&lt;br&gt;
    }&lt;br&gt;
    */&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;public class Example {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        // Tạo một đối tượng của SubClass&lt;br&gt;
        SubClass sub = new SubClass();&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Constructor của SuperClass đã được tạo&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Điều này cho thấy rằng super() được trình biên dịch ngầm cung cấp khi không có constructor nào được định nghĩa trong lớp con, đảm bảo rằng lớp cha luôn được khởi tạo trước.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSxnUT1op_LVqqkxLopFc3sB38074io4bKQo8N2U5zddyTiPOthUoOyFKdy2n73lwWRjAsItQzQmsV3HCE0HJGkksCLHcK9eS6dd9M9MBEZoC4OdNzzwfaqzQHhvIYjvIHb3eM-sTr56o28q2wBrkbS9tk2Ja16W7I_OxJryw04t3OYgWn-U2QXw4b0Mk/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả super() được trình biên dịch ngầm cung cấp khi không có constructor trong lớp con." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEhSxnUT1op_LVqqkxLopFc3sB38074io4bKQo8N2U5zddyTiPOthUoOyFKdy2n73lwWRjAsItQzQmsV3HCE0HJGkksCLHcK9eS6dd9M9MBEZoC4OdNzzwfaqzQHhvIYjvIHb3eM-sTr56o28q2wBrkbS9tk2Ja16W7I_OxJryw04t3OYgWn-U2QXw4b0Mk%2Fw640-h360%2Fimage.png" title="Ảnh mô tả super() được trình biên dịch ngầm cung cấp khi không có constructor trong lớp con." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span&gt;Ảnh mô tả super() được trình biên dịch ngầm cung cấp khi không có constructor trong lớp con.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;br&gt;

</description>
      <category>từkhóasupertrongjava</category>
      <category>superkeywordstrongjava</category>
      <category>tukhoasupertrongjava</category>
      <category>tieushare</category>
    </item>
    <item>
      <title>Tính Kế Thừa (Inheritance) Trong Java | Khái Niệm, Cách Dùng Và Ví Dụ</title>
      <dc:creator>Tiểu Share</dc:creator>
      <pubDate>Sun, 08 Nov 2026 10:04:33 +0000</pubDate>
      <link>https://dev.to/tieushare/tinh-ke-thua-inheritance-trong-java-khai-niem-cach-dung-va-vi-du-3ajg</link>
      <guid>https://dev.to/tieushare/tinh-ke-thua-inheritance-trong-java-khai-niem-cach-dung-va-vi-du-3ajg</guid>
      <description>&lt;p&gt;&lt;span id="docs-internal-guid-820ab22c-7fff-513b-8b8b-1b54836b7042"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;"Trong lập trình hướng đối tượng, &lt;b&gt;&lt;a href="https://www.tieushare.com/2026/10/tinh-ke-thua-inheritance-trong-java.html" rel="noopener noreferrer"&gt;tính kế thừa (Inheritance)&lt;/a&gt;&lt;/b&gt; là một nguyên lý quan trọng cho phép một lớp kế thừa các thuộc tính và phương thức từ một lớp khác. Điều này không chỉ giúp tái sử dụng mã nguồn mà còn làm cho việc mở rộng và bảo trì chương trình trở nên dễ dàng hơn. Dưới đây là những điều cơ bản bạn cần biết về tính kế thừa trong Java."&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅰ. &lt;a href="https://www.tieushare.com/2026/10/tinh-ke-thua-inheritance-trong-java.html" rel="noopener noreferrer"&gt;Kế thừa (Inheritance) là gì&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Kế thừa trong java là sự liên quan giữa hai class với nhau, trong đó có class cha (superclass) và class con (subclass). Khi kế thừa class con được hưởng tất cả các phương thức và thuộc tính của class cha. Tuy nhiên, nó chỉ được truy cập các thành viên public và protected của class cha. Nó không được phép truy cập đến thành viên private của class cha.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;Cách truy cập thành viên private của lớp cha (một cách gián tiếp)&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Mặc dù không thể truy cập trực tiếp, nhưng chúng ta có thể truy cập và thay đổi giá trị của thành viên private của lớp cha một cách gián tiếp thông qua các phương thức public hoặc protected mà lớp cha cung cấp.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Sử dụng phương thức getter và setter: Nếu lớp cha cung cấp các phương thức getter và setter cho thành viên private, lớp con có thể sử dụng các phương thức này để đọc và ghi giá trị của thành viên đó.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Sử dụng phương thức protected: Nếu một thành viên được khai báo là protected, nó có thể được truy cập từ trong lớp con hoặc từ các lớp trong cùng một package.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Ý tưởng đằng sau tính kế thừa trong Java là bạn có thể tạo các lớp mới được xây dựng dựa trên các lớp hiện có. Khi kế thừa từ một lớp hiện có, bạn có thể sử dụng lại các phương thức và trường thuộc tính của lớp cha. Hơn nữa, bạn cũng có thể thêm các phương thức và trường thuộc tính mới trong lớp hiện tại của mình.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Kế thừa đại diện cho mối quan hệ IS-A, còn được gọi là mối quan hệ cha-con.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Tại sao sử dụng kế thừa?&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;↳ Tái sử dụng mã (Code Reusability): &lt;/span&gt;&lt;span&gt;Kế thừa giúp bạn tận dụng lại các thuộc tính và phương thức đã được định nghĩa trong lớp cha. Điều này giúp tiết kiệm thời gian và công sức khi xây dựng các lớp mới.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tạo mối quan hệ giữa các lớp: &lt;/span&gt;&lt;span&gt;Mô hình hóa các mối quan hệ "Cha - Con" (IS-A) trong thế giới thực.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tính đa hình (Polymorphism): &lt;/span&gt;&lt;span&gt;Kế thừa là nền tảng cho tính đa hình, cho phép các đối tượng của các lớp con phản hồi cùng một phương thức theo cách riêng của chúng.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Các thuật ngữ trong kế thừa&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;↳ Lớp cha (Superclass hoặc Parentclass): &lt;/span&gt;&lt;span&gt;Lớp mà các thuộc tính và phương thức được kế thừa.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Lớp con (Subclass hoặc Childclass): &lt;/span&gt;&lt;span&gt;Lớp kế thừa các thuộc tính và phương thức từ lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Từ khóa extends: &lt;/span&gt;&lt;span&gt;Trong Java, từ khóa extends được sử dụng để chỉ rõ một lớp kế thừa từ lớp khác.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Phương thức ghi đè (Overriding): &lt;/span&gt;&lt;span&gt;Lớp con định nghĩa lại một phương thức đã có trong lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Phương thức nạp chồng (Overloading): &lt;/span&gt;&lt;span&gt;Cùng một tên phương thức nhưng với các danh sách tham số khác nhau.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Cú pháp của kế thừa trong Java&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Cú pháp để thực hiện kế thừa rất đơn giản:&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Cú Pháp&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;class LớpCon extends LớpCha {&lt;br&gt;
    // Các thuộc tính và phương thức của lớp con&lt;br&gt;
  }&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong đó:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ LớpCon: &lt;/span&gt;&lt;span&gt;Tên của lớp con.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ extends: &lt;/span&gt;&lt;span&gt;Từ khóa chỉ ra rằng lớp con đang kế thừa từ lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ LớpCha: &lt;/span&gt;&lt;span&gt;Tên của lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Các kiểu kế thừa trong java&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Chúng ta có thể phân loại kế thừa trong Java như sau:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;b&gt;1. Các kiểu kế thừa theo lớp&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Đơn kế thừa (Single Inheritance)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Kế thừa đa cấp (Multilevel Inheritance)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Kế thừa phân cấp (Hierarchical Inheritance)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;b&gt;2. Các kiểu kế thừa theo interface&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Đa kế thừa (Multiple Inheritance)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Kế thừa hỗn hợp (Hybrid Inheritance)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTMJ0AyyXi6uw2bf7tqLpYB0obDD4qwCfR8MqgeAms6nV7vPfvl7S2p-2tnV0icTVf9F_p6kQqcv_eWFxZzGLFQMWzT8cGTGrcLJCsopHtNQfFq2g5rBtMqSPMq67-9bZio2wMG_dNDlaqbxb9L3cKqOH1gHmxfMIhGIzURGXhOqh4zB-v6mdl1yd1S7I/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả các loại kế thừa trong Java." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEhTMJ0AyyXi6uw2bf7tqLpYB0obDD4qwCfR8MqgeAms6nV7vPfvl7S2p-2tnV0icTVf9F_p6kQqcv_eWFxZzGLFQMWzT8cGTGrcLJCsopHtNQfFq2g5rBtMqSPMq67-9bZio2wMG_dNDlaqbxb9L3cKqOH1gHmxfMIhGIzURGXhOqh4zB-v6mdl1yd1S7I%2Fw640-h360%2Fimage.png" title="Ảnh mô tả các loại kế thừa trong Java." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span&gt;Ảnh mô tả các loại kế thừa trong Java.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;span&gt;&lt;br&gt;&lt;/span&gt;
&lt;p&gt;&lt;span&gt;Chúng ta sẽ thảo luận về các kiểu kế thừa theo lớp trong phần này. Các kiểu kế thừa thông qua interface sẽ được trình bày chi tiết trong phần về interface.&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅱ. Đơn kế thừa (Single Inheritance)&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;↳ Định nghĩa: &lt;/span&gt;&lt;span&gt;Một lớp chỉ có thể kế thừa từ một lớp cha duy nhất. Đây là kiểu kế thừa phổ biến nhất trong Java.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuClwGemzOk4G3LnYwjdCdmPpsUtpqHeVlGDp-GcX6BY6MPiB_fGKe30DkhkHXpHXBUYdSm3yr2h2b6p7EYPKCrM7e5Xu7OSZVEakeclUi6jUDq4BopOpU_kDbJLeB5nm2rbInJggqUK8w7VvGi5M2yDWV7HrO6T5WhRl-o8MlFpfgBUPIzJwOmnRtsmo/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả đơn kế thừa (Single Inheritance)." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEhuClwGemzOk4G3LnYwjdCdmPpsUtpqHeVlGDp-GcX6BY6MPiB_fGKe30DkhkHXpHXBUYdSm3yr2h2b6p7EYPKCrM7e5Xu7OSZVEakeclUi6jUDq4BopOpU_kDbJLeB5nm2rbInJggqUK8w7VvGi5M2yDWV7HrO6T5WhRl-o8MlFpfgBUPIzJwOmnRtsmo%2Fw640-h360%2Fimage.png" title="Ảnh mô tả đơn kế thừa (Single Inheritance)." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span&gt;Ảnh mô tả đơn kế thừa (Single Inheritance).&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;


&lt;p&gt;&lt;b&gt;Example.java&lt;/b&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;// Lớp cha Hinh&lt;br&gt;
class Hinh {&lt;br&gt;
    String Mau;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp Hinh
public Hinh(String Mau) {
    this.Mau = Mau;
}

// Phương thức để hiển thị Màu của hình
public void display() {
    System.out.println("Màu: " + Mau);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// Lớp con HinhTron kế thừa từ lớp Hinh&lt;br&gt;
class HinhTron extends Hinh {&lt;br&gt;
    double BanKinh;&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp HinhTron
public HinhTron(String Mau, double BanKinh) {
    super(Mau); // Gọi constructor của lớp cha
    this.BanKinh = BanKinh;
}

// Phương thức để tính diện tích của hình tròn
public double getArea() {
    return Math.PI * BanKinh * BanKinh;
}

// Phương thức để hiển thị thông tin của hình tròn
@Override
public void display() {
    super.display(); // Gọi phương thức display của lớp cha
    System.out.println("Bán Kính Hình Tròn: " + BanKinh);
    System.out.println("Diện Tích Hình Tròn: " + getArea());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// Lớp chính để kiểm tra&lt;br&gt;
public class Example {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        // Tạo đối tượng HinhTron&lt;br&gt;
        HinhTron hinhtron = new HinhTron("Đỏ", 5.0);&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Hiển thị thông tin của hình tròn
    hinhtron.display();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Màu: Đỏ&lt;br&gt;
Bán Kính Hình Tròn: 5.0&lt;br&gt;
Diện Tích Hình Tròn: 78.53981633974483&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong ví dụ trên, minh họa cách lớp HinhTron kế thừa các thuộc tính và phương thức từ lớp Hinh và thêm các tính năng riêng của nó.&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅲ. Kế thừa nhiều cấp (Multilevel Inheritance)&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;↳ Định nghĩa: &lt;/span&gt;&lt;span&gt;Một lớp kế thừa từ một lớp cha, lớp cha này lại kế thừa từ một lớp cha khác và cứ thế. Tạo thành một chuỗi kế thừa nhiều cấp.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2x0abdSPqzU252hKUJWnosDCSUk044SmneMnO0gnPN9_GtkOuEz70W_ryYuIxk3iBtAnmkEQSppzfRC3GJ37Hg1UX1C2e8ovrGHUfaQd4pw6hyScd1_TDP4JFJ2hvA5ZUneE5jsMM4TIT8g-bzI-epdaHxxY1MTsIgUp1sR-V33S6IG17-Y_SQJI2M5Q/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả kế thừa nhiều cấp (Multilevel Inheritance)." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEi2x0abdSPqzU252hKUJWnosDCSUk044SmneMnO0gnPN9_GtkOuEz70W_ryYuIxk3iBtAnmkEQSppzfRC3GJ37Hg1UX1C2e8ovrGHUfaQd4pw6hyScd1_TDP4JFJ2hvA5ZUneE5jsMM4TIT8g-bzI-epdaHxxY1MTsIgUp1sR-V33S6IG17-Y_SQJI2M5Q%2Fw640-h360%2Fimage.png" title="Ảnh mô tả kế thừa nhiều cấp (Multilevel Inheritance)." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span&gt;Ảnh mô tả kế thừa nhiều cấp (Multilevel Inheritance).&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;


&lt;p&gt;&lt;b&gt;Example.java&lt;/b&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;// Lớp cha Hinh&lt;br&gt;
class Hinh {&lt;br&gt;
    String Mau;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp Hinh
public Hinh(String Mau) {
    this.Mau = Mau;
}

// Phương thức để hiển thị Màu của hình
public void display() {
    System.out.println("Màu: " + Mau);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// Lớp con HinhTron kế thừa từ lớp Hinh&lt;br&gt;
class HinhTron extends Hinh {&lt;br&gt;
    double BanKinh;&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp HinhTron
public HinhTron(String Mau, double BanKinh) {
    super(Mau); // Gọi constructor của lớp cha
    this.BanKinh = BanKinh;
}

// Phương thức để tính diện tích của hình tròn
public double getArea() {
    return Math.PI * BanKinh * BanKinh;
}

// Phương thức để hiển thị thông tin của hình tròn
@Override
public void display() {
    super.display(); // Gọi phương thức display của lớp cha
    System.out.println("Bán Kính Hình Tròn: " + BanKinh);
    System.out.println("Diện Tích Hình Tròn: " + getArea());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;}&lt;br&gt;
// Lớp con HinhTru kế thừa từ lớp HinhTron&lt;br&gt;
class HinhTru extends HinhTron {&lt;br&gt;
    double ChieuCao;&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp HinhTru
public HinhTru(String Mau, double BanKinh, double ChieuCao) {
    super(Mau, BanKinh); // Gọi constructor của lớp HinhTron
    this.ChieuCao = ChieuCao;
}

// Phương thức để tính thể tích của hình trụ
public double getVolume() {
    return getArea() * ChieuCao;
}

// Phương thức để hiển thị thông tin của hình trụ
@Override
public void display() {
    super.display(); // Gọi phương thức display của lớp HinhTron
    System.out.println("Chiều cao của Hình Trụ: " + ChieuCao);
    System.out.println("Thể Tích của Hình Trụ " + getVolume());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// Lớp chính để kiểm tra&lt;br&gt;
public class Example {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        // Tạo đối tượng HinhTru&lt;br&gt;
        HinhTru hinhTru = new HinhTru("Đỏ", 5.0,10.0);&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Hiển thị thông tin của hình trụ
    hinhTru.display();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Màu: Đỏ&lt;br&gt;
Bán Kính Hình Tròn: 5.0&lt;br&gt;
Diện Tích Hình Tròn: 78.53981633974483&lt;br&gt;
Chiều cao của Hình Trụ: 10.0&lt;br&gt;
Thể Tích của Hình Trụ 785.3981633974483&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong ví dụ trên, minh họa cách lớp HinhTru kế thừa các thuộc tính và phương thức từ lớp HinhTron, và lớp HinhTron kế thừa từ lớp Hinh, tạo thành một chuỗi kế thừa nhiều cấp.&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅳ. Kế thừa thứ bậc (Hierarchical Inheritance)&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;↳ Định nghĩa: &lt;/span&gt;&lt;span&gt;Nhiều lớp con kế thừa từ cùng một lớp cha.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiu0nXhLbn4GgoNSfgb95hZvC6rrGCV3vGkCkbFstCMsHclkfk47XFRQyu1C5IRJ7MTwtts1v6P-pBc0s1qrlJVL07Uq_jew7zUhpCvpB7bCmrPK_XgW2qiXYtbTC9eRvHF5UgthFSGO1tMrxwFtzSpvI2-tLzjEeyzqFwfsgYaU0jifOnk1wlQ782iN9A/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả kế thừa thứ bậc (Hierarchical Inheritance)." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEiu0nXhLbn4GgoNSfgb95hZvC6rrGCV3vGkCkbFstCMsHclkfk47XFRQyu1C5IRJ7MTwtts1v6P-pBc0s1qrlJVL07Uq_jew7zUhpCvpB7bCmrPK_XgW2qiXYtbTC9eRvHF5UgthFSGO1tMrxwFtzSpvI2-tLzjEeyzqFwfsgYaU0jifOnk1wlQ782iN9A%2Fw640-h360%2Fimage.png" title="Ảnh mô tả kế thừa thứ bậc (Hierarchical Inheritance)." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Ảnh mô tả kế thừa thứ bậc (Hierarchical Inheritance).&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;


&lt;p&gt;&lt;b&gt;Example.java&lt;/b&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;// Lớp cha Hinh&lt;br&gt;
class Hinh {&lt;br&gt;
    String Mau;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp Hinh
public Hinh(String Mau) {
    this.Mau = Mau;
}

// Phương thức để hiển thị Màu của hình
public void display() {
    System.out.println("Màu: " + Mau);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// Lớp con HinhTron kế thừa từ lớp Hinh&lt;br&gt;
class HinhTron extends Hinh {&lt;br&gt;
    double BanKinh;&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp HinhTron
public HinhTron(String Mau, double BanKinh) {
    super(Mau); // Gọi constructor của lớp cha
    this.BanKinh = BanKinh;
}

// Phương thức để tính diện tích của hình tròn
public double getArea() {
    return Math.PI * BanKinh * BanKinh;
}

// Phương thức để hiển thị thông tin của hình tròn
@Override
public void display() {
    super.display(); // Gọi phương thức display của lớp cha
    System.out.println("Bán Kính Hình Tròn: " + BanKinh);
    System.out.println("Diện Tích Hình Tròn: " + getArea());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;}&lt;br&gt;
// Lớp con HinhChuNhat kế thừa từ lớp Hinh&lt;br&gt;
class HinhChuNhat extends Hinh {&lt;br&gt;
    double Dai, Rong;&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp HinhChuNhat
public HinhChuNhat(String Mau, double Dai, double Rong) {
    super(Mau); // Gọi constructor của lớp cha
    this.Dai = Dai;
    this.Rong = Rong;
}

// Phương thức để tính diện tích của hình chữ nhật
public double getArea() {
    return Dai * Rong;
}

// Phương thức để hiển thị thông tin của hình chữ nhật
@Override
public void display() {
    super.display(); // Gọi phương thức display của lớp cha
    System.out.println("chiều dài Hình Chữ Nhật: " + Dai);
    System.out.println("chiều Rộng Hình Chữ Nhật: " + Rong);
    System.out.println("Diện Tích Hình Chữ Nhật: " + getArea());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// Lớp chính để kiểm tra&lt;br&gt;
public class Example {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        // Tạo đối tượng HinhTron&lt;br&gt;
        HinhTron hinhtron = new HinhTron("Tím", 5.0);&lt;br&gt;&lt;br&gt;
        // Hiển thị thông tin của hình tròn&lt;br&gt;
        hinhtron.display();&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    System.out.println();

    // Tạo đối tượng HinhChuNhat
    HinhChuNhat hinhchunhat = new HinhChuNhat("Xanh", 10.0,5.0);  
    // Hiển thị thông tin của hình chữ nhật
    hinhchunhat.display();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Màu: Tím&lt;br&gt;
Bán Kính Hình Tròn: 5.0&lt;br&gt;
Diện Tích Hình Tròn: 78.53981633974483

&lt;/code&gt;&lt;p&gt;&lt;code&gt;Màu: Xanh&lt;br&gt;&lt;br&gt;
chiều dài Hình Chữ Nhật: 10.0&lt;br&gt;&lt;br&gt;
chiều Rộng Hình Chữ Nhật: 5.0&lt;br&gt;&lt;br&gt;
Diện Tích Hình Chữ Nhật: 50.0&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong ví dụ trên, minh họa cách các lớp HinhTron và HinhChuNhat kế thừa các thuộc tính và phương thức từ lớp Hinh và thêm các tính năng riêng của chúng.&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅴ. Tại sao Java không hỗ trợ đa kế thừa trực tiếp qua lớp?&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Java không hỗ trợ đa kế thừa trực tiếp qua lớp để tránh các vấn đề phức tạp và xung đột tiềm ẩn mà đa kế thừa có thể gây ra. Một trong những vấn đề nổi bật nhất là "Diamond Problem" (Vấn đề kim cương), dưới đây là một lý giải chi tiết:&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;a href="https://www.tieushare.com/2026/10/tinh-ke-thua-inheritance-trong-java.html" rel="noopener noreferrer"&gt;Vấn đề kim cương (Diamond Problem)&lt;/a&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Giả sử bạn có 4 lớp: A, B, C, và D.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Lớp B và C đều kế thừa từ lớp A.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Lớp D kế thừa cả lớp B và lớp C.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Trong trường hợp này, lớp D sẽ có hai bản sao của tất cả các phương thức và biến từ lớp A (thông qua lớp B và lớp C). Nếu lớp A có một phương thức, lớp D sẽ không biết chính xác phải sử dụng phiên bản nào của phương thức đó — phiên bản từ B hay từ C? Điều này dẫn đến sự mơ hồ và xung đột.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfG2zeaj4p92bc9lJmGywy0n9z2Ju68sn5cK4N6DurKhIzrOZC4oUQKf6_78fyuEGgd_gMC0QSj8iIh7U_spesqVRZlM2m77rgf6k7rSjKwOLRJXGwbEtksWys9Ra8STF3zgP378sZmMc-WhsAbee2jJIWwf85NkhCKvzL3vnJomV7P9wRsBdl_D622jg/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả vấn đề kim cương (Diamond Problem)." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEgfG2zeaj4p92bc9lJmGywy0n9z2Ju68sn5cK4N6DurKhIzrOZC4oUQKf6_78fyuEGgd_gMC0QSj8iIh7U_spesqVRZlM2m77rgf6k7rSjKwOLRJXGwbEtksWys9Ra8STF3zgP378sZmMc-WhsAbee2jJIWwf85NkhCKvzL3vnJomV7P9wRsBdl_D622jg%2Fw640-h360%2Fimage.png" title="Ảnh mô tả vấn đề kim cương (Diamond Problem)." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span&gt;Ảnh mô tả vấn đề kim cương (Diamond Problem).&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;span&gt;&lt;br&gt;&lt;/span&gt;

&lt;p&gt;&lt;b&gt;Example.java&lt;/b&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;class A {&lt;br&gt;
    void show() {&lt;br&gt;
        System.out.println("Hello from A");&lt;br&gt;
    }&lt;br&gt;
}

&lt;p&gt;class B extends A {&lt;br&gt;
    void show() {&lt;br&gt;
        System.out.println("Hello from B");&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;class C extends A {&lt;br&gt;
    void show() {&lt;br&gt;
        System.out.println("Hello from C");&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// Giả sử Java hỗ trợ đa kế thừa qua các lớp&lt;br&gt;
class D extends B, C {&lt;br&gt;
    // Không rõ phải gọi phương thức show() của B hay C?&lt;/p&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;public class Example {&lt;br&gt;&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;&lt;br&gt;
        D obj = new D();&lt;br&gt;&lt;br&gt;
        obj.show();  // Lỗi: Mơ hồ, không rõ gọi phương thức show() của B hay C&lt;br&gt;&lt;br&gt;
    }&lt;br&gt;&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Exception in thread "main" java.lang.Error: Unresolved compilation problem: at D.main(Example.java:22)&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;&lt;span&gt;Giải pháp thay thế của Java&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Thay vì hỗ trợ đa kế thừa qua các lớp, Java cung cấp hai giải pháp thay thế:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Đa kế thừa qua Interface: Java cho phép một lớp triển khai nhiều interface. Điều này cho phép đa kế thừa mà không gặp phải các vấn đề xung đột của đa kế thừa qua các lớp, vì interface chỉ chứa các phương thức trừu tượng (không có thân phương thức) và không có trạng thái (biến instance).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Sử dụng các lớp trừu tượng (Abstract Classes): Nếu bạn cần chia sẻ một phần của một lớp giữa nhiều lớp khác mà không cần sự trùng lặp hoặc xung đột, bạn có thể sử dụng các lớp trừu tượng và triển khai các lớp cụ thể từ đó.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;

</description>
      <category>tínhkếthừatrongjava</category>
      <category>inheritancetrongjava</category>
      <category>tinhkethuatrongjava</category>
      <category>tieushare</category>
    </item>
    <item>
      <title>Kiểm Soát Quyền Truy Cập (Access Control) Trong Java Là Gì? 4 Phạm Vi Truy Cập</title>
      <dc:creator>Tiểu Share</dc:creator>
      <pubDate>Sat, 07 Nov 2026 14:15:36 +0000</pubDate>
      <link>https://dev.to/tieushare/kiem-soat-quyen-truy-cap-access-control-trong-java-la-gi-4-pham-vi-truy-cap-46ie</link>
      <guid>https://dev.to/tieushare/kiem-soat-quyen-truy-cap-access-control-trong-java-la-gi-4-pham-vi-truy-cap-46ie</guid>
      <description>&lt;p&gt;&lt;span id="docs-internal-guid-86479573-7fff-d4af-1eb2-b0d2c87ecb6e"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;"Trong lập trình hướng đối tượng, Kiểm soát Quyền Truy cập (Access Control) là một tính năng quan trọng trong Java, cho phép bạn xác định các phần tử (biến, phương thức) của một lớp có thể được truy cập từ bên ngoài hoặc từ các lớp khác. Cơ chế này được thực hiện thông qua các Từ khóa Truy cập (Access Modifiers) như private, protected, và public, giúp đảm bảo tính bảo mật và tổ chức mã nguồn hiệu quả. Trong Java, có hai loại điều chỉnh chính:&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;Access Modifiers&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Non-access Modifiers&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;/blockquote&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcsRD8y1Q1x59YrxcZFl7zVs3q-kBU9sWT3kEro2kKwc37t1RXIRH5yPpFnumGuKJh6iK-hmaPkD4LP96TMzOUV1i3fSTdVcTK2pepLpD5fBy8MMliOagqIamte1sLaroVjGlixTvyjo5dha07fGXrMGdLxq64kVMQcHDNbnNiLtXdTjmitGqUFQkUYv4/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả các bộ điều chỉnh (Modifier) trong java." src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEgcsRD8y1Q1x59YrxcZFl7zVs3q-kBU9sWT3kEro2kKwc37t1RXIRH5yPpFnumGuKJh6iK-hmaPkD4LP96TMzOUV1i3fSTdVcTK2pepLpD5fBy8MMliOagqIamte1sLaroVjGlixTvyjo5dha07fGXrMGdLxq64kVMQcHDNbnNiLtXdTjmitGqUFQkUYv4%2Fs1600%2Fimage.png" title="Ảnh mô tả các bộ điều chỉnh (Modifier) trong java." width="800" height="450"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Ảnh mô tả các bộ điều chỉnh (Modifier) trong java.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;span&gt;Trong phần này chúng ta sẽ tìm hiểu về các Access Modifier.&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;&lt;span&gt;&lt;span&gt;Ⅰ. Access Modifiers (Công cụ sửa đổi truy cập)&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;&lt;b&gt;&lt;a href="https://www.tieushare.com/2026/10/kiem-soat-quyen-truy-cap-trong-java.html" rel="noopener noreferrer"&gt;Access Modifiers (Công cụ sửa đổi truy cập) trong Java&lt;/a&gt;&lt;/b&gt; được sử dụng để đặt mức độ truy cập cho các lớp, phương thức, và biến. Java có bốn loại Access Modifiers (Công cụ sửa đổi truy cập) chính:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Public (Công cộng)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Private (Riêng tư)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Protected (Được bảo vệ)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Default (Mặc định hay còn gọi là không có sửa đổi)&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Bảng dưới đây mô tả khả năng truy cập của bốn loại Access Modifiers trong java:&lt;/span&gt;&lt;/h3&gt;
&lt;span id="docs-internal-guid-97f620c7-7fff-acd3-2e98-fa2009f7479f"&gt;


&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col width="auto"&gt;
&lt;col width="70"&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Access Modifiers&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Công cụ sửa đổi truy cập)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Class&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Lớp)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Package&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Cùng Gói)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Subclass&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Lớp Con khác gói)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;World&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Toàn Bộ Chương Trình)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Public&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Công cộng)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Private&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Riêng tư)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;No&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;No&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;No&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Protected&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Được bảo vệ)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;No&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Default&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Mặc định)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;No&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;No&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;&lt;/span&gt;&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1xCpVrvlgQIGQbgltBfjRxwrnKaP5nOOiOMgHBHEgBwLQl6Ue3XInWXIN06dicpdb9ZLpoGVsGKIj5rtEUgVqkv1qeIfSlf2ipKUESI0yqS245IMvWchoUHoOyLrnAYjFEDKVJVP1BOEgDK-tiMEScJs1lEzxwR0BQOyTzdAWU_rxjce8hVtbEml4T4I/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả khả năng truy cập của bốn loại Access Modifiers trong java." src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEg1xCpVrvlgQIGQbgltBfjRxwrnKaP5nOOiOMgHBHEgBwLQl6Ue3XInWXIN06dicpdb9ZLpoGVsGKIj5rtEUgVqkv1qeIfSlf2ipKUESI0yqS245IMvWchoUHoOyLrnAYjFEDKVJVP1BOEgDK-tiMEScJs1lEzxwR0BQOyTzdAWU_rxjce8hVtbEml4T4I%2Fs1600%2Fimage.png" title="Ảnh mô tả khả năng truy cập của bốn loại Access Modifiers trong java." width="800" height="450"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Ảnh mô tả khả năng truy cập của bốn loại Access Modifiers trong java.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;span&gt;&lt;br&gt;&lt;/span&gt;
&lt;h3&gt;&lt;span&gt;Bảng mô tả phạm vi áp dụng của từng từ khóa cho các thành phần (lớp,biến, phương thức,constructor) như sau:&lt;/span&gt;&lt;/h3&gt;
&lt;span id="docs-internal-guid-6e47cbfc-7fff-bcc0-ae0c-3da25b206033"&gt;&lt;br&gt;
  &lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Thành phần&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Public&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Công cộng)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Private&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Riêng tư)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Protected&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Được bảo vệ)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Default&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Mặc định)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Class&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Lớp)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;No&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;No&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Biến&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Variable)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Phương thức&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Methods)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Constructor&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;(Hàm tạo)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Yes&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;&lt;/span&gt;&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅱ. Public (Công cộng)&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;↳ Mức độ truy cập: &lt;/span&gt;&lt;span&gt;Không giới hạn. Các thành phần khai báo với public có thể được truy cập từ bất kỳ đâu, từ bất kỳ lớp nào. Public có thể được áp dụng cho lớp, biến, phương thức, constructor.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Ví dụ Code của bạn có hai package và ba class như sau:&lt;/span&gt;&lt;/h3&gt;
&lt;h4&gt;&lt;span&gt;Trong Package1: có hai class A và class B&lt;/span&gt;&lt;/h4&gt;
&lt;br&gt;
&lt;b&gt;A.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;// Lưu file với tên A.java&lt;br&gt;
package Package1;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;public class A {&lt;br&gt;&lt;br&gt;
    public void Display(){&lt;br&gt;&lt;br&gt;
        System.out.println("Đây là phương thức của Class A");&lt;br&gt;&lt;br&gt;
    }&lt;br&gt;&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;


&lt;p&gt;&lt;b&gt;B.java&lt;/b&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;// Lưu file với tên B.java&lt;br&gt;
package Package1;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;public class B {&lt;br&gt;&lt;br&gt;
    public void Display(){&lt;br&gt;&lt;br&gt;
        System.out.println("Đây là phương thức của Class B");&lt;br&gt;&lt;br&gt;
    }&lt;br&gt;&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;


&lt;h4&gt;&lt;span&gt;Trong Package2: có một class C&lt;/span&gt;&lt;/h4&gt;

&lt;p&gt;&lt;b&gt;C.java&lt;/b&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;// Lưu file với tên C.java&lt;br&gt;
package Package2;&lt;br&gt;
// import Package1.* cho phép bạn sử dụng các lớp từ Package1 trong Package2.&lt;br&gt;
import Package1.*;

&lt;p&gt;public class C {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        // Khởi tạo đối tượng của lớp A từ Package1 và gọi phương thức Display&lt;br&gt;
        A classa = new A();&lt;br&gt;
        classa.Display();&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Khởi tạo đối tượng của lớp B từ Package1 và gọi phương thức Display
    B classb = new B();
    classb.Display();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Đây là phương thức của Class A&lt;br&gt;
Đây là phương thức của Class B&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong ví dụ trên, khi bạn biên dịch và chạy chương trình, Java sẽ bắt đầu thực thi từ phương thức main của lớp C. Nó sẽ tạo ra một đối tượng classa của lớp A và classb của lớp B. Sau đó, nó gọi phương thức Display của cả hai đối tượng này, kết quả là chuỗi trong Phương thức Display sẽ được in ra màn hình.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅲ. Private (Riêng tư)&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;↳ Mức độ truy cập: &lt;/span&gt;&lt;span&gt;chỉ được truy cập trong cùng lớp được khai báo. Các thành phần private không thể được truy cập từ bất kỳ lớp nào khác, ngay cả những lớp kế thừa nó. Private chỉ có thể được áp dụng cho biến, phương thức, constructor. Nó không thể áp dụng cho lớp.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;A.java&lt;/b&gt;&lt;br&gt;
  &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;package Package1;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;public class A {&lt;br&gt;&lt;br&gt;
    private int maSV = 11111;&lt;br&gt;&lt;br&gt;
    private String hoTen = "VTD";&lt;br&gt;&lt;br&gt;
    private double diemSo= 8.5;&lt;br&gt;&lt;br&gt;
    private void ThongTin(){&lt;br&gt;&lt;br&gt;
        System.out.println("Họ Tên: " + hoTen);&lt;br&gt;&lt;br&gt;
        System.out.println("Mã SV: " + maSV);&lt;br&gt;&lt;br&gt;
        System.out.println("Điểm Số: " + diemSo);&lt;br&gt;&lt;br&gt;
    }&lt;br&gt;&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;&lt;br&gt;
        A classa = new A();&lt;br&gt;&lt;br&gt;
        System.out.println("Thông tin sinh viên của class A");&lt;br&gt;&lt;br&gt;
        classa.ThongTin();&lt;br&gt;&lt;br&gt;
    }&lt;br&gt;&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Thông tin sinh viên của class A&lt;br&gt;
Họ Tên: VTD&lt;br&gt;
Mã SV: 11111&lt;br&gt;
Điểm Số: 8.5&lt;/code&gt;&lt;/pre&gt;


&lt;h3&gt;&lt;span&gt;Khai báo constructor với từ khóa private&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Khi bạn &lt;a href="https://www.tieushare.com/2026/10/constructor-trong-java.html" rel="noopener noreferrer"&gt;khai báo constructor &lt;/a&gt;là private, bạn không thể tạo một đối tượng của lớp đó từ bên ngoài lớp đó. Dưới đây là vi dụ về trường hợp này:&lt;/span&gt;&lt;/p&gt;
&lt;b&gt;A.java&lt;/b&gt;

  &lt;pre&gt;&lt;code&gt;package Package1;
// Lớp A
 class A {
    private int maSV = 11111;
    private String hoTen = "VTD";
    private double diemSo= 8.5;

    // Constructor private  Chỉ có thể truy cập từ bên trong lớp A
    private A(){
        System.out.println("Họ Tên: " + hoTen);
        System.out.println("Mã SV: " + maSV);
        System.out.println("Điểm Số: " + diemSo);
    }
}
// Lớp Bên ngoài (lớp main)
public class main{
    public static void main(String[] args) {
        System.out.println("Thông tin sinh viên của class A");
        A classa = new A();// Lỗi biên dịch
    }
}&lt;/code&gt;&lt;/pre&gt;
  
   
  &lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;Exception in thread "main" java.lang.Error: Unresolved compilation problem: The constructor A() is not visible at Package1.main.main(main.java:19)&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong trường hợp này, lớp A có một constructor private, điều đó có nghĩa là bạn không thể tạo một đối tượng của lớp A từ lớp main. Vì vậy, chương trình của bạn bị lỗi biên dịch.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅳ. Protected (Được bảo vệ)&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;↳ Mức độ truy cập: &lt;/span&gt;&lt;span&gt;chỉ được truy cập trong cùng một package và kể cả khi ở khác package nhưng phải mối quan hệ kế thừa (extends). Protected có thể được áp dụng cho biến, phương thức, constructor. Nó không thể áp dụng cho lớp.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Ví dụ Code của bạn có hai package và hai class kế thừa như sau:&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4&gt;&lt;span&gt;Trong Package1: có một class A&lt;/span&gt;&lt;/h4&gt;
&lt;b&gt;A.java&lt;/b&gt;

  &lt;pre&gt;&lt;code&gt;// Lưu file với tên A.java
package Package1;

 class A {    
    protected int maSV = 11111;
    protected String hoTen = "VTD";
    protected double diemSo= 8.5;

    // Constructor protected - Chỉ có thể truy cập từ bên trong lớp A hoặc các lớp con của nó
    protected A() {
        System.out.println("Họ Tên: " + hoTen);
        System.out.println("Mã SV: " + maSV);
        System.out.println("Điểm Số: " + diemSo);
    }
}&lt;/code&gt;&lt;/pre&gt;


&lt;h4&gt;&lt;span&gt;Trong Package2: có một class C kế thừa từ class A&lt;/span&gt;&lt;/h4&gt;
&lt;b&gt;C.java&lt;/b&gt;

  &lt;pre&gt;&lt;code&gt;// Lưu file với tên C.java
package Package2;
// import Package1.* cho phép bạn sử dụng các lớp từ Package1 trong Package2.
import Package1.*;

public class C extends A {

    public static void main(String[] args) {
        // Tạo đối tượng của lớp C, điều này sẽ gọi constructor của lớp A thông qua lớp C
        C classC = new C();
    }
}&lt;/code&gt;&lt;/pre&gt;
  
   
  &lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;Họ Tên: VTD
Mã SV: 11111
Điểm Số: 8.5&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong ví dụ trên, kết quả của chương trình sẽ hiển thị thông tin của sinh viên từ lớp A. Bởi vì C là lớp con của A và các biến, constructor của A có access modifier là protected, nên C có thể gọi constructor của A một cách hợp lệ.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅴ. Default (Mặc định hay còn gọi là không có sửa đổi)&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;↳ Mức độ truy cập: &lt;/span&gt;&lt;span&gt;chỉ được truy cập trong cùng một package. Nếu không khai báo bất kỳ Access Modifier nào, thì thành phần đó sẽ có mức độ truy cập default (package-private). Default có thể được áp dụng cho lớp, biến, phương thức, constructor.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Ví dụ Code của bạn có hai package và ba class như sau:&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4&gt;&lt;span&gt;Trong Package1: có hai class A và class B&lt;/span&gt;&lt;/h4&gt;
&lt;b&gt;A.java&lt;/b&gt;

  &lt;pre&gt;&lt;code&gt;// Lưu file với tên A.java
package Package1;

// Định nghĩa lớp A
class A {
    // Các thuộc tính của lớp A
    int maSV;
    String hoTen;
    double diemSo;

    // Constructor của lớp A
    A(){
        // Constructor này được gọi khi một đối tượng của lớp A được khởi tạo
        // Hiển thị thông tin (do các biến chưa được khởi tạo nên giá trị mặc định của chúng sẽ là null hoặc 0)
        System.out.println("Họ Tên: " + hoTen);
        System.out.println("Mã SV: " + maSV);
        System.out.println("Điểm Số: " + diemSo);
    }

    // Phương thức Thongtin để in ra dấu gạch ngang
    void Thongtin(){
        System.out.println("-----------");
    }
}&lt;/code&gt;&lt;/pre&gt;


&lt;b&gt;B.java&lt;/b&gt;
  &lt;pre&gt;&lt;code&gt;// Lưu file với tên B.java
package Package1;

// Lớp B để chứa phương thức main để thực thi chương trình
public class B {
    public static void main(String[] args) {
        // Khởi tạo một đối tượng của lớp A
        A classa = new A();

        // Gọi phương thức Thongtin() của đối tượng A
        classa.Thongtin();
    }
}&lt;/code&gt;&lt;/pre&gt;
  
   
  &lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;Họ Tên: null
Mã SV: 0
Điểm Số: 0.0
-----------&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong ví dụ trên, kết quả của chương trình sẽ hiển thị thông tin của sinh viên từ lớp A. Bởi vì class A và class B nằm chung trong Package1 và các biến, phương thức, constructor của A có access modifier là default, nên B có thể gọi constructor của A một cách hợp lệ.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Trong Package2: có một class C kế thừa từ class A&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;&lt;b&gt;C.java&lt;/b&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;// Lưu file với tên C.java&lt;br&gt;
package Package2;&lt;br&gt;
import Package1.*;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;public class C extends A {&lt;br&gt;&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;&lt;br&gt;
       // Khởi tạo một đối tượng của lớp A&lt;br&gt;&lt;br&gt;
       A classa = new A();// Xảy ra lỗi biên dịch&lt;br&gt;&lt;br&gt;
    }&lt;br&gt;&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Exception in thread "main" java.lang.Error: Unresolved compilation problem: The constructor A() is not visible at Package1.main.main(main.java:19)&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong ví dụ trên, trình biên dịch sẽ bị lỗi khi in thông tin của sinh viên từ lớp A. Bởi vì class A và class C không nằm chung trong Package1 và các biến, phương thức, constructor của A có access modifier là default (chỉ được truy cập trong cùng một package), nên C không có thể gọi constructor của A một cách hợp lệ.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;

</description>
      <category>kiểmsoátquyềntruycậptrongjava</category>
      <category>accesscontrolinjava</category>
      <category>accesscontrol</category>
      <category>tieushare</category>
    </item>
    <item>
      <title>Tính Đóng Gói (Encapsulation) Trong Java Là Gì? Ví Dụ Dễ Hiểu</title>
      <dc:creator>Tiểu Share</dc:creator>
      <pubDate>Fri, 06 Nov 2026 02:30:59 +0000</pubDate>
      <link>https://dev.to/tieushare/tinh-dong-goi-encapsulation-trong-java-la-gi-vi-du-de-hieu-4ig8</link>
      <guid>https://dev.to/tieushare/tinh-dong-goi-encapsulation-trong-java-la-gi-vi-du-de-hieu-4ig8</guid>
      <description>&lt;p&gt;&lt;span id="docs-internal-guid-a70fc756-7fff-7170-524d-444594f50633"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;"Trong lập trình hướng đối tượng, tính đóng gói (Encapsulation) là một nguyên lý cốt lõi giúp bảo vệ dữ liệu và kiểm soát quyền truy cập vào các thành phần của đối tượng. Điều này không chỉ nâng cao tính bảo mật mà còn làm cho mã nguồn trở nên dễ bảo trì hơn. Dưới đây là những điều cơ bản bạn cần biết về &lt;b&gt;&lt;a href="https://www.tieushare.com/2026/10/tinh-dong-goi-encapsulation-trong-java.html" rel="noopener noreferrer"&gt;tính đóng gói trong Java&lt;/a&gt;&lt;/b&gt;."&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅰ. Đóng gói (Encapsulation) là gì?&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Đóng gói (Encapsulation) là một khái niệm quan trọng trong lập trình hướng đối tượng (OOP) của Java. Nó đề cập đến việc đóng gói dữ liệu (các biến) và các phương thức thao tác trên dữ liệu đó trong một lớp, nhằm che giấu thông tin bên trong lớp và chỉ cung cấp những gì cần thiết thông qua các phương thức công khai (public methods).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Viên nang thuốc là ví dụ kinh điển và được sử dụng nhiều nhất. Tính đóng gói giống như viên nang thuốc chứa nhiều thành phần thuốc khác nhau, tính đóng gói bao bọc dữ liệu (thuộc tính) và các phương thức thao tác trên dữ liệu (phương thức) vào một đơn vị duy nhất (lớp). Viên nang bảo vệ thuốc khỏi các tác nhân bên ngoài, tương tự như lớp bảo vệ dữ liệu khỏi truy cập và sửa đổi trái phép.&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicThOu03zoy7J68kLABBFm59zZUmF0te5wFL-H_VwybTvZtxhy8uOOV4nb75C57-ckcm-YuQiY5ek97rmVSl5hUIyW8nfuGjkvqx1CFtg2RtA-5tRq_sQCgQusAadd-jqv-i91pAGH3RBp-pu3yPji7r2WmkYdTWbiNkiLIoTIU1QpaG1tlqjLugzeqp0/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả tính đóng gói (Encapsulation) trong Java." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEicThOu03zoy7J68kLABBFm59zZUmF0te5wFL-H_VwybTvZtxhy8uOOV4nb75C57-ckcm-YuQiY5ek97rmVSl5hUIyW8nfuGjkvqx1CFtg2RtA-5tRq_sQCgQusAadd-jqv-i91pAGH3RBp-pu3yPji7r2WmkYdTWbiNkiLIoTIU1QpaG1tlqjLugzeqp0%2Fw640-h360%2Fimage.png" title="Ảnh mô tả tính đóng gói (Encapsulation) trong Java." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span&gt;Ảnh mô tả tính đóng gói (Encapsulation) trong Java.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;&lt;span&gt;Các thuật ngữ liên quan đến đóng gói:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Lớp (Class): &lt;/span&gt;&lt;span&gt;Là một bản thiết kế cho các đối tượng, định nghĩa các thuộc tính và phương thức của chúng.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Đối tượng (Object): &lt;/span&gt;&lt;span&gt;Là một thực thể được tạo ra từ một lớp, nó có các thuộc tính và hành vi riêng.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Thuộc tính (Attribute): &lt;/span&gt;&lt;span&gt;Là một đặc tính của một đối tượng, thường được biểu diễn bằng các biến.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Phương thức (Method): &lt;/span&gt;&lt;span&gt;Là một hành động mà một đối tượng có thể thực hiện, thường được biểu diễn bằng các hàm.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Kiểm soát truy cập (Access modifier): &lt;/span&gt;&lt;span&gt;Sử dụng các từ khóa như public, private, protected để xác định mức độ truy cập vào các thành viên của một lớp.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Getter và setter: &lt;/span&gt;&lt;span&gt;Là các phương thức đặc biệt dùng để truy xuất và cập nhật giá trị của các thuộc tính private.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Lợi ích của đóng gói (Encapsulation):&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Kiểm soát dữ liệu: &lt;/span&gt;&lt;span&gt;Bạn có thể kiểm soát việc truy cập và thay đổi dữ liệu. Ví dụ, trong setter của grade, bạn có thể kiểm tra xem điểm có hợp lệ (không âm) trước khi cập nhật giá trị.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Ẩn dữ liệu (Data Hiding): &lt;/span&gt;&lt;span&gt;Các lớp khác không thể truy cập trực tiếp vào dữ liệu, giúp bảo vệ dữ liệu khỏi những thay đổi không mong muốn.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tính linh hoạt: &lt;/span&gt;&lt;span&gt;Bạn có thể dễ dàng thay đổi cách thức truy cập và thao tác dữ liệu bằng cách sửa đổi setter và getter.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Dễ dàng kiểm thử: &lt;/span&gt;&lt;span&gt;Các lớp được đóng gói dễ dàng kiểm thử riêng lẻ vì dữ liệu được bảo vệ.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅱ. &lt;a href="https://www.tieushare.com/2026/10/tinh-dong-goi-encapsulation-trong-java.html" rel="noopener noreferrer"&gt;Cách thức hoạt động của tính đóng gói (Encapsulation)&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Tính đóng gói (encapsulation) được thực hiện bằng cách khai báo các thuộc tính (biến) của lớp là private và cung cấp các phương thức công khai (public) để truy cập và sửa đổi các thuộc tính này. Các phương thức công khai này được gọi là các phương thức getter và setter. Dưới đây là cú pháp cơ bản để thực hiện tính đóng gói:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Khai báo dữ liệu thành private: &lt;/span&gt;&lt;span&gt;Bạn khai báo các biến lưu trữ dữ liệu (như accountNumber, balance, và accountHolderName) thành private. Điều này có nghĩa là các lớp khác không thể truy cập trực tiếp vào dữ liệu này.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Sử dụng phương thức công khai setter và getter: &lt;/span&gt;&lt;span&gt;Để cho phép các lớp khác truy cập và thay đổi dữ liệu được kiểm soát, bạn tạo các phương thức đặc biệt:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Setter: &lt;/span&gt;&lt;span&gt;Cho phép thiết lập giá trị cho biến. Ví dụ: set accountHolderName (String newaccountHolderName) để đặt tên mới cho tài khoản.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Getter: &lt;/span&gt;&lt;span&gt;Cho phép lấy giá trị của biến. Ví dụ: get accountHolderName() để lấy tên của chủ tài khoản.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅲ. Ví dụ về tính đóng gói (Encapsulation)&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Dưới đây là một ví dụ về tính đóng gói (encapsulation) trong một lớp Tài Khoản Ngân Hàng. Trong ví dụ này, các thuộc tính của tài khoản ngân hàng như số tài khoản, số dư, và tên chủ tài khoản được đóng gói bên trong lớp và chỉ có thể truy cập thông qua các phương thức công khai.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;BankAccount.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;public class BankAccount {&lt;br&gt;
    // Các thuộc tính được đóng gói&lt;br&gt;
    private String accountNumber;&lt;br&gt;
    private double balance;&lt;br&gt;
    private String accountHolderName;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor để khởi tạo tài khoản ngân hàng
public BankAccount(String accountNumber, String accountHolderName, double initialBalance) {
    this.accountNumber = accountNumber;
    this.accountHolderName = accountHolderName;
    this.balance = initialBalance;
}

// Phương thức để lấy số tài khoản
public String getAccountNumber() {
    return accountNumber;
}

// Phương thức để lấy tên chủ tài khoản
public String getAccountHolderName() {
    return accountHolderName;
}

// Phương thức để lấy số dư
public double getBalance() {
    return balance;
}

// Phương thức để nạp tiền vào tài khoản
public void deposit(double amount) {
    if (amount &amp;amp;gt; 0) {
        balance += amount;
        System.out.println("Nạp tiền thành công. Số dư mới: " + balance);
    } else {
        System.out.println("Số tiền nạp phải lớn hơn 0.");
    }
}

// Phương thức để rút tiền từ tài khoản
public void withdraw(double amount) {
    if (amount &amp;amp;gt; 0 &amp;amp;amp;&amp;amp;amp; amount &amp;amp;lt;= balance) {
        balance -= amount;
        System.out.println("Rút tiền thành công. Số dư mới: " + balance);
    } else {
        System.out.println("Số tiền rút không hợp lệ hoặc không đủ số dư.");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;


&lt;h3&gt;&lt;span&gt;&lt;b&gt;Giải thích đoạn mã trên:&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Các thuộc tính được đóng gói:&lt;/span&gt;&lt;span&gt; accountNumber, balance, và accountHolderName được khai báo là private, chỉ có thể truy cập bên trong lớp BankAccount.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Constructor: &lt;/span&gt;&lt;span&gt;Được sử dụng để khởi tạo các thuộc tính của tài khoản ngân hàng.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Các phương thức công khai Getter và Setter:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ getAccountNumber() và setAccountNumber(String accountNumber) để lấy và gán giá trị cho thuộc tính accountNumber.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ getAccountHolderName() và setAccountHolderName(String accountHolderName) để lấy và gán giá trị cho thuộc tính accountHolderName.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ getBalance() và setBalance(double balance) để lấy và gán giá trị cho thuộc tính balance.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Lớp Main: sử dụng phương thức getter.&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Tạo một đối tượng BankAccount và sử dụng các phương thức getter công khai để tương tác lấy thông tin của tài khoản ngân hàng.&lt;/span&gt;&lt;/p&gt;
&lt;b&gt;Main.java&lt;/b&gt;

  &lt;pre&gt;&lt;code&gt;public class Main {
    public static void main(String[] args) {
        // Tạo một đối tượng tài khoản ngân hàng
        BankAccount account = new BankAccount("123456789", "Dương", 1000.0);

        // In thông tin tài khoản
        System.out.println("Số tài khoản: " + account.getAccountNumber());
        System.out.println("Tên chủ tài khoản: " + account.getAccountHolderName());
        System.out.println("Số dư hiện tại: " + account.getBalance());

        // Nạp tiền vào tài khoản
        account.deposit(500.0);

        // Rút tiền từ tài khoản
        account.withdraw(200.0);

        // Thử rút số tiền lớn hơn số dư hiện tại
        account.withdraw(1500.0);
    }
}&lt;/code&gt;&lt;/pre&gt;
  
   
  &lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;Số tài khoản: 123456789
Tên chủ tài khoản: Dương
Số dư hiện tại: 1000.0
Nạp tiền thành công. Số dư mới: 1500.0
Rút tiền thành công. Số dư mới: 1300.0
Số tiền rút không hợp lệ hoặc không đủ số dư.&lt;/code&gt;&lt;/pre&gt;


&lt;h3&gt;&lt;span&gt;&lt;b&gt;Lớp Main: sử dụng phương thức setter.&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Tạo một đối tượng BankAccount, sử dụng các phương thức setter để thay đổi tên chủ tài khoản và sử dụng phương thức getter để tương tác lấy thông tin của chủ tài khoản ngân hàng mới.&lt;/span&gt;&lt;/p&gt;
&lt;b&gt;Main.java&lt;/b&gt;

  &lt;pre&gt;&lt;code&gt;public class Main {
    public static void main(String[] args) {
        // Tạo một đối tượng tài khoản ngân hàng
        BankAccount account = new BankAccount("123456789", "Dương", 1000.0);
        
        // Thay đổi tên chủ tài khoản và in lại thông tin
        account.setAccountHolderName("Nguyễn Văn A");
        
        // In thông tin tài khoản
        System.out.println("Số tài khoản: " + account.getAccountNumber());
        System.out.println("Tên chủ tài khoản: " + account.getAccountHolderName());
        System.out.println("Số dư hiện tại: " + account.getBalance());
    }
}&lt;/code&gt;&lt;/pre&gt;
  
   
  &lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;Số tài khoản: 123456789
Tên chủ tài khoản: Nguyễn Văn A
Số dư hiện tại: 1000.0&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong ví dụ này minh họa cách tính đóng gói bảo vệ dữ liệu của tài khoản ngân hàng và chỉ cho phép truy cập và thay đổi dữ liệu thông qua các phương thức công khai, đảm bảo tính an toàn và toàn vẹn của dữ liệu.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅳ. Ví dụ về vấn đề khi không có tính đóng gói (Encapsulation)&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Dưới đây là một ví dụ minh họa cho thấy các vấn đề có thể xảy ra khi không sử dụng tính đóng gói trong lớp BankAccount:&lt;/span&gt;&lt;/p&gt;
&lt;b&gt;BankAccount.java&lt;/b&gt;

  &lt;pre&gt;&lt;code&gt;public class BankAccount {
    // Các thuộc tính không được đóng gói
    public String accountNumber;
    public double balance;
    public String accountHolderName;

    // Constructor để khởi tạo tài khoản ngân hàng
    public BankAccount(String accountNumber, String accountHolderName, double initialBalance) {
        this.accountNumber = accountNumber;
        this.accountHolderName = accountHolderName;
        this.balance = initialBalance;
    }

    // Các phương thức nạp tiền và rút tiền
    public void deposit(double amount) {
        if (amount &amp;gt; 0) {
            balance += amount;
            System.out.println("Nạp tiền thành công. Số dư mới: " + balance);
        } else {
            System.out.println("Số tiền nạp phải lớn hơn 0.");
        }
    }

    public void withdraw(double amount) {
        if (amount &amp;gt; 0 &amp;amp;&amp;amp; amount &amp;lt;= balance) {
            balance -= amount;
            System.out.println("Rút tiền thành công. Số dư mới: " + balance);
        } else {
            System.out.println("Số tiền rút không hợp lệ hoặc không đủ số dư.");
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
  


&lt;h3&gt;&lt;span&gt;&lt;b&gt;Lớp Main&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;&lt;b&gt;Main.java&lt;/b&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;public class Main {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        // Tạo một đối tượng tài khoản ngân hàng&lt;br&gt;
        BankAccount account = new BankAccount("123456789", "Dương", 1000.0);

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Truy cập và thay đổi trực tiếp các thuộc tính
    account.balance = -500.0; // Số dư không hợp lệ
    account.accountHolderName = ""; // Tên chủ tài khoản không hợp lệ

    // In thông tin tài khoản
    System.out.println("Số tài khoản: " + account.accountNumber);
    System.out.println("Tên chủ tài khoản: " + account.accountHolderName);
    System.out.println("Số dư hiện tại: " + account.balance);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Số tài khoản: 123456789&lt;br&gt;
Tên chủ tài khoản:&lt;br&gt;
Số dư hiện tại: -500.0&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;&lt;span&gt;Vấn đề trong ví dụ trên:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Số dư âm: &lt;/span&gt;&lt;span&gt;Số dư tài khoản có thể bị đặt thành giá trị âm, điều này không hợp lệ trong thực tế.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tên chủ tài khoản trống: &lt;/span&gt;&lt;span&gt;Tên chủ tài khoản có thể bị đặt thành giá trị trống, điều này cũng không hợp lệ.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Thiếu tính kiểm soát: &lt;/span&gt;&lt;span&gt;Không có cách nào để kiểm soát hoặc xác minh các giá trị được đặt cho các thuộc tính.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Nếu không có tính đóng gói (encapsulation), các thuộc tính của lớp BankAccount sẽ không được bảo vệ và có thể bị truy cập hoặc thay đổi trực tiếp từ bên ngoài. Điều này có thể dẫn đến nhiều vấn đề, bao gồm:&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;&lt;b&gt;Bảo mật và an toàn dữ liệu:&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ Truy cập trái phép: &lt;/span&gt;&lt;span&gt;Các thuộc tính như accountNumber, balance và accountHolderName có thể bị truy cập và thay đổi từ bất kỳ đâu trong chương trình, dẫn đến việc dữ liệu nhạy cảm của tài khoản ngân hàng bị xâm phạm.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Sửa đổi không hợp lệ: &lt;/span&gt;&lt;span&gt;Các giá trị của thuộc tính có thể bị thay đổi thành các giá trị không hợp lệ hoặc không mong muốn mà không có bất kỳ kiểm tra hoặc xác minh nào. Ví dụ, số dư tài khoản (balance) có thể bị đặt thành số âm hoặc số lượng không hợp lệ.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;Khó khăn trong bảo trì và Phát triển:&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ Mã lộn xộn và phức tạp: &lt;/span&gt;&lt;span&gt;Việc cho phép truy cập trực tiếp đến các thuộc tính từ nhiều phần khác nhau của chương trình sẽ làm cho mã nguồn trở nên khó đọc, khó hiểu và khó bảo trì.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Thiếu tính kiểm soát: &lt;/span&gt;&lt;span&gt;Không có khả năng kiểm soát khi nào và làm thế nào các thuộc tính được thay đổi, làm cho việc gỡ lỗi và bảo trì trở nên phức tạp hơn.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;&lt;b&gt;Thiếu khả năng kiểm tra và xác minh:&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ Không thể kiểm tra giá trị: &lt;/span&gt;&lt;span&gt;Không có cách nào để đảm bảo rằng các giá trị của thuộc tính luôn hợp lệ. Ví dụ, không có cách nào để kiểm tra xem số tiền nạp hoặc rút có hợp lệ hay không trước khi thực hiện thay đổi.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;

</description>
      <category>tínhđónggóitrongjava</category>
      <category>encapsulationtrongjava</category>
      <category>tinhdonggoitrongjava</category>
      <category>tieushare</category>
    </item>
    <item>
      <title>Từ khóa static trong Java là gì? Cách sử dụng và ví dụ</title>
      <dc:creator>Tiểu Share</dc:creator>
      <pubDate>Thu, 05 Nov 2026 05:07:55 +0000</pubDate>
      <link>https://dev.to/tieushare/tu-khoa-static-trong-java-la-gi-cach-su-dung-va-vi-du-59fl</link>
      <guid>https://dev.to/tieushare/tu-khoa-static-trong-java-la-gi-cach-su-dung-va-vi-du-59fl</guid>
      <description>&lt;p&gt;&lt;span id="docs-internal-guid-c155c45c-7fff-8728-5272-bee7ae052e49"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;"Trong Java, từ khóa static là một công cụ quan trọng, cho phép bạn định nghĩa các thành phần có thể truy cập mà không cần tạo đối tượng. Điều này giúp tối ưu hóa bộ nhớ và làm cho chương trình trở nên hiệu quả hơn. Dưới đây là những điều cơ bản bạn cần biết về từ khóa static trong Java."&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Từ khóa static trong Java được sử dụng để quản lý bộ nhớ một cách hiệu quả. Khi một thành phần được khai báo là static thì nó thuộc về lớp chứ không phải thuộc về một đối tượng cụ thể nào của lớp đó. Từ khóa static có thể được áp dụng cho:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;↳ Biến static.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Phương thức static.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Khối lệnh static.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjO4ebqz71QbbslDGSZrMLQaw4iAQ3p_wAVQrg3WHEmBT97vChMcn3WyCrYQc33j4KEoXcSSS_4CfVcV1X2YeABKyPT8wcQA-Oh7jcOLl3B6t6FfRhFQ7EtENmOMmEY-E51smUikOnFNLQ5tI9PEW5IlRCUDzgc52ow1uPhF0mHie0ULp5htKmaT8blHfM/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả các ngữ cảnh của từ khóa static." src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEjO4ebqz71QbbslDGSZrMLQaw4iAQ3p_wAVQrg3WHEmBT97vChMcn3WyCrYQc33j4KEoXcSSS_4CfVcV1X2YeABKyPT8wcQA-Oh7jcOLl3B6t6FfRhFQ7EtENmOMmEY-E51smUikOnFNLQ5tI9PEW5IlRCUDzgc52ow1uPhF0mHie0ULp5htKmaT8blHfM%2Fs1600%2Fimage.png" title="Ảnh mô tả các ngữ cảnh của từ khóa static." width="800" height="450"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Ảnh mô tả các ngữ cảnh của từ khóa static.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;span&gt;&lt;b&gt;&lt;a href="https://www.tieushare.com/2026/10/tu-khoa-static-trong-java.html" rel="noopener noreferrer"&gt;Từ khóa static&lt;/a&gt;&lt;/b&gt; là một công cụ mạnh mẽ trong Java, nhưng cần được sử dụng một cách hợp lý. Hiểu rõ các đặc điểm và ứng dụng của static sẽ giúp bạn viết code Java hiệu quả hơn.&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅰ. Biến static&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Khi bạn khai báo một biến là static, thì biến đó được gọi là biến tĩnh, hay biến static.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Đặc điểm của biến static:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Thuộc về lớp, chứ không thuộc về đối tượng nào.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Có một bản sao duy nhất cho toàn bộ lớp, bất kể có bao nhiêu đối tượng được tạo ra.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Được khởi tạo khi lớp được tải vào bộ nhớ.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Cách sử dụng biến static:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Để lưu trữ các thông tin chung cho tất cả các đối tượng của lớp, ví dụ như số lượng đối tượng đã được tạo, các hằng số chung, tên công ty, tên trường học...&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Truy cập trực tiếp thông qua tên lớp mà không cần tạo đối tượng.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Ví dụ 1:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Hãy tưởng tượng một công ty tên là ABC Corp có nhiều nhân viên. Tất cả nhân viên đều làm việc cho cùng một công ty, vì vậy tên công ty của họ giống nhau. Trong trường hợp này, tên công ty có thể là biến static trong lớp Employee. Dưới đây là một ví dụ cụ thể để bạn hiểu rõ hơn:&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;Không sử dụng biến static&lt;/span&gt;&lt;/h4&gt;
&lt;br&gt;
&lt;b&gt;Employee.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;public class Employee {&lt;br&gt;
    String companyName = "ABC Corp";&lt;br&gt;
    int id;&lt;br&gt;
    String name;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public Employee(int id, String name) {
    this.id = id;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;this.name = name;&lt;br&gt;
    }&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void display() {
    System.out.println(id +". "+ name + " Làm việc tại " + companyName);
}

public static void main(String[] args) {
    Employee employee1 = new Employee("Vương");
    Employee employee2 = new Employee("Trường");

    employee1.display();
    employee2.display();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;1. Vương Làm việc tại ABC Corp

&lt;/code&gt;&lt;ol&gt;
&lt;code&gt;&lt;br&gt;
&lt;/code&gt;&lt;li&gt;&lt;code&gt;Trường Làm việc tại ABC Corp&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong ví dụ này, mỗi đối tượng Employee có một bản sao riêng của biến companyName. Điều này không hiệu quả về bộ nhớ vì companyName là thuộc tính chung của tất cả các đối tượng.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;Sử dụng biến static&lt;/span&gt;&lt;/h4&gt;
&lt;br&gt;
&lt;b&gt;Employee.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;public class Employee {&lt;br&gt;
    static String companyName = "ABC Corp";&lt;br&gt;
    int id;&lt;br&gt;
    String name;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public Employee(int id, String name) {
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;this.id = id;&lt;br&gt;
        this.name = name;&lt;br&gt;
    }&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void display() {
    System.out.println(id +". "+ name + " Làm việc tại " + companyName);
}

public static void main(String[] args) {
    Employee employee1 = new Employee("Vương");
    Employee employee2 = new Employee("Trường");

    employee1.display();
    employee2.display();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;1. Vương Làm việc tại ABC Corp

&lt;/code&gt;&lt;ol&gt;
&lt;code&gt;&lt;br&gt;
&lt;/code&gt;&lt;li&gt;&lt;code&gt;Trường Làm việc tại ABC Corp&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong ví dụ này, biến companyName được khai báo là static, do đó chỉ có một bản sao duy nhất của biến này được chia sẻ giữa tất cả các đối tượng Employee, giúp tiết kiệm bộ nhớ.&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-KDkamD0uifTE1XQQdLcL4UpsiHEyWOlVJyaEZdBBd8GWWCIyg5gzwRYGrILCaDrLxMPrKWqavBziT3Djcss4vd48Du7V_vlnYmGcZwUlq9ijPcGiywc9iVW-qd1kDq525wp1BqvjB555ReIizM2YbODr3F-1-nfPQSF7o9lYaL-6GvlUagJJihx3_fM/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả thông tin chung của biến static." src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEh-KDkamD0uifTE1XQQdLcL4UpsiHEyWOlVJyaEZdBBd8GWWCIyg5gzwRYGrILCaDrLxMPrKWqavBziT3Djcss4vd48Du7V_vlnYmGcZwUlq9ijPcGiywc9iVW-qd1kDq525wp1BqvjB555ReIizM2YbODr3F-1-nfPQSF7o9lYaL-6GvlUagJJihx3_fM%2Fs1600%2Fimage.png" title="Ảnh mô tả thông tin chung của biến static." width="800" height="450"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Ảnh mô tả thông tin chung của biến static.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;&lt;span&gt;&lt;b&gt;Ví dụ 2:&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Trong ví dụ này, biến static được dùng để đếm số lượng đối tượng được tạo từ một lớp, so sánh với cách không sử dụng biến static.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;Không sử dụng biến static&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;Trong ví dụ này, mỗi đối tượng sẽ có biến count riêng của nó, do đó, biến đếm không hoạt động chính xác.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;ECounter.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;public class Counter {&lt;br&gt;
    int count = 0; // Biến đếm không static

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public Counter() {
    count++;
    System.out.println("Biến đếm số lượng không dùng static: " + count);
}

public static void main(String[] args) {
    Counter c1 = new Counter();
    Counter c2 = new Counter();
    Counter c3 = new Counter();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Biến đếm số lượng không dùng static: 1&lt;br&gt;
Biến đếm số lượng không dùng static: 1&lt;br&gt;
Biến đếm số lượng không dùng static: 1&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong ví dụ này, mỗi đối tượng Counter có biến count riêng, nên giá trị của count không được chia sẻ giữa các đối tượng.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;Sử dụng biến static&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;Trong ví dụ này, biến count được khai báo là static, do đó, nó được chia sẻ giữa tất cả các đối tượng và đếm chính xác số lượng đối tượng được tạo ra.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Counter.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;public class Counter {&lt;br&gt;
    static int count = 0; // Biến đếm dùng static

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public Counter() {
    count++;
    System.out.println("Biến đếm số lượng dùng static: " + count);
}

public static void main(String[] args) {
    Counter c1 = new Counter();
    Counter c2 = new Counter();
    Counter c3 = new Counter();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Biến đếm số lượng dùng static: 1&lt;br&gt;
Biến đếm số lượng dùng static: 2&lt;br&gt;
Biến đếm số lượng dùng static: 3 &lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong ví dụ này, biến count được chia sẻ giữa tất cả các đối tượng Counter, do đó, nó đếm chính xác số lượng đối tượng được tạo ra.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Bảng so sánh chi tiết giữa biến static và biến thể hiện (instance variable) trong Java.&lt;/span&gt;&lt;/h3&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Đặc điểm&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Biến static (Biến lớp)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Biến thể hiện (Biến instance)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Thuộc về&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Lớp&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Đối tượng (instance) của lớp&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Bộ nhớ&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Vùng nhớ chung của lớp&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Vùng nhớ riêng của mỗi đối tượng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Số lượng bản sao&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Chỉ có một bản sao cho toàn bộ lớp&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Mỗi đối tượng có một bản sao riêng biệt&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Cách truy cập&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Truy cập trực tiếp qua tên lớp&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Truy cập qua đối tượng của lớp&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Vòng đời&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Được tạo khi lớp được load và tồn tại cho đến khi chương trình kết thúc&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Được tạo khi đối tượng được khởi tạo và bị hủy khi đối tượng bị thu hồi bộ nhớ&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Sử dụng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Để lưu trữ thông tin chung cho tất cả các đối tượng của lớp, các hằng số, các phương thức tiện ích&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Để lưu trữ dữ liệu riêng của từng đối tượng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Ví dụ&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Số lượng đối tượng đã được tạo, giá trị Pi, tên chung…&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tên của một người, tuổi, địa chỉ&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅱ. &lt;a href="https://www.tieushare.com/2026/10/tu-khoa-static-trong-java.html" rel="noopener noreferrer"&gt;Phương thức static&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Nếu bạn áp dụng từ khóa static với bất cứ phương thức nào, thì phương thức đó được gọi là phương thức static.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Đặc điểm của phương thức static:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Phương thức static thuộc về lớp và có thể được gọi mà không cần tạo đối tượng của lớp đó.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Phương thức static thường được sử dụng trong các lớp tiện ích hoặc để thực hiện các tác vụ không liên quan đến các biến thể hiện (biến instance).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Phương thức static có thể truy cập các biến static khác và gọi các phương thức static khác trong cùng một lớp.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Cách sử dụng phương thức static:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Để thực hiện các tác vụ liên quan đến lớp chứ không phải đối tượng cụ thể, ví dụ như các phương thức tiện ích (utility methods).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Phương thức main luôn là một phương thức static.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Ví dụ 1: Phương thức static trong một lớp tiện ích.&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Phương thức static thường được sử dụng trong các lớp tiện ích (utility classes) nơi mà các phương thức không cần đến trạng thái của đối tượng.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Math.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;public class Math {&lt;br&gt;
    // Phương thức static để tính tổng hai số&lt;br&gt;
    public static int add(int a, int b) {&lt;br&gt;
        return a + b;&lt;br&gt;
    }

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Phương thức static để tính hiệu hai số
public static int subtract(int a, int b) {
    return a - b;
}

// Phương thức static để tính tích hai số
public static int multiply(int a, int b) {
    return a * b;
}

public static void main(String[] args) {
    // Gọi các phương thức static mà không cần tạo đối tượng
    int tong = Math.add(10, 5);
    int hieu = Math.subtract(10, 5);
    int nhan = Math.multiply(10, 5);

    // In kết quả ra màn hình
    System.out.println("Tổng hai số: " + tong);
    System.out.println("Hiệu hai số: " + hieu);
    System.out.println("Nhân hai số: " + nhan);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Tổng hai số: 15&lt;br&gt;
Hiệu hai số: 5&lt;br&gt;
Nhân hai số: 50&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong ví dụ này, các phương thức add, subtract và multiply là các phương thức static. Chúng có thể được gọi trực tiếp bằng tên lớp Math mà không cần tạo đối tượng của lớp này.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Ví dụ 2: Phương thức static trong một lớp thông thường.&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Phương thức static cũng có thể được sử dụng trong một lớp thông thường để thực hiện các tác vụ không liên quan đến các biến thể hiện (instance variables):&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Counter.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;public class Counter {&lt;br&gt;
    private static int count = 0;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Phương thức static để tăng giá trị của biến count
public static void increment() {
    count++;
}

// Phương thức static để lấy giá trị hiện tại của biến count
public static int getCount() {
    return count;
}

public static void main(String[] args) {
    // Gọi các phương thức static mà không cần tạo đối tượng
    Counter.increment();
    Counter.increment();
    Counter.increment();

    // In giá trị của biến count ra màn hình
    System.out.println("Count: " + Counter.getCount());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Tổng hai số: 15&lt;br&gt;
Hiệu hai số: 5&lt;br&gt;
Nhân hai số: 50&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong ví dụ này, phương thức increment và getCount là các phương thức static. Chúng có thể được gọi trực tiếp bằng tên lớp Counter mà không cần tạo đối tượng của lớp này. Biến count là biến static và được chia sẻ giữa tất cả các đối tượng của lớp Counter.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Các hạn chế chính của phương thức static&lt;/span&gt;&lt;/h3&gt;
&lt;h4&gt;&lt;span&gt;1. Không thể truy cập trực tiếp biến instance:&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Phương thức static không thể truy cập trực tiếp các biến instance (biến không phải static) của lớp. Điều này là do phương thức static không liên kết với bất kỳ đối tượng cụ thể nào, trong khi biến instance lại thuộc về một đối tượng nhất định.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;2. Không thể gọi trực tiếp phương thức instance:&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Tương tự như biến instance, phương thức static cũng không thể gọi trực tiếp các phương thức instance. Lý do là phương thức static không có ngữ cảnh của một đối tượng.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;3. Không thể sử dụng từ khóa this và super:&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Từ khóa this đại diện cho đối tượng hiện tại, còn super dùng để gọi đến phương thức của lớp cha. Do phương thức static không liên quan đến bất kỳ đối tượng cụ thể nào, nên không thể sử dụng hai từ khóa này trong phương thức static.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;4. Không thể ghi đè (override):&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Phương thức static không thể bị ghi đè bởi các lớp con. Điều này là do phương thức static thuộc về lớp chứ không thuộc về đối tượng, và việc ghi đè chỉ áp dụng cho các phương thức instance.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Ví dụ minh họa các hạn chế của phương thức static:&lt;/span&gt;&lt;/h3&gt;
&lt;br&gt;
&lt;b&gt;Animal.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;class Animal {&lt;br&gt;
    public static void sound() {&lt;br&gt;
        System.out.println("Âm thanh của động vật");&lt;br&gt;
    }&lt;br&gt;
}

&lt;p&gt;class Dog extends Animal {&lt;br&gt;
    @Override&lt;br&gt;
    public static void sound() {&lt;br&gt;
        System.out.println("Tiếng chó sủa");&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;public class Main {&lt;br&gt;
    public static void main(String[] args) {   &lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Gọi phương thức static bằng tên lớp
    Dog.sound();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Exception in thread "main" java.lang.Error: Unresolved compilation problem: The method sound() of type Dog must override or implement a supertype method&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;&lt;span&gt;So sánh chi tiết giữa phương thức static và phương thức không static (instance method) trong Java:&lt;/span&gt;&lt;/h3&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Đặc điểm&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Phương thức static&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Phương thức không static (instance method)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Thuộc về&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Lớp&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Đối tượng (instance) của lớp&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Cách gọi&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Gọi trực tiếp qua tên lớp&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Gọi thông qua đối tượng của lớp&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Truy cập&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có thể truy cập biến static và phương thức static khác&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có thể truy cập cả biến static, biến instance và phương thức static, phương thức instance&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Từ khóa this và super&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Không thể sử dụng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có thể sử dụng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Ghi đè&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Không thể ghi đè&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có thể ghi đè&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Sử dụng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Các phương thức tiện ích, hằng số, điểm vào của chương trình (main)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Các hành động liên quan đến trạng thái của đối tượng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅲ. &lt;a href="https://www.tieushare.com/2026/10/tu-khoa-static-trong-java.html" rel="noopener noreferrer"&gt;Khối lệnh static&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Khối lệnh static được sử dụng để khởi tạo dữ liệu tĩnh. Nó được thực thi trước phương thức main tại lúc tải lớp.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Example.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;public class Example {&lt;br&gt;
    public static int number;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static {
    number = 42;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;System.out.println("Xin chào, Java");&lt;br&gt;
        System.out.println("Khối lệnh Static được thực thi");&lt;br&gt;
    }&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static void main(String[] args) {
  System.out.println("\nXin chào, Main");
    System.out.println("Giá trị của number: " + Example.number);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Xin chào, Khối Static&lt;br&gt;
Khối lệnh Static được thực thi

&lt;/code&gt;&lt;p&gt;&lt;code&gt;Xin chào, Main&lt;br&gt;&lt;br&gt;
Giá trị của number: 42&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;h3&gt;&lt;span&gt;Câu hỏi: Tại sao phương thức main trong Java lại là static?&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Câu trả lời ngắn gọn: &lt;/span&gt;&lt;span&gt;Phương thức main trong Java được khai báo là static để JVM (Java Virtual Machine) có thể gọi trực tiếp nó mà không cần phải tạo ra một đối tượng nào của lớp chứa phương thức main.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;b&gt;Giải thích chi tiết:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ JVM và điểm khởi đầu: &lt;/span&gt;&lt;span&gt;Khi bạn chạy một chương trình Java, JVM sẽ tìm đến phương thức main() để bắt đầu thực thi.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Không cần tạo đối tượng: &lt;/span&gt;&lt;span&gt;Để đơn giản hóa quá trình khởi động chương trình, JVM không cần phải tạo ra một đối tượng của lớp chứa phương thức main. Việc khai báo main là static cho phép JVM gọi trực tiếp phương thức này mà không cần qua các bước tạo đối tượng phức tạp.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tính độc lập: &lt;/span&gt;&lt;span&gt;Phương thức static thuộc về lớp chứ không thuộc về bất kỳ đối tượng nào của lớp đó. Điều này có nghĩa là phương thức main có thể được gọi ngay cả khi chưa có bất kỳ đối tượng nào của lớp được tạo ra.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tính tiện lợi: &lt;/span&gt;&lt;span&gt;Việc khai báo main là static giúp cho việc viết và chạy các chương trình Java trở nên đơn giản và trực quan hơn.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Example.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;public class Example {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        System.out.println("Xin chào, thế giới!");&lt;br&gt;
    }&lt;br&gt;
}&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong ví dụ trên, khi bạn chạy chương trình này, JVM sẽ tìm đến lớp Example và gọi trực tiếp phương thức main() mà không cần tạo ra một đối tượng nào của lớp Example.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Các câu hỏi liên quan bạn có thể quan tâm:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Câu hỏi: Tại sao phương thức main phải là public?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Trả lời: Để JVM có thể truy cập được phương thức main từ bất kỳ lớp nào.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Câu hỏi: Tại sao phương thức main phải là void?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Trả lời: Vì phương thức main không cần trả về bất kỳ giá trị nào.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Câu hỏi: Có thể có nhiều phương thức main trong một lớp không?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Trả lời: Không, một lớp chỉ có thể có một phương thức main.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Câu hỏi: Phương thức main có thể được override không?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Trả lời: Không, phương thức static không thể bị override.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;So sánh khối static và phương thức main trong Java nhé.&lt;/span&gt;&lt;/h3&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Đặc điểm&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Khối static&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Phương thức main&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Mục đích&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Khởi tạo biến static, công việc chuẩn bị&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Điểm bắt đầu của chương trình&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Thời điểm thực thi&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Khi lớp được load&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Khi chương trình được chạy&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tham số&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Không có&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Mảng String&lt;a href="https://dev.to%C4%91%E1%BB%91i%20s%E1%BB%91%20d%C3%B2ng%20l%E1%BB%87nh"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Giá trị trả về&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Không&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;void (không có)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có thể gọi trực tiếp&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Không&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có (JVM gọi)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;br&gt;

</description>
      <category>từkhóastatictrongjava</category>
      <category>tukhoastatictrongjava</category>
      <category>thiskeywordsinjava</category>
      <category>tieushare</category>
    </item>
    <item>
      <title>Từ Khóa this (this Keywords) Trong Java Là Gì? Cách Sử Dụng Và Ví Dụ</title>
      <dc:creator>Tiểu Share</dc:creator>
      <pubDate>Wed, 04 Nov 2026 15:22:43 +0000</pubDate>
      <link>https://dev.to/tieushare/tu-khoa-this-this-keywords-trong-java-la-gi-cach-su-dung-va-vi-du-5767</link>
      <guid>https://dev.to/tieushare/tu-khoa-this-this-keywords-trong-java-la-gi-cach-su-dung-va-vi-du-5767</guid>
      <description>&lt;p&gt;&lt;span id="docs-internal-guid-00782da8-7fff-b1e1-4722-d2a46a541e2a"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;"Trong Java, từ khóa this là một công cụ mạnh mẽ trong lập trình hướng đối tượng, giúp giải quyết xung đột giữa các biến và làm cho mã nguồn trở nên rõ ràng hơn. Dưới đây là những điều cơ bản bạn cần biết về từ khóa this trong Java."&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;a href="https://www.tieushare.com/2026/10/tu-khoa-this-trong-java.html" rel="noopener noreferrer"&gt;&lt;b&gt;Từ khóa this trong Java &lt;/b&gt;&lt;/a&gt;được sử dụng để tham chiếu đến đối tượng của lớp hiện tại. Bằng cách sử dụng this, bạn có thể truy cập và thao tác với các thành phần của đối tượng đó như biến, phương thức, constructor và thậm chí là lớp lồng nhau. Việc này giúp cho mã nguồn trở nên rõ ràng hơn trong việc xử lý các tên biến trùng lặp (shadowing), gọi constructor từ constructor khác của cùng lớp, và quản lý phạm vi của các thành phần lớp.&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h3&gt;&lt;span&gt;Trong java, từ khóa this có 6 cách sử dụng như sau:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Từ khóa this có thể được dùng để truy cập tới biến instance của lớp hiện tại.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Từ khóa this có thể được dùng để gọi phương thức của lớp hiện tại.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Từ khóa this() có thể được dùng để gọi Constructor của lớp hiện tại.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Từ khóa this có thể được truyền như một tham số trong phương thức.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Từ khóa this có thể được truyền như một tham số trong phương Constructor.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Từ khóa this có thể được dùng để trả về instance của lớp hiện tại.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;span&gt;Lưu ý:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Trong lập trình, đặc biệt là lập trình hướng đối tượng (OOP), instance (hay còn gọi là thể hiện, đối tượng cụ thể) là một bản sao riêng biệt và không trùng lặp của một lớp (class). Lớp đóng vai trò như bản thiết kế, bản mẫu, trong khi instance là hiện thân thực tế của bản thiết kế đó. Ví dụ, nếu bạn có một lớp Car, thì khi bạn tạo một đối tượng Car, ví dụ Car myCar = new Car();, myCar là một thể hiện (instance) của lớp Car.&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzyBN-GP7eRrpcAQ2pzGteRlBNbpRBRODIfNOFGBsp-t43WGJjW3s1psDOOC-I5flBw5fJPcT4AzCem3hiO2qo0vfI90dPPDMx4SoND3clbyZA9TnzNVXW3Z-4CrVueSHQzAgZZGUW2Axmc3M29B7Sa5nl__rl9-lrWhsG_z-KGdG8ZgGzrXWHr6GNE8U/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả các chức năng của từ khóa this." src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEjzyBN-GP7eRrpcAQ2pzGteRlBNbpRBRODIfNOFGBsp-t43WGJjW3s1psDOOC-I5flBw5fJPcT4AzCem3hiO2qo0vfI90dPPDMx4SoND3clbyZA9TnzNVXW3Z-4CrVueSHQzAgZZGUW2Axmc3M29B7Sa5nl__rl9-lrWhsG_z-KGdG8ZgGzrXWHr6GNE8U%2Fs1600%2Fimage.png" title="Ảnh mô tả các chức năng của từ khóa this." width="800" height="450"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Ảnh mô tả các chức năng của từ khóa this.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅰ. Từ khóa this dùng để truy cập tới biến instance của lớp hiện tại.&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Từ khóa this được dùng để tham chiếu đến biến instance (còn gọi là thuộc tính) của đối tượng hiện tại. Nó hữu ích trong trường hợp tên biến instance trùng với tên tham số của phương thức.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Trong ví dụ, có khả năng xảy ra nhầm lẫn:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Biến name được khai báo bên trong lớp (biến instance).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tham số name được truyền vào phương thức (tham số).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Nếu không dùng this, compiler (trình biên dịch) sẽ khó xác định bạn muốn sử dụng biến instance name hay tham số name.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
 &lt;b&gt;Point.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;// Định nghĩa lớp Point với hai thuộc tính x và y&lt;br&gt;
public class Point {&lt;br&gt;
    public int x = 0; // Biến instance 'x'&lt;br&gt;
    public int y = 0; // Biến instance 'y'

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp Point, nhận vào hai tham số int và gán giá trị cho x và y
public Point(int x, int y) { // Tham số 'x' và 'y'
    x = x; // Không dùng this
    y = y;
}
public void display() {
    System.out.println("Toạ độ điểm x= "+ x + ", y= "+y);
}
public static void main(String args[]) {
    Point point1 = new Point(50, 50);
    Point point2 = new Point(100, 100);
    point1.display();
    point2.display();  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Toạ độ điểm x= 0, y= 0&lt;br&gt;
Toạ độ điểm x= 0, y= 0&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;&lt;span&gt;Sử dụng this giải quyết vấn đề&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Bằng cách sử dụng this.Tên_Biến trước tên biến instance, bạn rõ ràng chỉ ra cho compiler rằng bạn muốn truy cập vào biến instance name thuộc về đối tượng hiện tại.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Point.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;// Định nghĩa lớp Point với hai thuộc tính x và y&lt;br&gt;
public class Point {&lt;br&gt;
    public int x = 0; // Biến instance 'x'&lt;br&gt;
    public int y = 0;// Biến instance 'y'

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp Point, nhận vào hai tham số int và gán giá trị cho x và y
public Point(int x, int y) {// Tham số 'x và y'
    this.x = x; // Dùng từ khóa this
    this.y = y;
}
public void display() {
    System.out.println("Toạ độ điểm x= "+ x + ", y= "+y);
}
public static void main(String args[]) {
    Point point1 = new Point(50, 50);
    Point point2 = new Point(100, 100);
    point1.display();
    point2.display();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Toạ độ điểm x= 50, y= 50&lt;br&gt;
Toạ độ điểm x= 100, y= 100&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;&lt;span&gt;Gán giá trị để giải quyết vấn đề:&lt;/span&gt;&lt;/h3&gt;
&lt;br&gt;
&lt;b&gt;Point.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;// Định nghĩa lớp Point với hai thuộc tính x và y&lt;br&gt;
public class Point {&lt;br&gt;
    public int x = 0; // Biến instance 'x'&lt;br&gt;
    public int y = 0;// Biến instance 'y'

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp Point, nhận vào hai tham số int và gán giá trị cho n và m
public Point(int n, int m) {
     x = n; // Không cần phải sử dụng this vì tên không trùng
     y = m;
}
public void display() {
    System.out.println("Toạ độ điểm x= "+ x + ", y= "+ y);
}
public static void main(String args[]) {
    Point point1 = new Point(50, 50);
    Point point2 = new Point(100, 100);
    point1.display();
    point2.display();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Toạ độ điểm x= 50, y= 50&lt;br&gt;
Toạ độ điểm x= 100, y= 100 &lt;/code&gt;&lt;/pre&gt;



&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅱ. Từ khóa this dùng để gọi phương thức của lớp hiện tại.&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;&lt;a href="https://www.tieushare.com/2026/10/tu-khoa-this-trong-java.html" rel="noopener noreferrer"&gt;&lt;b&gt;Từ khóa this trong Java &lt;/b&gt;&lt;/a&gt;không chỉ dùng để truy cập biến instance mà còn có thể gọi các phương thức (method) của lớp hiện tại. Việc sử dụng this làm rõ ràng bạn đang gọi phương thức của lớp hiện tại, tránh nhầm lẫn với phương thức của lớp khác. Bằng cách sử dụng this.Tên_Phương thức trước tên phương thức (Methods) và tham số của phương thức nếu có.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Person.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;class Person {&lt;br&gt;
    String name; // Biến instance 'name' để lưu tên của đối tượng Person

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp Person, nhận một tham số là tên và gán nó cho biến 'name'
public Person(String name) {
    this.name = name;
}

// Phương thức greet() để in ra lời chào kèm theo tên của đối tượng
public void greet() {
    System.out.println("Xin chào, tên của tôi là: " + this.name);
}

// Phương thức introduce() để gọi phương thức greet()
public void introduce() {
    this.greet(); // Gọi phương thức 'greet()' của lớp hiện tại
}

// Phương thức main để chạy chương trình
public static void main(String[] args) {
    // Tạo một đối tượng Person với tên "VTD"
    Person person = new Person("VTD");
    // Gọi phương thức introduce() của đối tượng person
    person.introduce();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Xin chào, tên của tôi là: VTD&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong phương thức introduce(), từ khóa this được sử dụng để gọi các phương thức greet() của đối tượng hiện tại. Điều này làm cho code trở nên rõ ràng và dễ đọc hơn, cho thấy rằng các phương thức này thuộc về đối tượng hiện tại của lớp Person.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Trong nhiều trường hợp, nếu bạn không sử dụng từ khóa this để gọi một phương thức của lớp hiện tại, trình biên dịch Java sẽ tự động thêm nó cho bạn. Điều này có nghĩa là việc gọi một phương thức mà không có từ khóa this sẽ hoạt động tương tự như khi bạn gọi phương thức đó với từ khóa this.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Person.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;/class Person {&lt;br&gt;
    String name; // Biến instance 'name' để lưu tên của đối tượng Person

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp Person, nhận một tham số là tên và gán nó cho biến 'name'
public Person(String name) {
    this.name = name;
}

// Phương thức greet() để in ra lời chào kèm theo tên của đối tượng
public void greet() {
    System.out.println("Xin chào, tên của tôi là: " + this.name);
}
public void Support() {
    System.out.println("Tôi có thể giúp gì được cho bạn " );
}

// Phương thức introduce() để gọi phương thức greet() và  Support() của lớp hiện tại
public void introduce() {
    greet(); // Không dùng từ khóa this
    Support();
}

// Phương thức main để chạy chương trình
public static void main(String[] args) {
    // Tạo một đối tượng Person với tên "VTD"
    Person person = new Person("VTD");
    // Gọi phương thức introduce() của đối tượng person
    person.introduce();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Xin chào, tên của tôi là: VTD&lt;br&gt;
Tôi có thể giúp gì được cho bạn&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong ví dụ trên, trình biên dịch sẽ tự động hiểu rằng các phương thức này thuộc về đối tượng hiện tại và thêm từ khóa this một cách ngầm định.&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_xZvMnweaDZgKFt6f2xKyL9TDgCbrQ2kTIhNqWbK5TzlQJNKtm2St3nmCfwr5wqm8ZaeK4uIfNEZevo1h79GjsES4tD6-A9tctGaVkOJ7ZypLbcEVfnZyS7LQysb87lWqCyu6C061J6Z02dR-8dzqqFNpLfanQ36ZaLcXw2c6jxm2FZlnAJG78I3RyKA/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả trình biên dịch sẽ thêm từ khóa this một cách ngầm định." src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEh_xZvMnweaDZgKFt6f2xKyL9TDgCbrQ2kTIhNqWbK5TzlQJNKtm2St3nmCfwr5wqm8ZaeK4uIfNEZevo1h79GjsES4tD6-A9tctGaVkOJ7ZypLbcEVfnZyS7LQysb87lWqCyu6C061J6Z02dR-8dzqqFNpLfanQ36ZaLcXw2c6jxm2FZlnAJG78I3RyKA%2Fs1600%2Fimage.png" title="Ảnh mô tả trình biên dịch sẽ thêm từ khóa this một cách ngầm định." width="800" height="450"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Ảnh mô tả trình biên dịch sẽ thêm từ khóa this một cách ngầm định.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅲ. Từ khóa this() dùng để gọi constructor của lớp hiện tại.&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Từ khóa this() được sử dụng để gọi một constructor khác trong cùng một lớp. this() chỉ được phép xuất hiện duy nhất một lần và luôn phải là câu lệnh đầu tiên được viết trong constructor. Cú pháp của nó như sau: this(tham số của constructor).&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Person.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;public class Person {&lt;br&gt;
    // Các biến instance để lưu tên và tuổi của đối tượng Person&lt;br&gt;
    private String name;&lt;br&gt;
    private int age;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor mặc định, không có tham số
public Person() {
    this("Constructor mặc định", 0); // Gọi constructor có hai tham số với giá trị mặc định
}

// Constructor với một tham số, chỉ định tên
public Person(String name) {
    this(name, 1); // Gọi constructor có hai tham số, với tuổi mặc định là 1
}

// Constructor với hai tham số, chỉ định cả tên và tuổi
public Person(String name, int age) {
    this.name = name;
    this.age = age; // Gán giá trị tham số cho các biến instance
}

// Phương thức display() để in ra tên và tuổi của đối tượng
public void display() {
    System.out.println("Tên: " + name + ", Tuổi: " + age);
}

// Phương thức main để chạy chương trình
public static void main(String[] args) {
    // Tạo các đối tượng Person với các constructor khác nhau
    Person person1 = new Person(); // Sử dụng constructor mặc định
    Person person2 = new Person("Constructor với một tham số"); // Sử dụng constructor với một tham số
    Person person3 = new Person("Constructor với hai tham số", 2); // Sử dụng constructor với hai tham số

    // Gọi phương thức display() của từng đối tượng để in ra thông tin
    person1.display();
    person2.display();
    person3.display();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Tên: Constructor mặc định, Tuổi: 0&lt;br&gt;
Tên: Constructor với một tham số, Tuổi: 1&lt;br&gt;
Tên: Constructor với hai tham số, Tuổi: 2&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong ví dụ này, việc sử dụng từ khóa this() giúp tránh lặp lại mã và thiết lập các giá trị mặc định cho các biến thành viên một cách hiệu quả.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅳ. Từ khóa this được truyền như một tham số trong phương thức.&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Từ khóa this có thể được truyền như một tham số cho các phương thức khác. Việc sử dụng này ít phổ biến hơn so với các trường hợp sử dụng this khác, nhưng nó có thể hữu ích trong một số tình huống cụ thể. Cú pháp của nó như sau: Tên_Phươngthức(this).&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Student.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;class Student {&lt;br&gt;
    int id; // Biến instance 'id' để lưu mã số sinh viên&lt;br&gt;
    String name; // Biến instance 'name' để lưu tên của sinh viên

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp Student, nhận hai tham số và gán chúng cho các biến instance
Student(int id, String name) {
    this.id = id;
    this.name = name;
}

// Phương thức display() để in ra mã số sinh viên và tên sinh viên
void display() {
    System.out.println("Mã: " + id + ", Tên: " + name);
}

// Phương thức updateName() để cập nhật tên của đối tượng Student được truyền vào
void updateName(Student student, String newName) {
    student.name = newName;
}

// Phương thức changeName() để thay đổi tên của đối tượng hiện tại
void changeName(String newName) {
    updateName(this, newName); // Gọi phương thức updateName() với đối tượng hiện tại
}

// Phương thức main để chạy chương trình
public static void main(String[] args) {
    // Tạo một đối tượng Student với mã số 1 và tên "Vương"
    Student student = new Student(1, "Vương");
    // Gọi phương thức display() để in ra thông tin sinh viên
    student.display(); // Kết quả: ID: 1, Name: Vương

    // Gọi phương thức changeName() để thay đổi tên của sinh viên thành "Trường"
    student.changeName("Trường");
    // Gọi phương thức display() để in ra thông tin sinh viên đã cập nhật
    student.display(); // Kết quả: ID: 1, Name: Trường
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Mã: 1, Tên: Vương&lt;br&gt;
Mã: 1, Tên: Trường&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Hy vọng ví dụ này giúp bạn hiểu rõ hơn về việc sử dụng từ khóa this được truyền như một tham số trong phương thức!&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅴ. Từ khóa this được truyền như một tham số trong constructor.&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Trong một số trường hợp hiếm hoi, bạn có thể truyền this (đối tượng hiện tại) làm tham số cho một constructor khác. Có nghĩa là bạn đang chuyển đối tượng hiện tại của lớp đó vào constructor của một lớp khác. Điều này có thể hữu ích khi bạn cần chia sẻ dữ liệu hoặc hành động giữa các đối tượng liên quan. Cú pháp của nó như sau: this.Tên_đốitượng.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Person.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;// Định nghĩa lớp Person để biểu diễn một người có tên và tuổi&lt;br&gt;
class Person {&lt;br&gt;
    String name; // Biến instance lưu trữ tên của người&lt;br&gt;
    int age; // Biến instance lưu trữ tuổi của người

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp Person, nhận tham số là tên và tuổi, và gán cho các biến instance tương ứng
Person(String name, int age) {
    this.name = name;
    this.age = age;
}

// Phương thức displayInfo() in ra thông tin tên và tuổi của người
void displayInfo() {
    System.out.println("Tên: " + name);
    System.out.println("Tuổi: " + age);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// Định nghĩa lớp Address để biểu diễn địa chỉ có thành phố, quốc gia và một đối tượng Person&lt;br&gt;
class Address {&lt;br&gt;
    String city; // Biến instance lưu trữ tên thành phố&lt;br&gt;
    String country; // Biến instance lưu trữ tên quốc gia&lt;br&gt;
    Person person; // Biến instance lưu trữ thông tin của một đối tượng Person&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp Address, nhận tham số là thành phố, quốc gia và một đối tượng Person, và gán cho các biến instance tương ứng
Address(String city, String country, Person person) {
    this.city = city;
    this.country = country;
    this.person = person;
}

// Phương thức displayAddress() in ra thông tin của đối tượng Person và địa chỉ
void displayAddress() {
    person.displayInfo(); // Gọi phương thức displayInfo() của đối tượng Person để in ra thông tin tên và tuổi
    System.out.println("Thành Phố: " + city); // In ra tên thành phố
    System.out.println("Quốc Gia: " + country); // In ra tên quốc gia
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;// Lớp chính MainClass để chạy chương trình&lt;br&gt;&lt;br&gt;
public class MainClass {&lt;br&gt;&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;&lt;br&gt;
        Person person = new Person("Vương", 27); &lt;br&gt;&lt;br&gt;
        Address address = new Address("Đà Nẵng", "Việt Nam", person); &lt;br&gt;&lt;br&gt;
        address.displayAddress(); // Gọi phương thức displayAddress() của đối tượng Address để in ra thông tin địa chỉ và đối tượng Person&lt;br&gt;&lt;br&gt;
    }&lt;br&gt;&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Tên: Vương&lt;br&gt;
Tuổi: 27&lt;br&gt;
Thành Phố: Đà Nẵng&lt;br&gt;
Quốc Gia: Việt Nam &lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong ví dụ này, từ khóa this được sử dụng để truyền đối tượng hiện tại vào constructor hoặc phương thức khác, giúp chia sẻ thông tin giữa các đối tượng một cách dễ dàng.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅵ. Từ khóa this được dùng để trả về instance của lớp hiện tại.&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Khi bạn sử dụng this để trả về thể hiện của lớp hiện tại, có nghĩa là bạn đang yêu cầu Java trả về đối tượng đang thực thi phương thức hiện tại. Điều này thường được sử dụng trong các phương thức để trả về chính đối tượng mà phương thức đang thao tác. Cú pháp của nó như sau:&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Cú Pháp&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;Kiểu_trảvề Tên_Phươngthức(){

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return this;
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p class="syntax-heading" dir="ltr"&amp;gt;
  &amp;lt;svg aria-label="Example" class="syntax-icon" role="img" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"&amp;gt;
    &amp;lt;path d="M6 2.75h8l4 4V21.25H6a2 2 0 0 1-2-2V4.75a2 2 0 0 1 2-2Z"&amp;gt;
    &amp;lt;path d="M14 2.75v4h4"&amp;gt;
    &amp;lt;path d="m10 11-2 2 2 2m4-4 2 2-2 2"&amp;gt;
  &amp;lt;/path&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;/svg&amp;gt;
  &amp;lt;b class="syntax-title"&amp;gt;Book.java&amp;lt;/b&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;pre&gt;&lt;code&gt;public class Book {&lt;br&gt;
    private String title; // Biến instance để lưu trữ tiêu đề sách&lt;br&gt;
    private String author; // Biến instance để lưu trữ tác giả của sách

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp Book, khởi tạo đối tượng Book với tiêu đề và tác giả
public Book(String title, String author) {
    this.title = title;
    this.author = author;
}

// Phương thức setTitle để thay đổi tiêu đề sách
public void setTitle(String newTitle) {
    this.title = newTitle;
}

// Phương thức getCurrentBook trả về chính đối tượng Book hiện tại
public Book getCurrentBook() {
    return this;
}

// Phương thức displayInfo để hiển thị thông tin của cuốn sách
public void displayInfo() {
    System.out.println("Tiêu đề: " + title);
    System.out.println("Tác giả: " + author);
}

// Phương thức main để chạy chương trình
public static void main(String[] args) {
    // Tạo một đối tượng Book mới với tiêu đề "Lập trình java" và tác giả "Java"
    Book myBook = new Book("Lập trình java", "Java");

    // Đặt lại tiêu đề của sách
    myBook.setTitle("Lập trình hướng đối tượng trong Java");

    // Lấy đối tượng Book hiện tại thông qua phương thức getCurrentBook()
    Book currentBook = myBook.getCurrentBook();

    // In ra thông tin của cuốn sách hiện tại
    System.out.println("Thông tin cuốn sách hiện tại:");
    currentBook.displayInfo();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Thông tin cuốn sách hiện tại:&lt;br&gt;
Tiêu đề: Lập trình hướng đối tượng trong Java&lt;br&gt;
Tác giả: Java&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong ví dụ này, khi chạy chương trình chúng ta thấy rằng việc sử dụng this trong phương thức getCurrentBook() đã giúp chúng ta trả về đúng thể hiện (instance) của lớp Book hiện tại mà phương thức đang hoạt động.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;b&gt;Lưu ý:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;this chỉ có thể được sử dụng để trả về instance của lớp hiện tại từ một phương thức instance.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Chứng minh từ khóa this&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Hãy chứng minh rằng từ khóa this tham chiếu đến biến instance của lớp hiện tại. Trong chương trình này, chúng ta đang in ra biến tham chiếu và this, đầu ra của cả hai biến đều giống nhau.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Book.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;public class Book {&lt;br&gt;
    private String title; // Biến private để lưu trữ tiêu đề của sách

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp Book, nhận một tham số là tiêu đề và gán nó cho biến 'title'
public Book(String title) {
    this.title = title;
}

// Phương thức printCurrentBook() để in ra thông tin về cuốn sách hiện tại
public void printCurrentBook() {
    System.out.println("Cuốn sách hiện tại: " + this.title);
}

// Phương thức main để chạy chương trình
public static void main(String[] args) {
    // Tạo một đối tượng Book với tiêu đề "Lập trình Java"
    Book book1 = new Book("Lập trình Java");
    // Gọi phương thức printCurrentBook() của đối tượng book1
    book1.printCurrentBook();

    // Tạo một đối tượng Book với tiêu đề "Cấu trúc dữ liệu"
    Book book2 = new Book("Cấu trúc dữ liệu");
    // Gọi phương thức printCurrentBook() của đối tượng book2
    book2.printCurrentBook();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Cuốn sách hiện tại: Lập trình Java&lt;br&gt;
Cuốn sách hiện tại: Cấu trúc dữ liệu&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong ví dụ này, từ khóa this được sử dụng để chỉ rõ rằng title được truy cập là của đối tượng hiện tại mà phương thức printCurrentBook() đang thao tác.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;

</description>
      <category>thiskeywordstrongjava</category>
      <category>từkhóathistrongjava</category>
      <category>tukhoathistrongjava</category>
      <category>tieushare</category>
    </item>
    <item>
      <title>Constructor (Hàm Khởi Tạo) trong Java là gì? Cách sử dụng và ví dụ</title>
      <dc:creator>Tiểu Share</dc:creator>
      <pubDate>Tue, 03 Nov 2026 10:29:32 +0000</pubDate>
      <link>https://dev.to/tieushare/constructor-ham-khoi-tao-trong-java-la-gi-cach-su-dung-va-vi-du-49f1</link>
      <guid>https://dev.to/tieushare/constructor-ham-khoi-tao-trong-java-la-gi-cach-su-dung-va-vi-du-49f1</guid>
      <description>&lt;p&gt;&lt;span id="docs-internal-guid-1b1c1851-7fff-4d23-c9ee-9629c479bdc2"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;"&lt;b&gt;Trong Java, Constructor (hàm khởi tạo) &lt;/b&gt;là một thành phần không thể thiếu trong lập trình hướng đối tượng, giúp khởi tạo đối tượng một cách hiệu quả và linh hoạt. Dưới đây là những điều cơ bản bạn cần biết về Constructor trong Java."&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅰ. &lt;a href="https://www.tieushare.com/2026/10/constructor-trong-java.html" rel="noopener noreferrer"&gt;Constructor (Hàm khởi tạo) trong Java là gì?&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Constructor (hàm khởi tạo) là một loại phương thức đặc biệt được sử dụng để khởi tạo đối tượng trong Java. Constructor có cùng tên với lớp mà nó thuộc về và không có kiểu trả về (không có void, int, v.v.).&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Đặc điểm của Constructor (Hàm khởi tạo):&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Tên Constructor trùng với tên lớp: &lt;/span&gt;&lt;span&gt;Đây là điểm phân biệt chính giữa constructor và các phương thức khác.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Không có kiểu trả về: &lt;/span&gt;&lt;span&gt;Constructor không có kiểu trả về, kể cả void.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tự động được gọi khi tạo đối tượng: &lt;/span&gt;&lt;span&gt;Khi bạn tạo một đối tượng mới bằng từ khóa new, constructor tương ứng sẽ được gọi tự động để khởi tạo đối tượng đó.&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅱ. Các loại Constructor (Hàm khởi tạo)&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Có thể có nhiều constructor khác nhau cho cùng một lớp, được phân biệt bởi số lượng và kiểu của các tham số:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;↳ Constructor không có tham số (No-arg constructor)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Constructor có tham số (Parameterized constructor)&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpMLI2DIJqhZ6oQ_G8zu_X1vA-WljQtVHDFCRpu-Z1qZyOGW3-9kK92It9_Y2QzRJeJLMjFkGUL-hmUohnYeX8OPcLGJ3UGRl0R_RgqO6OaRHQcoCzzWvaDW8HDL9G3xUYcmoaZUSC4Kfy1OLCdnFvVk9s_E3MpIKwg50_azQMy0hrTo2hA3C1uuyjfbk/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả các loại constructor trong java." src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEjpMLI2DIJqhZ6oQ_G8zu_X1vA-WljQtVHDFCRpu-Z1qZyOGW3-9kK92It9_Y2QzRJeJLMjFkGUL-hmUohnYeX8OPcLGJ3UGRl0R_RgqO6OaRHQcoCzzWvaDW8HDL9G3xUYcmoaZUSC4Kfy1OLCdnFvVk9s_E3MpIKwg50_azQMy0hrTo2hA3C1uuyjfbk%2Fs1600%2Fimage.png" title="Ảnh mô tả các loại constructor trong java." width="800" height="450"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Ảnh mô tả các loại constructor trong java.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;&lt;span&gt;&lt;b&gt;1. &lt;a href="https://www.tieushare.com/2026/10/constructor-trong-java.html" rel="noopener noreferrer"&gt;Constructor không có tham số (No-arg constructor)&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;hay còn gọi constructor mặc đinh khi không có bất kì tham số nào được truyền vào. Được cung cấp tự động bởi trình biên dịch Java nếu bạn không định nghĩa bất kỳ constructor nào.&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;&lt;b&gt;Cú pháp Constructor không có tham số (No-arg constructor):&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;br&gt;
&lt;b&gt;Cú Pháp&lt;/b&gt;&lt;br&gt;
  &lt;pre&gt;&lt;code&gt;Tên_Class() {&lt;br&gt;
    // Constructor mặc định do trình biên dịch tự động tạo ra&lt;br&gt;
}&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;b&gt;MyClass.java&lt;/b&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;public class MyClass {&lt;br&gt;
    // Constructor mặc định do trình biên dịch tự động tạo ra&lt;br&gt;
    MyClass(){&lt;br&gt;
        System.out.println("Đây là lớp học của tôi");&lt;br&gt;
    }&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        MyClass myclass = new MyClass();&lt;br&gt;
    }&lt;br&gt;
}&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Đây là lớp học của tôi&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Quy tắc: &lt;/span&gt;&lt;span&gt;Nếu không có hàm tạo (constructor) nào được định nghĩa trong một lớp, trình biên dịch Java sẽ tự động tạo ra một hàm tạo mặc định (default constructor).&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNqdkfk1Ysh1kaTVkqmVRrXfmbnj8wkTwKgDJXhGpR23wyp-aBNiP3zGvpo__bPlwBGw5Drm8PZ4wklVCTSzk72Ykr9eA-978UEGZsC7ZghHpoONZSDnk2jR9t6SqKKmSiHWLmJdgY6IQzTO4Xt_UOuvG-FriV5VMlHoAc0AvNVfhkIy9lL49X7GxV0Tk/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả constructor không có tham số sẽ được thêm vào bởi trình biên dịch." src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEiNqdkfk1Ysh1kaTVkqmVRrXfmbnj8wkTwKgDJXhGpR23wyp-aBNiP3zGvpo__bPlwBGw5Drm8PZ4wklVCTSzk72Ykr9eA-978UEGZsC7ZghHpoONZSDnk2jR9t6SqKKmSiHWLmJdgY6IQzTO4Xt_UOuvG-FriV5VMlHoAc0AvNVfhkIy9lL49X7GxV0Tk%2Fs1600%2Fimage.png" title="Ảnh mô tả constructor không có tham số sẽ được thêm vào bởi trình biên dịch." width="800" height="450"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Ảnh mô tả constructor không có tham số sẽ được thêm vào bởi trình biên dịch.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;&lt;span&gt;Mục đích của constructor mặc định là gì?&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;Hàm tạo mặc định là một loại hàm tạo đặc biệt. Nó được gọi tự động khi bạn tạo một đối tượng của lớp mà không cung cấp giá trị khởi tạo nào. Mục đích chính của hàm tạo mặc định là gán các giá trị mặc định cho các thuộc tính (property) của đối tượng mới.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;b&gt;Ví dụ về các giá trị mặc định:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Số nguyên (int): 0&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Số thực (double): 0.0&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Kiểu logic (boolean): false&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Chuỗi (String): null&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Kiểu dữ liệu tham chiếu (reference type): null&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Hàm tạo mặc định giúp bạn dễ dàng tạo các đối tượng với các giá trị khởi đầu hợp lý, đảm bảo chúng hoạt động chính xác ngay cả khi bạn không cung cấp giá trị cụ thể khi tạo.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;MyClass.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;public class MyClass {&lt;br&gt;
    // Constructor mặc định do trình biên dịch tự động tạo ra&lt;br&gt;
    int a;&lt;br&gt;
    String b;&lt;br&gt;
    void ThongTin(){&lt;br&gt;
        System.out.println("Đây là số nguyên: "+a);&lt;br&gt;
        System.out.println("Đây là một chuỗi: "+b);&lt;br&gt;
    }&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        MyClass myclass = new MyClass();&lt;br&gt;
        myclass.ThongTin();&lt;br&gt;
    }&lt;br&gt;
}&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Đây là số nguyên: 0&lt;br&gt;
Đây là một chuỗi: null&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong chương trình trên, mặc dù bạn không tạo bất kì constructor nào nhưng trình biên dịch vẫn cung cấp cho bạn một constructor mặc đinh. Giá trị 0 và null ở kết quả chương trình được cung cấp bởi constructor mặc định.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;2. &lt;a href="https://www.tieushare.com/2026/10/constructor-trong-java.html" rel="noopener noreferrer"&gt;Constructor có tham số (Parameterized constructor)&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Constructor cho phép truyền một hoặc nhiều tham số để cung cấp giá trị khởi tạo cho các thuộc tính của đối tượng. Được sử dụng để khởi tạo đối tượng với các giá trị khác nhau.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;MyClass.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;public class MyClass {&lt;br&gt;
        int MSV;&lt;br&gt;
        String Tên;&lt;br&gt;
        // Constructor có tham số&lt;br&gt;
        public MyClass(int a) {&lt;br&gt;
            MSV = a;&lt;br&gt;
            System.out.println("Mã sinh viên: "+a);&lt;br&gt;
        }&lt;br&gt;
        public MyClass(int a,String b) {&lt;br&gt;
            MSV = a;&lt;br&gt;
            Tên = b;&lt;br&gt;
            System.out.println("Mã sinh viên: "+ a +" Tên: "+b);&lt;br&gt;
        } &lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        MyClass myclass = new MyClass(227520004);&lt;br&gt;&lt;br&gt;
        MyClass myclass1 = new MyClass(227520005,"VTD");&lt;br&gt;
    }&lt;br&gt;
}&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Mã sinh viên: 227520004&lt;br&gt;
Mã sinh viên: 227520005 Tên: VTD&lt;/code&gt;&lt;/pre&gt;



&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅲ. Quá tải hàm khởi tạo (Constructor Overloading) trong Java&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Trong lập trình Java, hàm khởi tạo (constructor) là một phương thức đặc biệt dùng để tạo và khởi tạo các đối tượng mới. Nó giống như một công thức để "nặn ra" các đối tượng thuộc về một lớp (class) nào đó.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Quá Tải Hàm Khởi Tạo (Constructor Overloading) là kỹ thuật hay ho cho phép bạn định nghĩa nhiều hàm khởi tạo khác nhau cho cùng một lớp. Mỗi hàm khởi tạo này sẽ có một danh sách tham số (parameter list) riêng, giúp bạn cung cấp các giá trị ban đầu khác nhau cho các thuộc tính (property) của đối tượng.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Cách phân biệt các hàm khởi tạo trùng tải:&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Trình biên dịch Java sẽ phân biệt các hàm khởi tạo dựa vào số lượng tham số và kiểu dữ liệu của chúng.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Mỗi hàm khởi tạo cần có danh sách tham số duy nhất.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;MyClass.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;public class MyClass {&lt;br&gt;
        int MSV;&lt;br&gt;
        String Tên;&lt;br&gt;
        int Tuoi;&lt;br&gt;
        // Constructor có tham số&lt;br&gt;
        public MyClass(int a) {&lt;br&gt;
            MSV = a;&lt;br&gt;
            System.out.println("Mã sinh viên: "+a);&lt;br&gt;
        }&lt;br&gt;
        public MyClass(int a,String b) {&lt;br&gt;
            MSV = a;&lt;br&gt;
            Tên = b;&lt;br&gt;
            System.out.println("Mã sinh viên: "+ a +" Tên: "+b);&lt;br&gt;
        }&lt;br&gt;&lt;br&gt;
        public MyClass(int a,String b, int c) {&lt;br&gt;
            MSV = a;&lt;br&gt;
            Tên = b;&lt;br&gt;
            Tuoi = c;&lt;br&gt;
            System.out.println("Mã sinh viên: "+ a +" Tên: "+b+" Tuổi: "+c);&lt;br&gt;
        } 

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static void main(String[] args) {
    MyClass myclass = new MyClass(227520004);  
    MyClass myclass1 = new MyClass(227520005,"VTD");
    MyClass myclass2 = new MyClass(227520005,"VTD",27);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Mã sinh viên: 227520004&lt;br&gt;
Mã sinh viên: 227520005 Tên: VTD&lt;br&gt;
Mã sinh viên: 227520005 Tên: VTD Tuổi: 27&lt;/code&gt;&lt;/pre&gt;



&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅳ. Sao chép Constructor (Hàm khởi tạo) trong Java&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Trong Java, không tồn tại khái niệm Hàm Sao Chép (copy constructor) giống như trong C++. Tuy nhiên, chúng ta có thể sao chép các giá trị từ một đối tượng này sang một đối tượng khác tương tự như Sao Chép (copy constructor) trong C++.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;&lt;b&gt;Các cách sao chép giá trị đối tượng trong Java:&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Sử dụng Constructor: &lt;/span&gt;&lt;span&gt;Đây là một cách để sao chép giá trị trong quá trình tạo đối tượng mới.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Gán Trực Tiếp: &lt;/span&gt;&lt;span&gt;Bạn có thể gán giá trị của các thuộc tính từ một đối tượng sang một đối tượng khác.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Phương thức clone(): &lt;/span&gt;&lt;span&gt;Lớp Object cung cấp phương thức clone() để tạo ra một bản sao của đối tượng.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Ví dụ: Sao chép giá trị đối tượng bằng Constructor&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Mặc dù Java không có hàm sao chép theo đúng nghĩa, bạn có thể mô phỏng hành vi sao chép bằng cách tạo một constructor mới nhận đối tượng hiện có làm tham số và gán các giá trị của nó cho đối tượng mới.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;MyClass.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;class SinhVien {&lt;br&gt;
    String hoTen;&lt;br&gt;
    int maSV;&lt;br&gt;
    double diemSo;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor bình thường
public SinhVien(String hoTen, int maSV, double diemSo) {
    this.hoTen = hoTen;
    this.maSV = maSV;
    this.diemSo = diemSo;
}
// Phương thức để hiển thị thông tin sinh viên
public void hienThiThongTin() {
    System.out.println("Họ Tên: " + hoTen);
    System.out.println("Mã SV: " + maSV);
    System.out.println("Điểm Số: " + diemSo);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;}&lt;br&gt;
public class Main {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        // Tạo một đối tượng SinhVien&lt;br&gt;
        SinhVien sv1 = new SinhVien("Nguyen Van A", 11111, 8.5);&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Tạo đối tượng SinhVien thứ hai với điểm số là 0
    SinhVien sv2 = new SinhVien("Nguyen Van B",22222, 0);
    // Sao điểm số của sv1 gán cho sv2
    sv2.diemSo = sv1.diemSo;

    // Hiển thị thông tin của cả hai đối tượng
    System.out.println("Thông tin sinh viên 1:");
    sv1.hienThiThongTin();

    System.out.println("\nThông tin sinh viên 2:");
    sv2.hienThiThongTin();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Thông tin sinh viên 1:&lt;br&gt;
Họ Tên: Nguyen Van A&lt;br&gt;
Mã SV: 11111&lt;br&gt;
Điểm Số: 8.5

&lt;/code&gt;&lt;p&gt;&lt;code&gt;Thông tin sinh viên 2:&lt;br&gt;&lt;br&gt;
Họ Tên: Nguyen Van B&lt;br&gt;&lt;br&gt;
Mã SV: 22222&lt;br&gt;&lt;br&gt;
Điểm Số: 8.5&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong ví dụ này, khi chạy chương trình bạn sẽ thấy rằng cả hai đối tượng sv1 và sv2 đều chứa cùng một điểm số là 8.5, cho thấy rằng chúng ta đã sao chép thành công các giá trị diemso từ sv1 sang sv2 bằng cách gán giá trị diemso.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅴ. Sự khác nhau giữa constructor (Hàm khởi tạo) và Method (Phương thức) trong java&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Constructor (Hàm khởi tạo) và Method (Phương thức) là hai thành phần quan trọng trong lập trình Java. Tuy nhiên, chúng có những đặc điểm riêng biệt:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Điểm giống nhau: &lt;/span&gt;&lt;span&gt;Đều thuộc về lớp (class), cả constructor và method đều được định nghĩa bên trong một lớp và có thể truy cập được từ các đối tượng của lớp đó.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Điểm khác nhau:&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Đặc điểm&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Constructor&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Phương thức&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Mục đích&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tạo và khởi tạo đối tượng mới.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Thực hiện các hành động cụ thể trên đối tượng.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tên&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Giống tên lớp.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tự do đặt tên.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Kiểu trả về&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Không có kiểu trả về.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có thể trả về giá trị (kiểu dữ liệu) hoặc không trả về (void).&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Gọi&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tự động gọi khi tạo đối tượng mới bằng toán tử new.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Gọi bằng cách sử dụng tên phương thức và đối tượng.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Overloading&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có thể trùng tải dựa vào danh sách tham số.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có thể trùng tải dựa vào danh sách tham số.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Mặc định&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có thể có constructor mặc định do trình biên dịch tự động tạo.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Không có phương thức mặc định.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



</description>
      <category>constructortrongjava</category>
      <category>constructorinjava</category>
      <category>hàmkhởitạotrongjava</category>
      <category>tieushare</category>
    </item>
    <item>
      <title>Lớp (Class) trong Java là gì? | Cú pháp và ví dụ dễ hiểu</title>
      <dc:creator>Tiểu Share</dc:creator>
      <pubDate>Mon, 02 Nov 2026 12:43:16 +0000</pubDate>
      <link>https://dev.to/tieushare/lop-class-trong-java-la-gi-cu-phap-va-vi-du-de-hieu-1n81</link>
      <guid>https://dev.to/tieushare/lop-class-trong-java-la-gi-cu-phap-va-vi-du-de-hieu-1n81</guid>
      <description>&lt;p&gt;&lt;span id="docs-internal-guid-1f22b300-7fff-c1f6-7de9-def075ebc4dd"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;"Trong Java, class (lớp) là một khái niệm cơ bản và quan trọng trong lập trình hướng đối tượng. Dưới đây là những điểm cơ bản về lớp trong Java."&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅰ. &lt;a href="https://www.tieushare.com/2026/10/lop-class-trong-java.html" rel="noopener noreferrer"&gt;Lớp (Class) trong Java &lt;/a&gt;là gì?&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Là một bản thiết kế hoặc mô tả chi tiết cho một nhóm các đối tượng có chung đặc điểm và hành vi.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Xác định các thuộc tính và phương thức chung cho các đối tượng thuộc lớp đó.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ &lt;/span&gt;&lt;span&gt;Giống như một khuôn mẫu để tạo ra các đối tượng cụ thể.&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅱ. Các thành phần chính của một lớp (Class)&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Một lớp trong Java có thể chứa rất nhiều thành phần khác nhau, giúp định nghĩa đầy đủ về một đối tượng. Dưới đây là các thành phần chính mà một lớp có thể chứa:&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;1. Thuộc tính (Attributes):&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Biến/Trường (Variables/Fields): &lt;/span&gt;&lt;span&gt;Các thuộc tính hoặc trạng thái của lớp. Chúng có thể được khai báo là private, protected, hoặc public. Các biến thành viên thường được sử dụng để lưu trữ dữ liệu mà đối tượng của lớp quản lý.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Hằng: &lt;/span&gt;&lt;span&gt;Các giá trị không đổi trong suốt quá trình thực thi chương trình.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;2. Phương thức (Methods):&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Hành động: &lt;/span&gt;&lt;span&gt;Định nghĩa các hành động mà đối tượng có thể thực hiện. Ví dụ: một lớp SinhVien có thể có phương thức inThongTin() để in thông tin của sinh viên ra màn hình.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;3. Hàm Tạo (Constructor)&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Constructor: &lt;/span&gt;&lt;span&gt;Hàm khởi tạo, được gọi tự động khi tạo một đối tượng để khởi tạo các thuộc tính của đối tượng.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Destructor: &lt;/span&gt;&lt;span&gt;Hàm hủy, được gọi tự động khi đối tượng bị thu hồi bộ nhớ (trong một số ngôn ngữ khác, Java không có destructor theo nghĩa đen nhưng có cơ chế garbage collection).&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;4. Khối mã (Blocks):&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Khối khởi tạo: &lt;/span&gt;&lt;span&gt;Được thực hiện khi tạo đối tượng, trước khi gọi constructor.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Khối tĩnh: &lt;/span&gt;&lt;span&gt;Được thực hiện khi lớp được tải lần đầu tiên.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;5. Lớp lồng nhau(Nested Classes):&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Lớp bên trong: &lt;/span&gt;&lt;span&gt;Một lớp được định nghĩa bên trong một lớp khác.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Lớp tĩnh: &lt;/span&gt;&lt;span&gt;Một lớp lồng nhau có thể được tạo đối tượng độc lập mà không cần tạo đối tượng của lớp ngoài.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;6. Giao diện (Interface):&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Khai báo các phương thức trừu tượng: &lt;/span&gt;&lt;span&gt;Một lớp có thể implements một hoặc nhiều giao diện để thực hiện các phương thức được khai báo trong giao diện đó.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;7. Enum:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Một loại lớp đặc biệt: &lt;/span&gt;&lt;span&gt;Dùng để định nghĩa một tập hợp các hằng số có tên.&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmdtYfxjYPGTaN1Zz6uKkxGflRalwzTF2mVUgJqrZz5GeD5W5nSMrUht-YxcUkZ9qdHRvXtBy8ZvBEZ067x89nbFCceBJd8bWPHi0d_9iM-QOTjgDW0DtLwVxUeAyhO-8hoQlFT2W0ypC8rY9pcO0MLjJAXTn2uP0ek7emyFDcVU5L0Pz-Qrii9x2EwdU/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh mô tả các thành phần chính của một lớp trong Java." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEgmdtYfxjYPGTaN1Zz6uKkxGflRalwzTF2mVUgJqrZz5GeD5W5nSMrUht-YxcUkZ9qdHRvXtBy8ZvBEZ067x89nbFCceBJd8bWPHi0d_9iM-QOTjgDW0DtLwVxUeAyhO-8hoQlFT2W0ypC8rY9pcO0MLjJAXTn2uP0ek7emyFDcVU5L0Pz-Qrii9x2EwdU%2Fw640-h360%2Fimage.png" title="Ảnh mô tả các thành phần chính của một lớp trong Java." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Ảnh mô tả các thành phần chính của một lớp trong Java.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅲ. &lt;a href="https://www.tieushare.com/2026/10/lop-class-trong-java.html" rel="noopener noreferrer"&gt;Khai báo lớp (Class)&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Cấu trúc cơ bản của một lớp trong Java:&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
      &lt;b&gt;Cú Pháp&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;modifier class className {&lt;br&gt;
      // Khai báo thuộc tính, hàm khởi tạo và phương thức&lt;br&gt;
}&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;&lt;span&gt;Giải thích từng phần:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ modifier: &lt;/span&gt;&lt;span&gt;Từ khóa truy cập cho lớp (ví dụ: public, private).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ className: &lt;/span&gt;&lt;span&gt;Tên của lớp (phải tuân theo quy tắc đặt tên Java).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ fieldDeclaration: &lt;/span&gt;&lt;span&gt;Khai báo các thuộc tính của lớp.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ methodDeclaration: &lt;/span&gt;&lt;span&gt;Khai báo các phương thức của lớp.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Đây là một cách khai báo lớp đơn giản. Thân lớp (phần nằm giữa cặp ngoặc nhọn) chứa tất cả code cần thiết cho vòng đời của các đối tượng được tạo từ lớp: hàm khởi tạo để khởi tạo các đối tượng mới, khai báo các thuộc tính lưu trữ trạng thái của lớp và các đối tượng của nó, và các phương thức để thực hiện hành vi của lớp và các đối tượng của nó.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Khai báo lớp ở trên là dạng đơn giản. Nó chỉ chứa các thành phần bắt buộc của một khai báo lớp. Bạn có thể cung cấp thêm thông tin về lớp ở đầu khai báo, chẳng hạn như tên lớp cha, lớp có implements (triển khai) bất kỳ giao diện nào không, v.v. Ví dụ:&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Cú Pháp&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;class MyClass extends MySuperClass implements YourInterface {&lt;br&gt;
  // Khai báo thuộc tính, hàm khởi tạo và phương thức&lt;br&gt;
}&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Điều này có nghĩa là MyClass là lớp con của MySuperClass và nó implements giao diện YourInterface.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Bạn cũng có thể thêm các từ khóa thay đổi quyền truy cập như public (công khai) hoặc private (riêng tư) ngay ở đầu - vì vậy bạn có thể thấy rằng dòng đầu tiên của khai báo lớp có thể trở nên khá phức tạp. Các từ khóa public và private quy định lớp khác có thể truy cập MyClass như thế nào, chúng sẽ được thảo luận chi tiết hơn trong bài học sau. Bài học về giao diện và kế thừa sẽ giải thích cách và lý do tại sao bạn sử dụng các từ khóa extends (mở rộng) và implements (triển khai) trong khai báo lớp. Hiện tại, bạn không cần lo lắng về những điều phức tạp thêm này&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Nhìn chung, khai báo lớp có thể bao gồm các thành phần này, theo thứ tự:&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;↳ Từ khóa thay đổi quyền truy cập: &lt;/span&gt;&lt;span&gt;public (công khai), private (riêng tư) và một số từ khóa khác mà bạn sẽ gặp sau. (Tuy nhiên, lưu ý rằng từ khóa private chỉ có thể áp dụng cho các lớp lồng (nested class).).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Tên lớp: &lt;/span&gt;&lt;span&gt;được bắt đầu bằng chữ in hoa theo quy ước.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ TÊN LỚP CHA (nếu có): &lt;/span&gt;&lt;span&gt;Tên lớp cha (superclass) của lớp, nếu có, được đặt trước bởi từ khóa extends. Một lớp chỉ có thể kế thừa (subclass) từ một lớp cha duy nhất.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Danh sách các giao diện (interface) được implements (triển khai): &lt;/span&gt;&lt;span&gt;Nếu lớp implements bất kỳ giao diện nào, danh sách các giao diện được phân cách bằng dấu phẩy, đứng trước bởi từ khóa implements. Một lớp có thể implements nhiều hơn một giao diện..&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Thân lớp: &lt;/span&gt;&lt;span&gt;được bao bọc bởi cặp ngoặc nhọn .&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅳ. Khởi tạo đối tượng từ lớp (Class)&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Để tạo một đối tượng trong Java, bạn cần thực hiện ba bước chính:&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;1. Khai báo (Declaration):&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Mục đích: Cho chương trình biết kiểu đối tượng bạn muốn tạo và tên biến bạn sẽ sử dụng để tham chiếu đến nó.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Cách thực hiện - Sử dụng cú pháp sau:&lt;/span&gt;&lt;/p&gt;
&lt;b&gt;Cú Pháp&lt;/b&gt;

  &lt;pre&gt;&lt;code&gt;Point originOne;&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Trong ví dụ này, originOne là một biến được khai báo để tham chiếu đến một đối tượng của lớp Point.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;2. Khởi tạo (Instantiation)&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Mục đích: Tạo ra một đối tượng mới từ một lớp (bản thiết kế).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Cách thực hiện: Sử dụng toán tử new cùng với tên lớp và giá trị khởi tạo cho các thuộc tính của đối tượng.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Cú Pháp&lt;/b&gt;&lt;br&gt;
  &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;originOne = new Point(23, 94);&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Toán tử new sẽ phân bổ bộ nhớ cho một đối tượng mới của lớp Point và trả về tham chiếu đến đối tượng đó.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;3. Khởi tạo giá trị ban đầu (Initialization)&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Đây là bước bạn gọi một constructor để thiết lập giá trị ban đầu cho đối tượng.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Cú Pháp&lt;/b&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;Point originOne = new Point(23, 94);&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt;Constructor Point(int a, int b) nhận vào hai tham số a và b để thiết lập giá trị cho x và y. Khi bạn gọi new Point(23, 94), nó sẽ gán x = 23 và y = 94.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;4. Ví dụ cụ thể&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Hãy chắc chắn rằng các tệp trên được lưu với các tên Point.java, Rectangle.java, và CreateObjectDemo.java, và tất cả chúng đều nằm trong cùng một thư mục.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Lớp Point đại diện cho một điểm trong không gian hai chiều, có các thuộc tính x và y để lưu trữ tọa độ của điểm đó trên trục hoành và trục tung.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Point.java&lt;/b&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;// Định nghĩa lớp Point với hai thuộc tính x và y&lt;br&gt;
public class Point {&lt;br&gt;
    public int x = 0;&lt;br&gt;
    public int y = 0;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor của lớp Point, nhận vào hai tham số int và gán giá trị cho x và y
public Point(int a, int b) {
    x = a;
    y = b;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;h4&gt;&lt;span&gt;&lt;b&gt;Đặc điểm:&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ x và y: Là các biến thành viên (instance variables) của lớp Point để lưu trữ tọa độ của điểm.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Constructor: Lớp có một constructor để khởi tạo giá trị cho x và y khi một đối tượng Point được tạo ra.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Lớp Rectangle đại diện cho một hình chữ nhật trong không gian hai chiều, được xác định bởi chiều rộng (width), chiều cao (height) và một điểm gốc (origin) là tọa độ của góc trái trên của hình chữ nhật.&lt;/span&gt;&lt;/p&gt;
&lt;br&gt;
&lt;b&gt;Rectangle.java&lt;/b&gt;


&lt;pre&gt;&lt;code&gt;public class Rectangle {&lt;br&gt;
    public int width = 0;&lt;br&gt;
    public int height = 0;&lt;br&gt;
    public Point origin;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Constructor không tham số
public Rectangle() {
    origin = new Point(0, 0);
}

// Constructor với một tham số Point
public Rectangle(Point p) {
    origin = p;
}

// Constructor với hai tham số int
public Rectangle(int w, int h) {
    origin = new Point(0, 0);
    width = w;
    height = h;
}

// Constructor với một tham số Point và hai tham số int
public Rectangle(Point p, int w, int h) {
    origin = p;
    width = w;
    height = h;
}
// phương thức di chuyển hình chữ nhật
public void move(int x, int y) {
     origin.x = x;
    origin.y = y;
}

// phương thức tính diện tích hình chữ nhật
public int getArea() {
 return width * height;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;h4&gt;&lt;span&gt;&lt;b&gt;Đặc điểm:&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ width và height: Là các biến thành viên để lưu trữ kích thước của hình chữ nhật.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ origin: Là một đối tượng của lớp Point, biểu diễn tọa độ của góc trái trên của hình chữ nhật.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Constructor: Lớp có nhiều hàm khởi tạo (constructor) để tạo ra đối tượng Rectangle với các cách khác nhau, bao gồm không có tham số, một Point, hai số nguyên, và một Point kèm theo hai số nguyên.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Trong lớp CreateObjectDemo, phương thức main được sử dụng để tạo và khởi tạo các đối tượng Point và Rectangle, và sau đó in ra thông tin của chúng.&lt;/span&gt;&lt;/p&gt;


&lt;p&gt;CreateObjectDemo.java&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;public class CreateObjectDemo {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        // Khai báo và khởi tạo đối tượng Point với giá trị x = 2 và y = 4&lt;br&gt;
        Point Toado = new Point(2, 4);

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Khai báo và khởi tạo đối tượng Rectangle với đối tượng Point Toado và các giá trị width = 20, height = 40
    Rectangle HinhMot = new Rectangle(Toado, 20, 40);

    // Khai báo và khởi tạo đối tượng Rectangle với width = 50 và height = 100, origin mặc định là (0, 0)
    Rectangle HinhHai = new Rectangle(50, 100);

    // In thông tin của các đối tượng để kiểm tra
    System.out.println("Hình thứ nhất: Tọa độ (" + HinhMot.origin.x + ", " + HinhMot.origin.y + "), Rộng: " + HinhMot.width + ", Dài: " + HinhMot.height);
    System.out.println("Hình thứ hai: Tọa độ (" + HinhHai.origin.x + ", " + HinhHai.origin.y + "), Rộng: " + HinhHai.width + ", Dài: " + HinhHai.height);

    // In diện tích của hai hình chữ nhật
    System.out.println("Diện tích hình 1: " + HinhMot.getArea());
    System.out.println("Diện tích hình 2: " + HinhHai.getArea());

    // Thay đổi tọa độ hình chữ nhật thứ nhất và in lại thông tin
    HinhMot.move(4, 2);
    System.out.println("Hình thứ nhất sau khi di chuyển: Tọa độ (" + HinhMot.origin.x + ", " + HinhMot.origin.y + "), Rộng: " + HinhMot.width + ", Dài: " + HinhMot.height);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;h4&gt;&lt;span&gt;&lt;b&gt;Đặc điểm:&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;↳ Lớp CreateObjectDemo chứa phương thức main, là nơi chính để thực thi chương trình.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Sử dụng: Trong phương thức main, bạn đã tạo:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Một đối tượng Point tại tọa độ (2, 4).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Hai đối tượng Rectangle: HinhMot với góc trái trên ở Toado và kích thước 20x40, HinhHai với kích thước 50x100 và góc trái trên mặc định ở (0, 0).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ In ra thông tin của hai hình chữ nhật và diện tích của chúng.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;↳ Thay đổi tọa độ của HinhMot và in lại thông tin để xem sự thay đổi.&lt;/span&gt;&lt;/p&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Hình thứ nhất: Tọa độ (2, 4), Rộng: 20, Dài: 40&lt;br&gt;
Hình thứ hai: Tọa độ (0, 0), Rộng: 50, Dài: 100&lt;br&gt;
Diện tích hình 1: 800&lt;br&gt;
Diện tích hình 1: 5000&lt;br&gt;
Hình thứ nhất: Tọa độ (4, 2), Rộng: 20, Dài: 40&lt;/code&gt;&lt;/pre&gt;



&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅴ. Sử dụng các thành viên lớp (thuộc tính, phương thức)&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3&gt;&lt;span&gt;Truy cập và sửa đổi thuộc tính&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Sử dụng toán tử&lt;/span&gt;&lt;span&gt; . &lt;/span&gt;&lt;span&gt;sau tên đối tượng và tên thuộc tính.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Gọi phương thức&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Sử dụng toán tử&lt;/span&gt;&lt;span&gt; . &lt;/span&gt;&lt;span&gt;sau tên đối tượng và tên phương thức, theo sau là dấu ngoặc đơn và danh sách tham số (nếu có).&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Ví dụ: Thuộc tính và phương thức của một chiếc ô tô&lt;/span&gt;&lt;/h3&gt;
&lt;h4&gt;&lt;span&gt;&lt;b&gt;↳ Thuộc tính (Attributes)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;Các thuộc tính là những đặc điểm hoặc đặc tính của một chiếc ô tô. Dưới đây là một số thuộc tính phổ biến: Màu sắc (color), Trọng lượng (weight), Hãng sản xuất (manufacturer), Mẫu xe (model), Năm sản xuất (year), Loại nhiên liệu (fuelType), Tốc độ tối đa (maxSpeed), Giá tiền (price)&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;&lt;b&gt;↳ Phương thức (Methods)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span&gt;Các phương thức là những hành động mà một chiếc ô tô có thể thực hiện hoặc những thao tác có thể được thực hiện trên một chiếc ô tô. Dưới đây là một số phương thức phổ biến: Khởi động (start), Dừng (stop), Lái xe (drive), Bật đèn (turnOnLights), Tắt đèn (turnOffLights), Tăng tốc (accelerate), Giảm tốc (decelerate),&lt;/span&gt;&lt;/p&gt;


&lt;p&gt;Car.java&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;public class Car {&lt;br&gt;
    // Thuộc tính của lớp Car&lt;br&gt;
    String color;&lt;br&gt;
    double weight;&lt;br&gt;
    String manufacturer;&lt;br&gt;
    String model;&lt;br&gt;
    int year;&lt;br&gt;
    String fuelType;&lt;br&gt;
    int maxSpeed;&lt;br&gt;
    int mileage;&lt;br&gt;
    double price;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Phương thức của lớp Car
void start() {
    System.out.println("Xe đang khởi động");
}

void stop() {
    System.out.println("Xe đang dừng lại");
}

void drive() {
    System.out.println("Xe đang được lái");
}

void brake() {
    System.out.println("Xe đang phanh gấp");
}

void turnOnLights() {
    System.out.println("Đèn đang được bật");
}

void turnOffLights() {
    System.out.println("Đèn đang được tắt");
}

void accelerate() {
    System.out.println("Xe đang tăng tốc");
}

void decelerate() {
    System.out.println("Xe đang giảm tốc");
}
@Override
public String toString() {
    return "Car: " +
            " Màu= " + color  +
            ", Trọng lượng= " + weight +
            ", Hãng= " + manufacturer + 
            "";
}
public class Main {
    public static void main(String[] args) {
        // Khởi tạo đối tượng Car
        Car myCar = new Car();

        // Gán giá trị cho các thuộc tính của đối tượng Car
        myCar.color = "Red";
        myCar.weight = 1500.5;
        myCar.manufacturer = "Toyota";
        System.out.println(myCar);

        // Sử dụng các phương thức của đối tượng Car
        myCar.start();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/code&gt;&lt;p&gt;&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;&lt;span id="docs-internal-guid-6312f6eb-7fff-1a50-b17f-c1dc6278b43f"&gt;&lt;span&gt;&lt;b&gt;Kết quả của chương trình là: &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;Car: Màu= Red, Trọng lượng= 1500.5, Hãng= Toyota&lt;br&gt;
Xe đang khởi động&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;span&gt;Trong ví dụ trên, Lớp Car được định nghĩa với các thuộc tính và phương thức trên, và sau đó một đối tượng Car được khởi tạo và sử dụng trong hàm main.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;span&gt;Ⅵ. So sánh lớp (Class) và đối tượng (Object) trong lập trình hướng đối tượng&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Đối tượng và lớp là hai khái niệm cơ bản và quan trọng trong lập trình hướng đối tượng (OOP). Việc hiểu rõ sự khác biệt giữa hai khái niệm này là rất cần thiết để viết code OOP hiệu quả.&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;col width="auto"&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tiêu chí&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Lớp (Class)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Đối tượng (Object)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Bản chất&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Bản thiết kế hoặc khuôn mẫu&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Thực thể cụ thể, instance của lớp&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Khái niệm&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Trừu tượng, định nghĩa các thuộc tính và hành vi&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Cụ thể, có trạng thái và hành vi&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tạo ra bằng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Định nghĩa với từ khóa class&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Tạo ra từ lớp bằng từ khóa new&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Ví dụ&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;class Car { ... }&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Car myCar = new Car();&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Vai trò&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Định nghĩa thuộc tính và phương thức chung&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Thực hiện hành động cụ thể và lưu trữ trạng thái&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Static&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Có thể có các thành phần static&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Không thể là static, tất cả là instance-specific&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Số lượng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Một lớp có thể có nhiều đối tượng&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;span&gt;Một đối tượng là instance của một lớp&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDtybbI-bPDZHWePIuLfjRHwh-_PO4r8azVDnEBXCScwogNQ2YqMRhMbanaRYAAmt9F8_uYluFjJ963XieUMw1lt4hUgHhFe6VT1GNoBjBByKGMWndZshpnaJ_9LFlkLHTdZrqlrtcq-k96cmRkyeaU2PtdtbDmrMCwkJzGxxZAfs41ly3EnopCcYawzc/s1600/image.png" rel="noopener noreferrer"&gt;&lt;img alt="Ảnh minh họa để thấy sự khác biệt giữa lớp và đối tượng." height="360" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fb%2FR29vZ2xl%2FAVvXsEjDtybbI-bPDZHWePIuLfjRHwh-_PO4r8azVDnEBXCScwogNQ2YqMRhMbanaRYAAmt9F8_uYluFjJ963XieUMw1lt4hUgHhFe6VT1GNoBjBByKGMWndZshpnaJ_9LFlkLHTdZrqlrtcq-k96cmRkyeaU2PtdtbDmrMCwkJzGxxZAfs41ly3EnopCcYawzc%2Fw640-h360%2Fimage.png" title="Ảnh minh họa để thấy sự khác biệt giữa lớp và đối tượng." width="640"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span&gt;Ảnh minh họa để thấy sự khác biệt giữa lớp và đối tượng.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;span&gt;&lt;br&gt;&lt;/span&gt;
&lt;br&gt;

</description>
      <category>lớptrongjava</category>
      <category>classinjava</category>
      <category>loptrongjava</category>
      <category>tieushare</category>
    </item>
  </channel>
</rss>
