Mang đến cho bạn hành trang là Kiến thức và Kinh nghiệm

Lựa chọn chủ đề bạn quan tâm

Cùng nhau thảo luận về các vấn đề

Hãy theo dõi chúng tôi nếu bạn thấy bổ ích

  1. Hỏi đáp IT
  2. Hỏi nhanh

[CHIA SẺ] Java cơ bản - Khái niệm Class - phần 1

11230 Lượt xem 2 Bình luận 0 Lượt báo xấu
Bài học mô tả một cách chi tiết về một lớp, Ngăn xếp(Stack) và mô tả về tất cả các thành phần cung cấp cho vòng đời của một đối tượng được tạo ra bởi lớp đó. Bài học cũng đề cập đến các hàm dựng (constructor), các biến thành phần (member variable) và các phương thức (method).

Tạo ra các lớp
Bây giờ chúng ta sẽ học cách làm thế nào để tạo ra và sử dụng các đối tượng, và các đối tượng được dọn dẹp như thế nào. Cũng là lúc để chỉ cho bạn làm thế nào để viết ra các lớp từ những đối tượng được tạo ra. Bài học này chỉ cho bạn các thành phần chính của một lớp thông qua một ví dụ nhỏ cài đặt một ngăn xếp LIFO( Last-In-First-Out: vào sau ra trước).
Sơ đồ sau đây liệt kê nội dung lớp đó và cấu trúc của mã chương trình:


Việc cài đặt một ngăn xếp như trên sử dụng một lớp khác, một Vector (Véc - tơ), để lưu giữ các phần tử của ngăn xếp. Vector là một mảng (có thể lớn thêm về kích thước) của các đối tượng và có chức năng cấp phát bộ nhớ cho một đối tượng mới với dung lượng cần thiết. Lớp Stack sử dụng đoạn mã này bằng việc dùng một Vector để lưu trữ các phần tử của nó. Tuy nhiên, nó cũng bắt LIFO bị giới hạn vào Vector.. tức là, bạn chỉ được thêm các phần tử vào và xóa các phần tử tại đầu ngăn xếp.

1. Khai báo lớp
Sơ đồ trên dây cho thấy việc cài đặt một lớp gồm hai phần chính: khai báo lớp và thân lớp. Phần khai báo lớp khai báo tên của lớp cùng với các thuộc tính khác. Phần khai báo của lớp Stack khá đơn giản và cho biết lớp đó là công khai (public) và tên của lớp là Stack. Thông thường thì bạn chỉ cần khai báo dưới dạng tối thiểu như trên.
Tuy nhiên, việc khai báo lớp có thể cho biết nhiều hơn về lớp đó, ví dụ như tên của siêu lớp(superclass) và nếu có thể là một lớp con (subclass)
Phía trái của sơ đồ dưới đây biểu diễn các phần có thể có khi khai báo một lớp(theo đúng thứ tự trong sơ đồ). Phần bên phải là mô tả mục đích của việc khai báo các phần đó. Phần cần được khai báo là từ khóa class và tên của lớp như phần in đậm. Tất cả các phần khác có thể thêm vào và mỗi phần chỉ được viết trên một dòng( do “extends Super” là một phần riêng rẽ”) . Các phần in nghiêng biểu thị một định danh(identifier) nào đó, như tên của lớp hay giao diện (interface). Nếu bạn không khai báo rõ ràng các mục thêm vào, bộ dịc của Java sẽ hiểu ngầm định lớp của bạn là một lớp con của lớp Object có tính chất : không công khai (nonpublic), không trừu tượng (nonabstract), không phải là lớp cuối (nonfinal), không triển khai một giao diện nào cả.
Danh sách dưới đây cung cấp cho bạn một số chi tiết về các thành phần trong khai báo lớp. Đồng thời, nó cũng liên kết đến một số chương khác (có nói tới ý nghĩa của các phần này, ảnh hưởng của chúng tới các lớp và các chương trình Java của bạn ) trong giáo trình này.

public
Theo ngầm định, một lớp chỉ có thể được sử dụng bởi các lớp khác trong cùng một gói(package). Bổ từ public cho biết rằng lớp đó có thể đựơc sử dụng bởi bất cứ lớp nào không quan tâm tới gói của nó.

abstract
Bổ từ này chỉ ra rằng lớp không cho phép thể hiện(instantiate).

