Giải pháp chuyển đổi số trọn gói cho doanh nghiệp Việt
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ượng và lớ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.
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 main(), mà như bạn đã biết thì 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 đang 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, InteliJ hay các IDE khác đều hỗ trợ bạn tạo nhiều lớp khác nhau mà 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.
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 InteliJ nhé. Sau đó hãy tự tạo một project mới có tên OOPLearning. Rồi cũng hãy tự tạo lớp MainClass. Đảm bảo có phương thức main() bên trong lớp MainClass. Lớp HinhTron thì 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 main() được diễn tả bằng hình sau.

Như bạn biết, một lớp sẽ bao gồm các thuộc tính và 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.

Thuộc tính hay còn gọi là field. Như bạn đã biết, các thuộc tính của lớp sẽ giúp tạo ra các trạng thái, hay các đặc điểm của các đối tượng được tạo ra từ lớp này.
Để 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é.
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.
Chi tiết lớp HinhTron này khi tạo xong sẽ như hình bên dưới đây.

Bạn hãy thêm các thuộc tính sau vào lớp HinhTron vừa mới tạo.

Code của nó như sau.
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.
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 phương thức (chẳng hạn như trong phương thức main() mà bạn đã làm quen từ các bài trước) đúng không nào.
Tuy nhiên thuộc tính là thuộc tính, và biến là biến. Chúng không phải là một. Có vài tài liệu gọi rõ ra biến với cái tên là biến local, hay biến cục bộ (local variable). Để giúp phân biệt rõ hơn với từ thuộc tính, còn được gọi là thuộc tính global, hay thuộc tính toàn cục (global field). 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ớp và biến của phương thức nhé.
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 được khai báo với một nguyên tắc như nhau.
Biến chỉ được sử dụng cục bộ bên trong khối lệnh của phương thức, 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 phương thức, nên khi một phương thức 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 phương thức 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 phương thức 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 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 phương thức hinhTron.nhapBanKinh() rồi hinhTron.tinhChuVi(),… hinhTron.inChuVi().
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 phương thức, 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é.
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 phương thức, 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. Cách sử dụng cụ thể của từ khóa this sẽ được mình nói ở bài này.
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ử ở 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.
Tuy nhiên code trên đây chỉ là một ví dụ về cách truy xuất đến thuộc tính của lớp thôi. Theo nguyên tắc của gói ghém dữ liệu bên trong các lớp của OOP, thì một lớp sẽ không cho phép bên ngoài truy xuất đến các thuộc tính của nó một cách trực tiếp như vậy, bằng việc định nghĩa các khả_năng_truy_cập mà mình đã nói ở trên kia. 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ưa có câu hỏi nào cho bài này.