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

Posted by

Được chỉnh sửa ngày 20/5/2017.

Chào mừng các bạn đến với bài học số 17 trong chương trình học 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 nhìn lại việc khai báo một lớp đã làm từ bài trước, xem có vấn đề gì không nào.

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

Bài hôm trước chúng ta đã thực hành việc khai báo một lớp rồi. Tuy nhiên khi đó 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 các trình biên dịch khác) đề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.

Bạn hãy xem lại bài 3 để biết cách tạo mới một project và tạo các class nhé. Bài học hôm nay mình sẽ tạo một project mới có tên OOPLearning, với hàm main() nằm ở lớp MainClass. Rồi sau đó mình sẽ tạo lớp HinhTron tách biệt ra khỏi lớp MainClass này ở bước sau nữa.

Screen Shot 2017-04-24 at 18.31.25

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.

Blank Diagram - Page 2

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. 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, 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). Bạn thử tạo nhé.

Screen Shot 2017-04-25 at 10.43.22

Cũng như với bài trước, bạn hãy thêm vào các thuộc tính sau.

Screen Shot 2017-04-25 at 10.46.31

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 đánh giá 5 sao nếu thấy thích bài viết, hãy comment bên dưới nếu có thắc mắc, hãy để lại địa chỉ email của bạn để nhận được thông báo mới nhất khi có bài viết mới, và nhớ chia sẻ các bài viết của Yellow Code Books đến nhiều người khác nữa nhé.

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,…

Advertisements
Rating: 5.0/5. From 7 votes.
Please wait...

6 comments

  1. Đã 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.

Gửi phản hồi