Đặc điểm hướng đối tượng trong java

1. Đóng gói (encapsulation)

Cơ chế đóng gói trong lập trình hướng đối tượng giúp cho các đối    tượng   dấu      đi         một      phần    các chi          tiết       cài   đặt, cũng  như phần dữ liệu cục bộ của nó, và chỉ công bố ra ngoài những gì cần công bố để trao đổi với các đối tượng khác. Hay chúng ta có thể nói đối tượng là một thành tố hỗ trợ tính đóng gói.

Đơn vị đóng gói cơ bản của ngôn ngữ java là class. Một class định nghĩa hình thức của một đối tượng. Một class định rõ những thành phần dữ liệu và các đoạn mã cài đặt các thao tác xử lý trên các đối tượng dữ liệu đó. Java dùng class để xây dựng những đối tượng. Những đối tượng là những thể hiện (instances) của một class.

Một lớp bao gồm thành phần dữ liệu và thành phần xử lý. Thành phần dữ liệu của một lớp thường bao gồm các biến thành viên và các biến thể hiện của lớp. Thành phần xử lý là các thao tác trên các thành phần dữ liệu, thường trong java người gọi là phương thức. Phương thức là một thuật ngữ hướng đối tượng trong java, trong C/C++ người ta thường dùng thuật ngữ là hàm.

2. Tính đa hình (polymorphism):

Tính đa hình cho phép cài đặt các lớp dẫn xuất khác nhau từ một lớp nguồn. Một đối tượng có thể có nhiều kiểu khác nhau gọi là tính đa hình.

Ví dụ:

class AObject {

//…

void method_1()

{

//…

}

}

class B Object extends A Object {

//…

void method_1()

{

//…

}

}

class C

{ public static void main(String[] args)

{ ‘

// Tạo một mảng 2 phần tử kiểu A A Object arr Object = new A_Object[2];

B Object var_1 = new B_Object();

// Phần tử đầu tiên của mảng arr_Object[0] tham // chiếu đến 1 đối tượng kiểu B Object dẫn xuất // từ AObject arr_Object[0] = var_1;

A Object var_2; for (int i=0; i<2; i++)

{

var_2 = arr_Object[i]; var_2. method_1 ();

}

}

}

Vòng lặp for trong đoạn chương trình trên:

  • Với i = 0 thì biến var_2 có kiểu là B_Object, và lệnh var_2.method_1() sẽ         gọi       thực     hiện                                 phương   thức

method_1 của lớp B_Object.

  • Với i = 1 thì biến var_2 có kiểu là A_Object, và lệnh var_2.method_1() sẽ         gọi       thực     hiện                                 phương   thức

method_1 của lớp A_Object.

Trong ví dụ trên đối tượng var_2 có thể nhận kiểu A_Object hay B_Object. Hay nói các khác, một biến đối tượng kiểu A_Object như var_2 trong ví dụ trên có thể tham chiếu đến bất kỳ đối tượng nào của bất kỳ lớp con nào của lớp A_Object (ví dụ var_2 có thể tham chiếu đến đối tượng var_1, var_1 là đối tượng của lớp B_Object dẫn xuất từ lớp A_Object). Ngược lại một biến      của lớp               con không    thể    tham chiếu       đến      bất       kỳ        đối

tượng nào của lớp cha.

3. Tính kế thừa (inheritance)

Một lớp con (subclass) có thể kế thừa tất cả những vùng dữ liệu và phương thức của một lớp khác (siêu lớp – superclass). Như vậy việc tạo  một lớp        mới từ một   lớp      đã        biết      sao cho các

thành phần (fields và methods) của lớp cũ cũng sẽ thành các thành phần (fields và methods) của lớp mới. Khi đó ta gọi lớp mới là lớp dẫn xuất (derived class) từ lớp cũ (superclass). Có thể lớp cũ cũng là lớp được dẫn xuất từ một lớp nào đấy, nhưng đối với lớp mới   vừa tạo thì   lớp cũ       đó là       một lớp  siêu    lớp       trực

tiếp (immediate supperclass).

Dùng từ khóa extends để chỉ lớp dẫn xuất.

class A extends B

{

//…

}

3.1.Khái báo phương thức chồng

Tính kế thừa giúp cho các lớp con nhận được các thuộc tính/phương thức public và protected của lớp cha. Đồng thời cũng có     thể  thay thế  các  phương  thức  của  lớp  cha  bằng  cách

khai báo chồng. Chẳng hạn phương thức tinhgiaban() áp dụng trong lớp xega sẽ cho      kết       quả      gấp       2.5                  lần         chi phí   sản xuất thay