final
Bổ từ này cho biết lớp không thể là lớp con của bất cứ lớp nào khác.

class NameOfClass
Từ khóa class chỉ cho bộ dịch của Java biết rằng đây là khai báo lớp, tên của lớp là NameOfClass.

extends Super
Mệnh đề extends cho biết Super như là một siêu lớp (superclass) của lớp đó,liên quan tới việc thêm vào lớp đó sự phân cấp lớp(class hierarchy).

implements Interfaces
Để khai báo rằng lớp của bạn triển khai một hoặc nhiều giao diện nào đó, bạn có thể dùng từ khóa implements kèm theo dấu phẩy để liêt kê tên của các giao diện được cài đặt trong lớp đó.

2. Thân lớp
Phần thân lớp tiếp theo phần khai báo lớp và được bao bởi hai ngoặc nhọn ({}). Phần thân lớp chứa phần khai báo cho tất cả các biến chương trình (instance variable) và các biến lớp -class variable-(gọi chung là các biến bộ phận-member variable) của lớp đó. Thêm vào đó, thân lớp còn gồm các khai báo và cài đặt cho tất cả các phương thức(instance method) và phương thức-lớp(class method) – được gọi chung là các phương thức- của lớp đó.

Thân lớp chứa toàn bộ mã chương trình cung cấp cho vòng đời của đối tượng được tạo ra bởi lớp đó: constructor cho việc khởi tạo một đối tượng mới, khai báo cho các biến cung cấp trạng thái của lớp và các đối tượng của nó, các phương thức để triển khai hành động của lớp và các đối tượng của nó, và hãn hữu lắm, một phương thức cuối hóa (finalize method) để cung cấp các thao tác dọn dẹp một đối tượng sau khi nó đã xong việc.
Các biến và các phương thức được gọi chung là các bộ phận.
Chú ý: Các Constructors (tạm dịch là hàm dựng) không phải là phương thức cũng chẳng phải là bộ phận.
Lớp Stack định nghĩa một biến bộ phận trong phần thân của nó để chứa các phần tử của nó – véc-tơ items. Nó cũng định nghĩa một hàm dựng -- một hàm dựng không có đối số-- và ba phương thức: push, pop, và isEmpty.

3. Cung cấp các Constructors cho lớp của bạn
Một lớp có thể chứa một hoặc nhiều hàm dựng (constructor) cung cấp các thao tác khởi tạo một đối tượng được tạo ra từ lớp đó. Mục này chỉ cho bạn cách viết một hàm dựng.
Cung cấp các constructor cho lớp của bạn

Tất cả các lớp trong Java đều có những constructor (tạm dich là hàm dựng) có vai trò khởi tạo một đối tượng mới của lớp đó. Hàm dựng có cùng tên với lớp. Ví dụ, tên của hàm dựng của lớp Stack là Stack, tên constructor của lớp Rectangle là Rectangle, và tên constructor của lớp Thread là Thread. Lớp Stack của chúng ta chi định nghĩa một constructor đơn:

public Stack() {
items = new Vector(10);
}

Java cung cấp tên đè lên nhau cho các constructor , vì thế một lớp có thể có nhiều constructor, tất cả chúng đều cùng tên. Dưới đây là một constructor khác có thể được định nghĩa bởi Stack. Constructor đặc biệt này đặt cỡ khởi tạo cho ngăn xếp theo tham số của nó:

public Stack(int initialSize) {
items = new Vector(initialSize);
}

Cả hai constructor đều chia sẻ chung một tên, Stack, nhưng chúng có danh sách tham số khác nhau. Bộ dịch phân biệt các constructor này dựa trên số các tham số có trong danh sách và kiểu của chúng.
Thông thường, một constructor dùng các tham số của nó để khởi tạo một trạng thái của đối tượng mới. Khi tạo ra một đối tượng, chúng ta chọn constructor nào mà có tham số phù hợp nhất với những gì ta muốn khởi tạo cho đối tượng mới.
Dựa trên số lượng và kiểu của các tham số mà bạn đưa(pass) vào constructor, bô dịch có thể xác định constructor nào cần được sử dụng. Bộ dịch biết rằng khi bạn viết những dòng lệnh sau, nó nên dùng một constructor có một tham số kiểu số nguyên:

