Java Bài 17: Thuộc Tính Của Lớp

Posted by
Rating: 4.9/5. From 45 votes.
Please wait...

Được chỉnh sửa ngày 24/11/2020.

Chào mừng các bạn đến với bài học Java số 17, bài học về Thuộc tính của Lớp. Bài học này nằm trong chuỗi bài học lập trình ngôn ngữ Java của Yellow Code Books.

Chúng ta đã cùng nhau đi qua các bài giới thiệu về lập trình Hướng đối tượng, và chắc chắn các bạn cũng đã hiểu rõ thế nào là Đối tượng và thế nào là Lớp rồi phải không. Chúng ta sẽ còn nhiều bài học và bài tập thú vị liên quan đến các kiến thức Hướng đối tượng này ở phía trước, và tất cả chúng đều xoay quanh hai khái niệm trọng tâm, đó là Đối tượngLớp.

Từ bài học hôm nay chúng ta sẽ bắt đầu đi chi tiết vào từng khái niệm và cách sử dụng của các thành phần bên trong một lớp. Và mình đã rất mong muốn nói hết kiến thức về Thuộc tính và Phương thức của một lớp ở trong bài học hôm nay. Tuy nhiên, trong khi từ từ diễn đạt các vấn đề liên quan đến Thuộc tính trước, mình mới ngỡ ra là có rất nhiều thứ để nói về nó. Thế là mình chỉ đủ “giấy mực” để nói đến Thuộc tính mà thôi, hẹn các bạn bài sau sẽ là sân khấu cho Phương thức nhé.

Trước khi đi vào chi tiết về Thuộc tính, chúng ta hãy cùng nhau tạo một project mới nhé.

Thực Hành Tạo Một Project Mới

Chắc chắn bạn có thắc mắc, rằng bài hôm trước chúng ta đã thực hành việc khai báo một lớp rồi, sao không dùng lớp đó mà học tiếp cho bài hôm nay. Tuy nhiên, mình cũng muốn nói rằng, hôm trước bạn đã thử tạo lớp HinhTron cùng cấp với hàm main(), mà như bạn đã biết thì hàm main() này lại đang nằm trong một lớp khác, cụ thể lớp này có tên MyFirstClass mà chúng ta đã tạo từ thuở nảo thuở nào, từ bài học số 3 lận, hi vọng bạn còn nhớ.

Như vậy túm lại là lớp HinhTron mà bạn đã tạo từ bài trước lại nằm trong lớp MyFirstClass, điều này bạn chưa được tiếp cận, nó liên quan đến kiến thức Lớp lồng (Inner class hay Nested class) mà chúng ta sẽ nói đến sau. Để hỗ trợ tốt việc quản lý lớp bên trong các ứng dụng, Eclipse hay InteliJ đều hỗ trợ bạn tạo nhiều lớp khác nhau, mỗi lớp như vậy sẽ tách biệt nhau bởi một file .java. Và bài thực hành hôm nay chúng ta sẽ bắt đầu làm quen với việc quản lý các lớp một cách tách biệt như vậy.

Tạo Project Mới Với Eclipse

Bạn hãy xem lại mục này của bài 3 để biết cách tạo mới một project và tạo các class với Eclipse nhé. Sau đó hãy tự tạo một project mới có tên OOPLearning, với hàm main() nằm ở lớp MainClass. Lớp HinhTron sẽ được tạo ở mục thực hành kế tiếp bên dưới.

Hình ảnh của project mới, lớp MainClass.java và code của hàm main() được diễn tả bằng hình sau.

Tạo một project mới với tên lớp và hàm main ban đầu
Tạo một project mới với tên lớp và hàm main ban đầu trên Eclipse

Tạo Project Mới Với InteliJ

Cũng tương tự, mục này của bài 3 đã nói rõ cách tạo mới một project và lớp mới từ InteliJ. Bạn hãy tự tạo ra một project có tên OOPLearning, một lớp mới ban đầu có tên MainClass và phương thức main() bên trong nó luôn nhé. Hình ảnh của bài thực hành bước đầu tiên này như sau.

Tạo một project mới với tên lớp và hàm main ban đầu trên InteliJ
Tạo một project mới với tên lớp và hàm main ban đầu trên InteliJ

Như bạn biết, một lớp sẽ bao gồm các Thuộc tính và các Phương thức. Và như mình nói đó, do không đủ giấy mực để nói hết hai thành phần này trong bài hôm nay, nên mình sẽ nói các vấn đề liên quan đến khai báo và sử dụng Thuộc tính trước.