vì gấp 2 chi phí sản xuất giống như trong lớp xemay.

Ví dụ:

public class xega extends xemay {

public xega()

{

}

public xega(String snhasx, String s model, fchiphisx, int ithoigiansx);

{

this.nhasx = snhasx; this.model = smodel; this.chiphisx = fchiphisx; this.thoigiansx = ithoigiansx; this.so = 0;

}

public float tinhgiaban()

{

return 2.5 * chiphisx;

}

}

Java cung cấp 3 tiền tố/từ khóa để hỗ trợ tính kế thừa của lớp:

  • public: lớp có thể truy cập từ các gói, chương trình khác.
  • final: Lớp hằng, lớp không thể tạo dẫn xuất (không thể có con), hay đôi khi người ta gọi là lớp “vô sinh”.
  • abstract: Lớp trừu tượng (không có khai báo các thành phần và các phương thức trong lớp trừu tượng). Lớp dẫn xuất sẽ khai báo, cài đặt cụ thể các thuộc tính, phương thức của lớp trừu tượng.
  • Lớp nội

Lớp nội là lớp được khai báo bên trong 1 lớp khác. Lớp nội thể hiện tính đóng gói cao và có thể truy xuất trực tiếp biến của lớp cha.

Ví dụ:

public class A {

//…

int <field1> static class B {

//…

int <field_2> public B(int par_1)

{

field_2 = par_1 + fieldl;

}

}

}

Trong ví dụ trên thì chương trình dịch sẽ tạo ra hai lớp với hai files khác nhau: A.class và B.class

3.2.Lớp vô sinh

Lớp không thể có lớp dẫn xuất từ nó (không có lớp con) gọi là lớp “vô sinh”, hay nói cách khác không thể kế thừa được từ một lớp “vô sinh”. Lớp “vô sinh” dùng để hạn chế, ngăn ngừa các lớp khác dẫn xuất từ nó.

Để khai báo một lớp là lớp “vô sinh”, chúng ta dùng từ khóa final class.

Tất cả các phương thức của lớp vô sinh đều vô sinh, nhưng các thuộc tính của lớp vô sinh thì có thể không vô sinh.

Ví dụ:

public final class A {

public final int x; private int y;

public final void method_1()

{

//…

}

public final void method_2()

{

//…

}

}

3.3.Lớp trừu tượng

Lớp trừu tượng là lớp không có khai báo các thuộc tính thành phần  và các  phương thức.    Các      lớp       dẫn                      xuất      của        nó      sẽ

khai báo thuộc tính, cài đặt cụ thể các phương thức của lớp trừu tượng.

Ví dụ:

abstract class A {

abstract void method_1();

}

public class B extends A {

public void method1()

{

// cài đặt chi tiết cho phương thức methodl // trong lớp con B.

//…

}

}

public class C extends A {

public void method_1()

{

// cài đặt chi tiết cho phương thức methodl // trong lớp con C.

//…

}

}

Lưu ý: Các phương thức được khai báo dùng các tiền tố private và static thì không được khai báo là trừu tượng abstract. Tiền tố private thì không thể truy xuất từ các lớp dẫn xuất, còn tiền tố static thì chỉ dùng riêng cho lớp khai báo mà thôi.

3.4.Phương thức finalize()

Trong java không có kiểu dữ liệu con trỏ như trong C, người lập trình không cần phải quá bận tâm về việc cấp phát và giải phóng vùng nhớ, sẽ có một trình dọn dẹp hệ thống đảm trách việc này. Trình dọn dẹp hệ thống sẽ dọn dẹp vùng nhớ cấp phát cho các đối tượng trước khi hủy một đối tượng.

Phương thức finalize() là một phương thức đặc biệt được cài đặt sẵn cho các lớp. Trình dọn dẹp hệ thống sẽ gọi phương thức này trước       khi  hủy           một đối   tượng. Vì      vậy việc      cài        đặt       một      số thao tác giải phóng, dọn dẹp vùng nhớ đã cấp phát cho các đối tượng dữ liệu trong phương thức finalize() sẽ giúp cho người lập trình chủ động kiểm soát tốt quá trình hủy đối tượng thay vị giao cho trình dọn dẹp hệ thống tự động. Đồng thời việc cài đặt trong phương thức finalize() sẽ giúp cho bộ nhớ được giải phóng tốt hơn, góp phần cải tiến tốc độ chương trình.

Ví dụ:

class A {

// Khai báo các thuộc tính public void method1()

{

//…

}

protected voidfinalize()

{

// Có thể dùng để đóng tất cả các kết nối // vào cơ sở dữ liệu trước khi hủy đối tượng.

//…

}

}