Nền Tảng Lập Trình Hướng Đối Tượng Với Java

Triết Lý Hướng Đối Tượng Trong Phát Triển Phần Mềm

Phương pháp lập trình hướng đối tượng (OOP) tập trung vào việc mô hình hóa các vấn đề thực tế thông qua các thực thể riêng biệt gọi là đối tượng. Thay vì viết các thuật toán tuyến tính đơn thuần, cách tiếp cận này phân tách logic thành các khối chức năng tự quản lý. Mục tiêu chính bao gồm việc đóng gói dữ liệu, cho phép mở rộng tính năng mà không thay đổi mã gốc, và đảm bảo hành linh hoạt tương tác.

Các Đặc Tính Chủ Chốt của OOP

Hệ thống hướng đối tượng dựa trên ba trụ cột kỹ thuật quan trọng:

  1. Đóng gói (Encapsulation): Là cơ chế bảo vệ trạng thái nội bộ của đối tượng bằng cách ẩn đi các chi tiết cài đặt phức tạp. Chỉ những gì cần thiết mới được phơi bày ra ngoài qua các giao diện công khai.
  2. Kế thừa (Inheritance): Cho phép một lớp mới kế thừa thuộc tính và phương thức từ một lớp đã có sẵn. Điều này tối ưu hóa việc tái sử dụng mã nguồn và thiết lập mối quan hệ phân cấp cha-con.
  3. Đa hình (Polymorphism): Khái niệm này cho phép cùng một lệnh gọi có thể thực thi các hành vi khác nhau tùy thuộc vào kiểu đối tượng cụ thể đang được xử lý tại thời điểm chạy.

Cấu Trúc Lớp Và Khởi Tạo Đối Tượng

Mọi đối tượng trong Java đều được xây dựng dựa trên định nghĩa của Lớp (Class). Lớp đóng vai trò là khuôn mẫu (blueprint), trong khi đối tượng là phiên bản cụ thể được tạo ra từ khuôn mẫu đó.

Quy Định Tổng Quát Của Một Lớp

Để định nghĩa một cấu trúc dữ liệu mới, ta sử dụng cú pháp sau:

<span class="token keyword">class</span> TenLop {
    // Thuộc tính dữ liệu
    private KiDuLieu tenThuocTinh;

    // Hành động xử lý
    public void phuongThucHanhDong() {
        // Logic xử lý
    }
}

Quá Trình Khai Sinh Đối Tượng

Sau khi có định nghĩa lớp, bước tiếp theo là khởi tạo đối tượng trong bộ nhớ. Quá trình này bao gồm hai giai đoạn: định nghĩa biến tham chiếu và cấp phát vùng nhớ thực tế thông toán tử new.

Có hai cách thường dùng để thực hiện điều này:

  1. Tách biệt hai dòng lệnh:
  2. TypeTenLop tenBien = null;
    tenBien = new TypeTenLop();
        
  3. Gộp chung làm một bước:
  4. TypeTenLop tenBien = new TypeTenLop();
        

Ví dụ cụ thể về một tài khoản ngân hàng:

public class TaiKhoan {
    double soDu;

    public TaiKhoan(double duBatDau) {
        this.soDu = duBatDau;
    }
}

// Sử dụng
TaiKhoan tk = new TaiKhoan(1000000);

Toán tử gán = sẽ lưu địa chỉ vùng nhớ (heap address) của đối tượng vừa sinh vào biến tham chiếu (tk).

Bản Chất Của Tham Chiếu Dữ Liệu

Trong Java, biến của kiểu dữ liệu lớp (Reference Types) không lưu trữ trực tiếp dữ liệu mà lưu trữ đường dẫn trỏ đến nơi lưu trữ dữ liệu thực sự (vùng nhớ Heap). Do đó, một đối tượng trên Heap có thể được nhiều biến tham chiếu trỏ tới cùng lúc, tạo điều kiện cho việc chia sẻ dữ liệu giữa các phần của chương trình.

Kiểm Soát Truy Cập Dữ Liệu

Để đảm bảo tính đóng gói, Java cung cấp các quyền truy cập (Access Modifiers) quyết định khả năng hiển thị của các thành phần bên trong lớp:

  • Private: Chỉ truy cập được bên trong cùng lớp.
  • Protected: Truy cập trong lớp và các lớp con (chứa).
  • Public: Mở hoàn toàn cho tất cả mọi nơi.
  • Default (không modifier): Chỉ truy cập được trong cùng package.

Thiết Kế Đóng Gói Với Getter/Setter

Việc ẩn thuộc tính giúp ngăn chặn việc sửa đổi dữ liệu trái phép. Để kiểm soát điều này, ta sử dụng các hàm truy xuất:

  1. Setter: Gán giá trị cho thuộc tính kèm logic kiểm tra (ví dụ: tiền âm thì báo lỗi).
  2. Getter: Lấy giá trị nguyên bản trả về cho người gọi.

Phương Thức Khởi Tạo (Constructor)

Đây là hàm đặc biệt dùng để thiết lập trạng thái ban đầu cho đối tượng ngay khi nó được tạo. Các quy tắc bắt buộc:

  • Tên hàm phải trùng khít với tên Class.
  • Không khai báo kiểu trả về (trừ trống).
  • Có thể gọi lại các constructor khác (chaining).
public class NhanVien {
    String hoTen;

    public NhanVien(String ten) {
        this.hoTen = ten;
    }

    // Constructor ghi đè (Overload)
    public NhanVien() {
        this("Nhân viên mặc định");
    }
}

Vai Trò Của Từ Khoá 'this'

Biến this đại diện cho đối tượng hiện hành đang thực thi. Nó phục vụ ba mục đích chính:

  1. Phân biệt xung đột tên: Khi tên tham số truyền vào trùng với tên thuộc tính của class.
  2. Gọi phương thức: Gọi các hàm khác trong cùng một lớp.
  3. Gọi Constructor khác: Chuyển hướng quá trình khởi tạo sang constructor có tham số phù hợp hơn.

Lưu ý quan trọng: Câu lệnh gọi constructor bằng this() bắt buộc phải nằm ở dòng đầu tiên của body constructor và chỉ được tồn tại duy nhất một lần.

Xử Lý Vùng Nhớ Với Code Block Và Từ Khoá Static

Khi chương trình tải một class, các khối lệnh (blocks) sẽ được thực thi theo thứ tự ưu tiên cố định trong JVM:

  1. Static Code Block: Khối có tiền tố static. Được thực hiện duy nhất một lần khi class được nạp vào bộ nhớ.
  2. Constructor Code Block: Các dòng lệnh nằm trong class nhưng nằm ngoài hàm constructore. Thực thi mỗi khi khởi tạo một object mới.
  3. Constructor Method: Hàm khởi tạo cuối cùng được gọi để hoàn thiện đối tượng.

Tính Tĩnh (Static): Các biến và phương thức được gắn cờ static thuộc về Class chứ không thuộc về Instance cụ thể.

  • Truy cập tĩnh: Có thể gọi bằng tên Class.tênThànhPhần mà không cần tạo đối tượng mới.
  • Ứng dụng: Thường dùng cho hằng số toàn cục hoặc các công cụ hỗ trợ.

Thẻ: Java oop encapsulation inheritance static_keyword

Đăng vào ngày 19 tháng 5 lúc 01:12