Nhắc lại các thành phần của lớp
Nhắc lại các thành phần của lớp

Thuộc Tính Của Lớp

Thuộc tính, hay còn gọi là Field. Như bạn đã biết, các thuộc tính chính là các giá trị của lớp. Sau này khi các đối tượng được tạo ra từ lớp, thì các thuộc tính của lớp lúc này sẽ trở thành các đặc điểm của đối tượng đó.

Để khai báo một thuộc tính thì chúng ta có cú pháp sau.

[khả_năng_truy_cập] kiểu_thuộc_tính tên_thuộc_tính [= giá_trị_ban_đầu];

Ngoại trừ khả_năng_truy_cập sẽ được nói đến ở bài học sau (vì thành phần này nằm trong cặp ngoặc vuông, có nghĩa là có khai báo nó hay không thì cũng sẽ không bị hệ thống báo lỗi, do đó hôm nay mình sẽ chưa nói đến nó). Thì các thành phần còn lại bạn khai báo hoàn toàn giống với cách khai báo một biến (hay hằng). Nếu bạn không tin thì có thể xem lại bài viết về biến và hằng nhé.

Thực Hành Tạo Các Thuộc Tính

Chúng ta tiếp tục tạo mới lớp HinhTron như ở bài thực hành hôm trước. Tuy nhiên ở bài này bạn hãy thực hành việc tạo một lớp tách biệt ra với lớp MainClass.

Tạo Mới Lớp HinhTron Với Eclipse

Chi tiết lớp HinhTron này khi tạo xong sẽ như hình bên dưới đây. Bạn nên nhớ là trong quá trình tạo lớp HinhTron từ Eclipse thì bạn đừng check vào public static void main(String[] args) như khi tạo với MainClass, vì chúng ta không cần thêm một hàm main() nào khác nhé.

Tạo một lớp HinhTron mớ từ Eclipse
Tạo một lớp HinhTron mớ từ Eclipse

Tạo Mới Lớp HinhTron Với InteliJ

Với InteliJ thì sau khi tạo mới một lớp HinhTron sẽ như sau.

Tạo một lớp HinhTron mớ từ InteliJ
Tạo một lớp HinhTron mớ từ InteliJ

Thêm Thuộc Tính Vào Lớp HinhTron

Dù bạn tạo bằng Eclipse hay InteliJ thì đến bước này hãy cũng mình thêm các thuộc tính vào HinhTron nhé. Hình minh họa sau dành cho Eclipse, với InteliJ thì bạn cũng code tương tự.

Khai báo các thuộc tính cho HinhTron
Khai báo các thuộc tính cho HinhTron

Mọi thứ đều như bài học hôm trước. Tuy nhiên với bài hôm nay bạn đã hiểu hơn về quy tắc khai báo các thuộc tính đúng không nào.

Mối Liên Hệ Giữa Thuộc Tính Và Biến

Qua bài thực hành trên thì bạn có thể thấy rằng các thuộc tính mà bạn khai báo bên trong một lớp, chúng không khác gì so với các biến bên trong một hàm (chẳng hạn như trong hàm main() mà bạn đã làm quen từ các bài trước). Vậy mục này mình sẽ giúp các bạn nắm rõ hơn về thuộc tính thông qua các mối liên hệ giữa Thuộc tính của lớpBiến của hàm nhé.

Mối Liên Hệ Thứ Nhất

Khai báo chúng rất giống nhau. Như mình có trình bày trên kia, ngoại trừ khả_năng_truy_cập sẽ được nói ở bài sau ra, thì khai báo của chúng là như nhau.

public class HinhTron {
 
    /**
     * Demo sự giống nhau giữa Thuộc tính và Biến
     * nếu như không có thành phần khả_năng_truy_cập trước
     * các Thuộc tính
     */
 
    // Thuộc tính
    final float PI = 3.14f;
    float r;
    float cv;
    float dt;
 
    void tinhChuVi() {
        // Biến
        float banKinh = 10;
 
        cv = 2 * PI * banKinh;
    }
}

Mối Liên Hệ Thứ Hai

Biến chỉ được sử dụng cục bộ bên trong khối lệnh của hàm, trong khi thuộc tính được sử dụng toàn cục.

Và bởi vì biến chỉ được sử dụng cục bộ bên trong khối lệnh của hàm, nên khi một hàm thực thi hết các dòng code của nó, thì biến này cũng sẽ bị xóa khỏi bộ nhớ. Như vậy biến bên trong hàm chỉ dùng để tính toán tạm mà thôi.