new Stack(10);

Tương tự, khi bạn viết những dòng lệnh sau đây, bộ dich sẽ chọn một constructor không có tham số hay constructor ngầm định:

new Stack();

Khi bạn viết một lớp theo cách riêng, bạn không phải cung cấp các constructor cho nó. constructor ngầm định được hệ thống tạo ra một cách tự động cho tất cả các lóp không có constructor. constructor ngầm định này không làm việc gì cả. Vì thế, nếu bạn muốn thực hiện một số khởi tạo nào đó, bạn sẽ phải viết các constructor cho lớp của mình.
constructor của lớp con sau đây của lớp Thread thực hiện một hình ảnh động, cài đặt một số giá trị ngầm định, như là tốc độ của ảnh và số ảnh, và sau đó là tải ảnh:

class AnimationThread extends Thread {
int framesPerSecond;
int numImages;
Image[] images;
AnimationThread(int fps, int num) {
super("AnimationThread");
this.framesPerSecond = fps;
this.numImages = num;
this.images = new Image[numImages];
for (int i = 0; i <= numImages; i++) {
. . .
// Load all the images.
. . .
}
}
. . .
}

Chú ý về sự giống nhau của một constructor so với một phương thức; ở đó, nó có chứa các khai báo biến cục bộ, các vòng lặp, và các câu lệnh khác. Tuy nhiên, có một dòng trong constructor AnimationThread mà bạn không thể thấy trong một phương thức bình thường:

super("AnimationThread");

Dòng này kích hoạt một constructor cung cấp bởi siêu lớp của AnimationThread là Thread. Constructor Thread đặc biệt này đặt tên cho Thread với một chuỗi kí tự(String). Thông thường, một constructor muốn tạo ra những khởi tạo có ích được viết trong siêu lớp của lớp đó. Thật vậy, một số lớp phải gọi các constructor của siêu lớp của nó để đối tượng có thể làm việc đúng đắn. Constructor của siêu lớp phải được viết trong dòng đầu tiên của constructor của lớp con: Một đối tượng nên thực hiện các khởi tạo ở mức cao hơn(higher-level) trước.
Bạn có thể xác định những gì mà các đối tượng khác có thể tạo ra các thể hiện(instance) của một lớp bằng một định hướng truy cập trong khai báo của constructor:

private
Không một lớp nào khác có thể thể hiện được lớp của bạn. Lớp của bạn có thể chứa một số phương thức công khai(đôi khi còn được gọi là các các phương thức factory).Các phương thức này có thể tạo nên một đối tượng và trả về đối tượng đó, nhưng không một lớp nào các có thể làm được.

protected
Chỉ các lớp con của lớp đó và các lớp trong cùng một gói mới được phép tạo các thể hiện của lớp đó.

public
Một lớp bất kì đều tạo được một thể hiện của lớp của bạn.

Không xác định
Chỉ các lớp cùng gói với lớp của bạn mới được phép tạo ra một thể hiện của nó.

Các constructor cung cấp cách thức để khởi tạo một lớp mới. Bài Khởi tạo một thể hiện và bộ phận của lớp miêu tả các cách khởi tạo một lớp và một đối tượng được tạo ra. Bài đó cũng bàn về việc khi nào và tại sao bạn có thể dùng các kĩ thuật đó.

4. Khai báo các biến bộ phận
Các biến bộ phận biểu thị cho các trạng thái của một lớp. Bạn có thể khai báo các biến bộ phận của một lớp trong thân của lớp đó. Thông thường, bạn khai báo các biến của một lớp trước khi khai báo các phương thức của nó, mặc dù điều này là không bắt buộc.

classDeclaration {
member variable declarations
method declarations
}

Chý ý: Để khai báo các biến là bộ phận của một lớp, phần khai báo phải được viết trong thân lớp. nhưng không được khai báo trong một thân của môt phương thức nào đó. Các biến được khai báo trong thân của một phương thức là những biến cục bộ, chỉ có giá trị trong phương thức đó mà thôi.
Khai báo các biến bộ phận Stack dùng dòng lệnh sau đây để định nghĩa một biến bộ phận của nó:

private Vector items;