Còn thuộc tính thì được dùng toàn cục, nên khi một hàm kết thúc, thuộc tính này vẫn sẽ được lưu giữ giá trị cuối cùng của nó. Như ví dụ bên dưới, thuộc tính r sẽ được mang giá trị là 10 sau khi bạn gọi đến hàm tinhDienTich(). Điều này cũng đã được bạn kiểm chứng từ thực hành của bài trước, khi mà bạn gọi liên tiếp các hàm hinhTron.nhapBanKinh() rồi hinhTron.tinhChuVi(),… hinhTron.inChuVi().

public class HinhTron {
 
    /**
     * Demo cách sử dụng toàn cục của Thuộc tính,
     * và cách sử dụng cục bộ của Biến
     */
 
    // Thuộc tính
    final float PI = 3.14f;
    float r;
    float cv;
    float dt;
 
    void tinhChuVi() {
        // Biến banKinh định nghĩa ở đây chỉ dược sử
        // dụng cục bộ trong hàm này
        float banKinh = 10;
 
        cv = 2 * PI * banKinh;
    }
 
    void tinhDienTich() {
        // r là Thuộc tính của Lớp, được sử dụng thoải mái
        // trong các hàm
        r = 10;
 
        // Dĩ nhiên dt và PI cũng là Thuộc tính toàn cục
        dt = PI * r * r;
    }
}

Mối Liên Hệ Thứ Ba

Chuyện gì xảy ra nếu bạn định nghĩa một biến có cùng tên với một thuộc tính?

Khi này hệ thống sẽ giúp bạn xác định đâu là biến cục bộ, còn đâu là thuộc tính toàn cục. Bạn có thể xem ví dụ sau. Khi biến r được khai báo bên trong hàm, dù trùng tên với thuộc tính r, nhưng r trong tinhChuVi() vẫn được hiểu là biến cục bộ đấy nhé.

public class HinhTron {
 
    /**
     * Demo khi một Biến trong một hàm trùng tên
     * với một Thuộc tính trong một lớp
     */
 
    // Thuộc tính
    final float PI = 3.14f;
    float r;
    float cv;
    float dt;
 
    void tinhChuVi() {
        // Biến r này là biến cục bộ, vì nó được
        // khai báo lại, dù cho nó trùng tên
        float r = 10;
 
        cv = 2 * PI * r;
    }
 
    void tinhDienTich() {
        // Thuộc tính r này là toàn cục
        r = 15;
 
        dt = PI * r * r;
    }
}

Cũng ở mối liên hệ này, mình cũng muốn nói đến một vấn đề nhỏ nữa. Đó là nhiều khả năng sau này trong một hàm, bạn đã khai báo một biến trùng tên với thuộc tính của lớp rồi, nhưng… trớ trêu thay bạn vẫn sẽ muốn lúc thì dùng biến, lúc thì dùng thuộc tính với cùng một tên ấy. Để giải quyết tình trạng này, Java có hỗ trợ từ khóa this. this có ý nói: chính là đối tượng này. Đó là lý do vì sao bảng các keyword mà bạn làm quen ở bài 4 ngày xưa có liệt kê từ khóa this vào đó. Bạn xem ví dụ sử dụng this như sau.

public class HinhTron {
 
    /**
     * Demo khi một Biến trong một hàm trùng tên
     * với một Thuộc tính trong một lớp. Nhưng chúng ta
     * có thể dùng từ khóa this để chỉ định đến thuộc tính của lớp.
     */
 
    // Thuộc tính
    final float PI = 3.14f;
    float r;
    float cv;
    float dt;
 
    void tinhChuVi() {
        // Biến r cục bộ
        float r = 10;
 
        // this.r lại là thuộc tính, dòng code này
        // gán giả trị của biến r vào thuộc tính r
        this.r = r;
 
        // r trong phép tính này là biến r cục bộ đấy nhé
        cv = 2 * PI * r;
    }
}

Truy Xuất Đến Thuộc Tính Của Lớp Từ Bên Ngoài

Khi bạn ở đâu đó bên ngoài một lớp, và muốn truy xuất đến các thuộc tính của lớp đó, như bạn cũng đã biết đâu đó qua các bài thực hành trước, đó là bạn có thể sử dụng toán tử “.”.

Mình ví dụ với lớp HinhTron mà chúng ta đã khai báo ở trên kia, giả sử ở hàm main() khi chúng ta đã khai báo đối tượng hinhTron, chúng ta có thể truy xuất đến các thuộc tính của hinhTron như sau.