Dòng lệnh trên khai báo một biến bộ phận chứ không phải một loại biến nào khác(như biến cục bộ chẳng hạn) bởi vì dòng khai báo xuất hiện trong thân của lớp và nằm ngoài tất cả các phương thức và hàm dựng. Biến bộ phận được khai báo với tên gọi items, và kiểu của nó là kiểu Vector. Đồng thời, từ khóa private xác định items như là một bộ phận riêng (private). Điều này có nghĩa là chỉ các dòng lệnh trong lớp Stack mới được phép truy cập nó.

accessLevel Chỉ ra cấp truy cập bộ phận này.

static Khai báo một lớp bộ phận.

final Chỉ ra nó là hằng.

transient Biến loại tạm thời

violate Biến loại xung đột

type name Kiểu và tên của biến.

Đây là một khai báo biến bộ phận tương đối đơn giản, các khai báo có thể phức tạp hơn. Bạn có thể không dùng chỉ kiểu, tên, cấp truy cập mà còn dùng các thuộc tính khác nữa ,như là khi nào thì biến là một lớp hoặc là một biến thể hiện hay khi nào thì nó là hằng. Mỗi thành phần của một khai báo biến bộ phận có thể đựơc định nghĩa sâu hơn như sau:

accessLevel
Cho phép bạn điều khiển những lớp nào khác có quyền truy cập vào biến bộ phận thông qua việc dùng một trong bốn cấp là: công khai(public), bảo hộ(protected), gói(package) và cá nhân(private). Bạn có thể điều khiển việc truy cập cho các phương thức trong cùng cách thức như thế. Bài Điều khiển sự truy cập vào các bộ phận của một lớp sẽ thảo luận vấn đề này chi tiết hơn.

static
Khai báo đây là một biến lớp chứ không phải là một biến thể hiện. Bạn cũng có thể dùng static để khai báo các phương thức . Bài Tìm hiểu các thể hiện bộ phận và lớp bộ phận sau đây trong bài này sẽ nói về việc khai báo các thể hiện và các biến lớp.

final
Chỉ ra rằng giá trị của bộ phận này không thể thay đổi được. Ví như khai báo biến sau đây định nghĩa một hằng có tên AVOGADRO, có giá trị là số Avogadro(6.022*1023) và không thể thay đổi đựơc:
final double AVOGADRO = 6.022e23;
Nếu bạn cố gắng thay đổi giá trị của biến cuối(final), một lỗi dịch sẽ xảy ra. Theo lệ thường, tên của một giá trị hằng thường được viết hoa.

transient
Chỉ thị transient không được xác định hoàn toàn xác định trong Đặc tả ngôn ngữ Java(The Java Language Specification) nhưng được dùng trong đối tượng serial hóa(được thảo luận trong Serial hóa đối tượng (in the Learning the Java Language trail))

volatile
Từ khóa violate được dùng để ngăn cản bộ dịch thực hiện tối ưu hóa trên một bộ phận. Đây là một tính năng nâng cao của Java, chỉ một số ít lập trình viên dùng nó, và không được thảo luận trong bài này.

type
Giống như các biến, một biến bộ phận phải có kiểu. Bạn có thể dùng các tên kiểu nguyên thủy như int, float hay boolean. Hoặc cũng có thể tham chiếu các kiểu nào đó như mảng, đối tượng hay một tên giao diện nào đó.

name
Tên của một biến bộ phận có thể là một định danh hợp lệ nào đó trong Java và, theo quy ước, bắt đầu bằng một chữ cái viết thường. Bạn không thể khai báo nhiều hơn một biến bộ phận có cùng tên trong cùng một lớp, nhưng một biến bộ phận và một phương thức có thể trùng tên. Ví dụ, đoạn mã dưới đây là hợp lệ:

public class Stack {
private Vector items;
// a method with same name as a member variable
public Vector items() {
. . .
}
}
Câu trả lời

- Bạn đã sẵn sàng thảo luận về chủ đề này. Hãy bấm "Viết bình luận", bạn có thể lựa chọn sử dụng tài khoản Facebook hoặc Google++

- Vì sự phát triển của cộng đồng CNTT/CNPM tại Việt Nam!

Unknown user
No responses yet

2014-11-1-49-3-899Facebook-Likejpg
0 Lượt thích

bài chia sẻ chi tiết quá! xin cảm ơn
0 Lượt thích

Từ khóa tìm kiếm

Câu trả lời mới nhất

Tin tuyển dụng