public class MainClass {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
 
        HinhTron hinhTron = new HinhTron();
        hinhTron.r = 10.0f;
    }
 
}

Tuy nhiên không phải lúc nào một lớp cũng cho phép bạn truy xuất đến các thuộc tính (và ngay cả các phương thức) của nó đâu. Nó tùy thuộc vào khả_năng_truy_cập mà mình đã nói ở trên kia. Đa số các lớp sẽ “giấu” các thuộc tính của nó đi thông qua khai báo khả_năng_truy_cập này, và khi đó bạn có dùng bao nhiêu dấu “.” đi nữa cũng không tài nào nhìn thấy các thuộc tính bị giấu đó. Và chắc chắn chúng ta sẽ nói đến điều này khi giải thích cụ thể từng khả_năng_truy_cập ở bài sau nhé.

Chúng ta vừa kết thúc bài học về cách sử dụng các thuộc tính của một lớp. Bài sau mình sẽ nói đến cách sử dụng các phương thức.

Cảm ơn bạn đã đọc các bài viết của Yellow Code Books. Bạn hãy ủng hộ blog bằng cách:
– Đánh giá 5 sao ở mỗi bài viết nếu thấy thích.
– Comment bên dưới mỗi bài viết nếu có thắc mắc.
– Để lại địa chỉ email của bạn ở thanh bên phải để nhận được thông báo sớm nhất khi có bài viết mới.
– Chia sẻ các bài viết của Yellow Code Books đến nhiều người khác.
– Ủng hộ blog theo hướng dẫn ở thanh bên phải để blog ngày càng phát triển hơn.

Bài Kế Tiếp

Bài tiếp theo chúng ta sẽ xem qua tất cả các kiến thức liên quan đến phương thức của lớp, bao gồm các tham số truyền vào, kết quả trả về, truy xuất đến phương thức,…

13 comments

  1. hay quá mong ad tiếp tục ra các bài viết tiếp theo trong thời gian nhanh nhất. Thanks ad!!

    Rating: 4.9/5. From 8 votes.
    Please wait...
    1. Mình đang soạn bài kế tiếp đây ^^

      Rating: 5.0/5. From 5 votes.
      Please wait...
  2. Đã có quá nhiều bài học java cơ bản, OOP trên mạng và vô số sách. Nhưng chưa có ai viết hay, dễ hiểu, trực quan, cuốn hút như bạn này. Có điều bạn cố gắng ra bài nhanh chút để anh e đỡ phải đợi.

    Rating: 5.0/5. From 2 votes.
    Please wait...
    1. Cảm ơn bạn ManhDN, mình sẽ cố gắng dành thời gian viết nhiều hơn.

      No votes yet.
      Please wait...
  3. Phải nói là loạt bài hướng dẫn của anh rất gần gũi với newbie như em. Rất bổ ích

    No votes yet.
    Please wait...
    1. (like)

      Rating: 5.0/5. From 1 vote.
      Please wait...
  4. anh viết thực sự rất dễ hiểu. Rất đáng đọc

    No votes yet.
    Please wait...
  5. Thực sự rất hay và bổ ích.

    Rating: 5.0/5. From 2 votes.
    Please wait...
  6. Tuyệt vời @@ nhờ anh em hiểu rõ hơn về hướng đối tượng. Cảm ơn anh.

    No votes yet.
    Please wait...
  7. Dạy rất chi tiết và dễ hiểu , ko như các trang khác. Thanks AD nhiều^^

    No votes yet.
    Please wait...
  8. Anh viết rất dễ hiểu và rõ ràng, chúc anh mạnh khoẻ và tiếp tục ra bài mới nha. Mấy bài này trên trường dạy em nỏ hiểu chi cả (❁´◡`❁)

    Rating: 5.0/5. From 1 vote.
    Please wait...
  9. Thực sự câu từ rất gần gũi và dễ hiểu. Cảm ơn tác giả !
    Mình muốn xem từ những bài đầu trong “chương trình học java” này . Nhưng mà hình như link bị gỡ rồi hay sao ấy.

    No votes yet.
    Please wait...
    1. Vẩn còn mà bạn, do danh sách bài học nhiều quá nên trang Web có phân trang đấy, bạn để ý cuộn xuống hết danh sách rồi chú ý bên dưới có đánh dấu trang, bạn chọn các trang số lớn nhất để xem các bài đầu tiên nhé.

      Rating: 5.0/5. From 1 vote.
      Please wait...

Leave a Reply