Giải thích sự khác nhau giữa một hàm thành phần của lớp và một hàm của chương trình

Lớp là gì?

Một lớp là một thực thể xác định cách một đối tượng sẽ hành xử và những gì đối tượng sẽ chứa.Nói cách khác, đó là một kế hoạch chi tiết (blueprint) hoặc một bộ hướng dẫn để xây dựng một loại đối tượng cụ thể.

Cú pháp

class { khai báo thuộc tính; khai báo phương thức; }


Đối tượng là gì?

Một đối tượng bao gồm các phương thức (method) và thuộc tính (property) để tạo thành một kiểu dữ liệu cụ thể hữu ích.Đối tượng xác định hành vi của lớp.Khi bạn gửi tin nhắn đến một đối tượng, bạn đang yêu cầu đối tượng gọi hoặc thực thi một trong các phương thức của nó.
Dưới góc nhìn của lập trình, một đối tượng có thể là cấu trúc dữ liệu, biến hoặc hàm.Nó có một vị trí bộ nhớ được cấp phát.

Cú pháp

ClassName referenceVariable = new ClassName();

1. Object (Đối tượng).

Các bạn có thể hình dung về khái niệm đối tượng như sau: Trong lập trình hướng đối tượng, một thực thể được gọi là đối tượng nếu thực thể đó có 2 đặc điểm: trạng thái (state) và hành vi (behavior).

Ví dụ: là con người thì chúng ta sẽ có các trạng thái như: màu da, màu mắt, màu tóc, chiều cao, cân nặng,..., có các hành vi như: ăn, uống, làm việc,... ⇒ con người là 1 đối tượng.

Như vậy, thông qua ví dụ trên chúng ta có thể định nghĩa đối tượng như sau: đối tượng là một khái niệm được dùng để chỉ một thực thể cụ thể có trạng thái và hành vi. Một thực thể sẽ không được gọi là đối tượng nếu thực thể đó không thỏa mãn một trong các điều kiện trên.

Trạng thái: Những đặc điểm của một đối tượng, chẳng hạn như đối tượng Sinh viên thì có mã, họ tên, ngày tháng năm sinh,...

Hành vi: Những hành động mà một đối tượng thực hiện, ví dụ: Sinh viên thì có các hành vi như đi học, đi dã ngoại vui chơi giải trí,...

2. Class (Lớp).

Lớp là một tập hợp các đối tượng có cùng trạng thái và hành vi, vì vậy nó định nghĩa các tính chất của một tập hợp các đối tượng cùng kiểu. Ví dụ: Lớp Student sẽ bao gồm một tập hợp các sinh viên của một lớp học, lớp Mammals sẽ bao gồm một tập hợp các động vật có vú trên thế giới,...

Mỗi đối tượng là một thể hiện (instance) của lớp. Thông thường, các đối tượng trọng cùng một lớp sẽ có cùng một hành vi (behavior), nghĩa là có cách thức hoạt động tương tự như nhau. Cách thức hoạt động của các đối tượng thuộc về một lớp được thiết lập nhờ vào những phương thức (method) của lớp đó.

Cấu trúc của một lớp:

Giải thích sự khác nhau giữa một hàm thành phần của lớp và một hàm của chương trình

access_modifier: phạm vi truy cập của lớp, thuộc tính và phương thức.

Tên lớp (class name): mỗi lớp có một tên duy nhất để phân biệt với các lớp khác trong cùng một phạm vi.

Các thuộc tính (attributes): mô tả các trường để lưu dữ liệu cho mỗi đối tượng của lớp đang mô tả hay là lưu các tham chiếu đến các đối tượng của lớp khác. Sau này khi tạo lập một đối tượng của lớp thì mỗi thành phần dữ liệu trong đối tượng sẽ chứa hay liên kết với đối tượng dữ liệu cần thiết.

Hệ thống các phương thức của lớp (methods): mỗi phương thức của lớp thực chất là một hàm được viết riêng cho các đối tượng của lớp, chỉ được phép gọi để tác động lên chính các đối tượng của lớp này.

Dưới đây là ví dụ minh họa của 1 lớp.

Ví dụ
public class Student { // thuộc tính (instance variable) private String id; private String name; private String information; // Phương thức này có tên inputInformation và không có giá trị trả về public void inputInformation() { } // Phương thức này có tên showInformation và có kiểu trả về là String public String showInformation() { } // hàm main public static void main(String[] args) { } }

Sau đây là một số vấn đề mà chúng ta cần nắm khi xem qua cấu trúc của lớp. Những vấn đề này chúng ta sẽ tìm hiểu rõ hơn trong các bài sau.

Phạm vi truy cập (Access Modifier) của lớp, thuộc tính và phương thức

Trong Java, có 4 phạm vi truy cập sau: public, private, protected và default (mặc định). Bảng dưới đây sẽ giới thiệu tổng quan về phạm vi của 4 loại quyền truy cập này. Sang các bài sau, tôi sẽ nói rõ hơn về phạm vi truy cập trong Java.

  • public: có thể truy cập ở mọi nơi trong Project.
  • protected: truy cập được từ trong lớp khai báo, lớp con của lớp khai báo và các lớp cùng gói với lớp khai báo.
  • default: truy cập được từ trong lớp khai báo và các lớp cùng gói với lớp khai báo.
  • private: chỉ có thể truy cập bên trong lớp.

Thuộc tính (Instance variable).

Thuộc tính là 1 biến được khai báo bên trong lớp nhưng ở bên ngoài một phương thức, hàm tạo hoặc 1 khối lệnh. Thuộc tính được khởi tạo khi một lớp được khởi tạo và có thể được sử dụng ở bên trong một hàm, hàm tạo hoặc trong một khối lệnh trong lớp đó.

Phương thức

Phương thức là một hàm được viết riêng cho các đối tượng của lớp, chỉ được phép gọi để tác động lên chính các đối tượng của lớp này. Một phương thức của lớp bao gồm 3 thành phần chính đó là phạm vi truy câp, giá trị trả về và tên của phương thức đó.

Một phương thức là một tập hợp các câu lệnh được nhóm lại với nhau để thực hiện một chức năng nào đó. Sau đây tôi sẽ giới thiệu đến các bạn cách tạo và gọi phương thức trong chương trình. Trong bài ngày hôm nay, tôi chỉ minh họa cách khai báo và gọi phương thức thông thường (chưa đề cập đến cách gọi phương thức thông qua đối tượng của lớp).

Tạo phương thức

Cú pháp tạo phương thức như sau:

Cú pháp
[quyền_truy_cập] [kiểu_của_phương_thức] tênPhươngThức(Danh_sách_các_tham_số_truyền_vào) { [Khai báo các biến bên trong phương thức]; [Các câu lệnh bên trong]; return [giá_trị_trả_về]; }

, trong đó:

  • [quyền_truy_cập] là phạm vi truy cập của phương thức (sang bài sau tôi sẽ giới thiệu phần này).
  • [kiểu_của_phương_thức] là kiểu dữ liệu trả về của phương thức đó (void, int, long, float,...).
  • tênPhươngThức là tên do chúng ta tự định nghĩa và phải tuân theo quy tắc đặt tên phương thức (hàm) trong Java.
  • [Danh_sách_các_tham_số_truyền_vào] (nếu có) là các tham số chúng ta truyền vào cho phương thức (thường nằm tại phần đầu của định nghĩa phương thức), với mỗi tham số bao gồm tên tham số và kiểu dữ liệu của tham số. Phương thức có thể có hoặc không có tham số, nếu có nhiều hơn một tham số thì các tham số được viết cách nhau bởi một dấu phẩy.
  • [Các câu lệnh bên trong] là các lệnh trong thân phương thức để xử lý các công việc nhằm thực hiện chức năng của phương thức.
  • [giá_trị_trả_về] : giá trị trả về của phương thức phải phù hợp với [kiểu_của_phương_thức]. Trong trường hợp phương thức có kiểu void thì chúng ta có thể dùng lệnh return để kết thúc hàm hoặc khi thực hiện xong lệnh cuối cùng (gặp dấu } cuối cùng) thì phương thức cũng sẽ kết thúc. Sau lệnh return có thể trả lại 1 biểu thức để tính giá trị.

Gọi phương thức.

Một phương thức có thể được gọi thực hiện thông qua tên phương thức. Ví dụ dưới đây sẽ minh họa cách gọi phương thức trong Java:

Ví dụ
package vidu; public class MethodCallingInJava { // tạo 1 phương thức có kiểu trả về là void và không có tham số truyền vào // để gọi phương thức này trong main() thì phải khai báo là static public static void nhap() { System.out.println("Đây là ví dụ minh họa cách gọi phương thức void không đối trong Java"); } // tạo 1 phương thức có kiểu trả về là void và có tham số truyền vào public static void nhapCoDoiSo(String str) { System.out.println(str); } // tạo 1 phương thức có kiểu trả về là int và có 2 tham số truyền vào có kiểu int public static int tinhTong(int a, int b) { return a + b; } public static void main(String[] args) { nhap(); // gọi phương thức nhap() nhapCoDoiSo("Đây là ví dụ minh họa cách gọi phương thức void có đối số trong Java"); System.out.println("\nĐây là ví dụ minh họa cách gọi phương thức có kiểu trả về" + " là int và có tham số truyền vào trong Java"); int c = tinhTong(3, 5); // c = a + b System.out.println("c = " + c); } }

Kết quả sau khi biên dịch chương trình:

Giải thích sự khác nhau giữa một hàm thành phần của lớp và một hàm của chương trình

Hàm tạo (Constructor).

Trong lập trình hướng đối tượng, chúng ta có 1 loại hàm đặc biệt đó là hàm tạo. Hàm tạo trong Java là hàm có cùng tên với lớp và không có giá trị trả về. Chúng ta hãy xem đoạn chương trình sau:

Ví dụ
public class Student { // thuộc tính (instance variable) private String name; // hàm tạo mặc định public Student() { } // hàm tạo có đối số truyền vào có kiểu String và có tên là name public Student(String name) { } // hàm main public static void main(String[] args) { } }

Một lớp trong Java có thể có một hoặc nhiều hàm tạo. Có 2 loại hàm tạo chúng ta thường gặp đó là: hàm tạo mặc định (không có đối số) và hàm tạo có đối số.

  • Hàm tạo mặc định là hàm tạo không có tham số đầu vào. Trong trường hợp người lập trình không định nghĩa bất kỳ hàm tạo nào thì trình biên dịch sẽ tự động tạo ra một phương thức tạo lập mặc định cho lớp này.
  • Hàm tạo có đối số là các hàm tạo do người dùng định nghĩa với các tham số đầu vào khác nhau để khởi tạo dữ liệu cho đối tượng.

Ví dụ trong đoạn chương trình trên thì lớp Student có hàm public Student() và public Student(String name) là hàm tạo. Trong khi viết chương trình, nếu chúng ta không khởi tạo hàm tạo cho lớp thì khi đó trình biên dịch Java sẽ xây dựng 1 hàm tạo mặc định cho lớp đó.

Ý nghĩa của hàm tạo: tự động khởi tạo các thông tin mặc định khi đối tượng được tạo ra.

Lưu ý: Khi người lập trình khai báo bất kỳ một hàm tạo nào cho lớp thì hàm tạo mặc định sẽ không được phát sinh bởi trình biên dịch cho lớp này nữa. Trong trường hợp này, nếu muốn sử dụng hàm tạo mặc định, người lập trình phải tự viết thêm vào.

Giới thiệu lập trình hướng đối tượng (OOP) với C++

- C++ là ngôn ngữ "lai" giữa lập trình cấu trúc và lập trình hướng đối tượng.

- Lập trình hướng đối tượng (OOP- Object-Oriented Programming) là một cách tư duy mới, tiếp cận hướng đối tượng để giải quyết vấn đề bằng máy tính. Thuật ngữ OOP ngày càng trở nên thông dụng trong lĩnh vực công nghệ thông tin.

- Lập trình hướng đối tượng (OOP) là một phương pháp thiết kế và phát triển phần mềm dựa trên kiến trúc lớp và đối tượng.

- Trong lập trình hướng đối tượng trong mỗi chương trình chúng ta có một số các đối tượng (object) có thể tương tác với nhau , thuộc các lớp (class) khác nhau, mỗi đối tượng tự quản lý lấy các dữ liệu của riêng chúng.


Lập trình hướng đối tượng là gì?

Lập trình hướng đối tượng, hay được gọi đơn giản là Vượt qua OOP, là một mô hình lập trình phần mềm dựa trên khái niệm về các đối tượng, thay vì chỉ các chức năng và quy trình. OOP được thiết kế sao cho khái niệm thế giới thực có thể được lập trình trong một chương trình máy tính. Như tên cho thấy, OOP sử dụng các đối tượng trong lập trình được tổ chức thành các lớp, cho phép các đối tượng riêng lẻ được nhóm lại với nhau. Mỗi đối tượng trong OOP chịu trách nhiệm cho một tập hợp các nhiệm vụ. Vì vậy, các tác vụ khác nhau trong chương trình được thực hiện, bằng cách gọi các hoạt động được xác định trên đối tượng tương ứng. Mặc dù, các tính năng cơ bản của OOP đã được phát minh vào những năm 1960, nhưng mãi đến những năm 1980, các ngôn ngữ hướng đối tượng mới thực sự bắt đầu được chú ý. OOP là một ý tưởng mang tính cách mạng và có một số lý do tại sao nó trở thành mô hình lập trình thống trị trong vài thập kỷ qua.

Giải thích sự khác nhau giữa một hàm thành phần của lớp và một hàm của chương trình

Mục lục

  • 1 Các tính chất cơ bản
  • 2 Một điểm mới về mẫu hình, về quan điểm
  • 3 Các mẫu hình định hướng đối tượng con
    • 3.1 OOP với các ngôn ngữ cấu trúc
    • 3.2 Các mô hình nguyên mẫu cơ bản
    • 3.3 Mô hình đối tượng cơ bản
  • 4 Định nghĩa chuẩn
  • 5 OOP trong văn lệnh
  • 6 Ví dụ mã nguồn trong C++
  • 7 Một số khái niệm cần biết trong ngôn ngữ OOP hiện đại
    • 7.1 Lớp (class)
    • 7.2 Lớp con (subclass)
    • 7.3 Lớp trừu tượng hay lớp cơ sở trừu tượng (abstract class)
    • 7.4 Phương thức (method)
    • 7.5 Thuộc tính (attribute)
    • 7.6 Quan hệ giữa lớp và đối tượng
    • 7.7 Thực thể (instance)
    • 7.8 Công cộng (public)
    • 7.9 Riêng tư (private)
    • 7.10 Bảo tồn (protected)
  • 8 Đa kế thừa (multiple inheritance)
  • 9 Lịch sử
  • 10 Các ngôn ngữ
  • 11 Đọc thêm
  • 12 Các bài liên hệ
  • 13 Tham khảo
  • 14 Liên kết ngoài
    • 14.1 Các phê phán

Mục lục

  • 1 Lớp và kiểu
  • 2 Thiết kế và hiện thực
    • 2.1 Cấu trúc
    • 2.2 Hành vi
    • 2.3 Khái niệm giao diện lớp
      • 2.3.1 Ví dụ
    • 2.4 Khả năng truy cập thành viên
  • 3 Các mối quan hệ giữa các lớp
    • 3.1 Sự hợp thành
    • 3.2 Sự phân cấp
      • 3.2.1 Định nghĩa lớp con
  • 4 Phân loại lớp
    • 4.1 Trừu tượng và cụ thể
    • 4.2 Cục bộ và nội bộ
    • 4.3 Siêu lớp
    • 4.4 Non-subclassable
    • 4.5 Mixins
    • 4.6 Partial
    • 4.7 Không khởi tạo
    • 4.8 Không tên
  • 5 Lợi ích
  • 6 Thể hiện trong thời gian chạy
  • 7 Xem thêm
  • 8 Ghi chú
  • 9 Tham khảo
  • 10 Đọc thêm
  • 11 Liên kết ngoài

Hàm khởi tạo (Constructor)

Hàm khởi tạo là gì?

Hàm khởi tạo là một hàm thành viên đặc biệt của một lớp. Nó sẽ được tự động gọi đến khi một đối tượng của lớp đó được khởi tạo.

Sự khác biệt giữa hàm tạo và hàm thành viên thông thường

Một hàm tạo sẽ khác những hàm thông thường ở những điểm sau:

  • Có tên trùng với tên lớp
  • Không có kiểu dữ liệu trả về ( kể cả kiểu void)
  • Tự động được gọi khi một đối tượng thuộc lớp được tạo ra
  • Nếu chúng ta không khai báo một hàm tạo, trình biên dịch C++ sẽ tự động tạo một hàm tạo mặc định cho chúng ta (sẽ là hàm ​​không có tham số nào và có phần thân trống).

Hàm tạo có thể rất hữu ích để thiết lập các giá trị khởi tạo cho các biến thành viên cụ thể.

Ví dụ đơn giản về hàm khởi tạo:

Các loại hàm khởi tạo

Hàm khởi tạo về cơ bản sẽ được chia làm 3 loại:

  1. Hàm khởi tạo không tham số (Cũng có thể gọi là hàm tạo mặc định – Default Constructor )
  2. Hàm khởi tạo có tham số ( Parameterized Constructor )
  3. Hàm khởi tạo sao chép ( Copy Constructor )

Giải thích sự khác nhau giữa một hàm thành phần của lớp và một hàm của chương trình

Hàm khởi tạo không tham số ( Default Constructor )

Hàm tạo loại này sẽ không truyền vào bất kì một đối số nào

Như trong ví dụ trên, hàm tạo sinhvien() không hề có đối số nào được truyền vào.

Theo ý kiến riêng của mình thì thông thường trong hàm loại này mình sẽ gán cho tất cả các thuộc tính về giá trị mặc định.

Trong ví dụ trên:

  • Thuộc tính ten thuộc kiểu string mình sẽ đưa về mặc định là một chuối rỗng "".
  • Thuộc tính tuoi thuộc kiểu int mình sẽ đưa về mặc định là 0.

Hàm khởi tạo có tham số ( Parameterized Constructor )

Với loại hàm tạo này ta có thể truyền đối số cho chúng. Thông thường, các đối số này giúp khởi tạo một đối tượng khi nó được tạo.

Để khai báo một hàm khởi tạo có tham số chỉ cần thêm các tham số vào nó giống như cách bạn thêm tham số bất kỳ hàm nào khác.Khi bạn xác định phần thân của hàm tạo, hãy sử dụng các tham số để khởi tạo đối tượng.

Sau khi khai báo hàm trong lớp, ta có thể dễ dàng dùng nó bằng cách truyền tham số trong khi khởi tạo đối tượng.

Lưu ý:

  • Khi một đối tượng được khai báo trong hàm khởi tạo có tham số, các giá trị ban đầu phải được truyền dưới dạng đối số cho hàm tạo.
  • Cách khai báo đối tượng bình thường có thể sẽ gây lỗi.
    Điều này có nghĩa là bình thường để khai báo một đối tượng bạn sẽ khai báo bằng cú pháp:

Nhưng do hàm khởi tạo là hàm có tham số nên cú pháp sẽ phải là:

  • Các hàm khởi tạo có thể được gọi một cách rõ ràng hoặc ngầm định.

    Nhưng thông thường để tiết kiệm code thì chúng ta hay sử dụng các ngầm định hơn.
Công dụng của hàm khởi tạo có tham số
  • Nó được sử dụng để khởi tạo các thành phần dữ liệu khác nhau của các đối tượng khác nhau với các giá trị khác nhau khi chúng được tạo.
  • Nó được sử dụng để nạp chồng các hàm khởi tạo.
    Nạp chồng? Có thể hiểu đơn giản là ta sẽ có nhiều hơn một hàm khởi tạo trong cùng một lớp. Và phần này thì sẽ được mình trình bài trong bài sau nhé.

Hàm khởi tạo sao chép ( Copy Constructor )

Hàm khởi tạo sao chép là gì?

Hàm khởi tạo sao chép là một hàm tạo mà tạo một đối tượng bằng việc khởi tạo nó với một đối tượng của cùng lớp đó, mà đã được tạo trước đó.

Một hàm khởi tạo sao chép sẽ có nguyên mẫu chung như sau:

Trong đó Classname là tên của lớp, old_obj là đối tượng cũ sẽ lấy làm gốc để sao chép sang đối tượng mới

Ví dụ đơn giản về hàm khởi tạo sao chép:

Sau khi chạy chương trình ta sẽ có kết quả:

Một hàm khởi tạo sao chép sẽ được gọi khi nào?

Hàm khởi tạo sao chép sẽ được gọi khi:

  1. Khi một đối tượng của lớp được trả về bằng một giá trị.
  2. Khi một đối tượng của lớp được truyền đối số dưới dạng tham số của một hàm.
  3. Khi một đối tượng được tạo ra dựa trên một đối tượng khác cùng lớp.
  4. Khi trình biên dịch tạo một đối tượng tạm thời.

Tuy nhiên trên thực tế thì không chắc chắn rằng hàm khởi tạo sao chép sẽ được gọi trong tất cả 4 trường hợp ở phía trên. Vì C++ tiêu chuẩn sẽ cho phép trình biên dịch tối ưu hoá bản sao trong một số trường hợp nhất định.

Một ví dụ cho điều này là: Ví dụ về tối ưu hoá giá trị trả về ( Có thể gọi tắt là RVO). Xem tại đây

Lưu ý:

Nếu một hàm tạo sao chép không được định nghĩa trong một lớp, trình biên dịch sẽ tự nó định nghĩa nó. Vì thế phải thật lưu ý nếu lớp có các biến con trỏ hoặc có sử dụng cấp phát bộ nhớ động thì nên viết lại hàm.

Chia sẻ nhỏ một chút là mình đã từng mắc lỗi tại đây do khi sử dụng cấp phát bộ nhớ động mà không viết lại hàm khởi tạo sao chép do đó dẫn đến việc truy cập sai ô nhớ.

Hàm tạo trong Java - Mọi điều cần biết về hàm tạo Java

22/05/2021 01:33

(Hàm tạo trong Java) Trong hướng dẫn về Java này, chúng ta sẽ thảo luận mọi thứ mà bạn phải biết về Constructor - Hàm tạo trong Java, sự cần thiết của các hàm tạo, kiểu của nó và các quy tắc để viết các hàm tạo trong Java. Chúng ta cũng sẽ xem các phương thức khác với các hàm tạo trong Java như thế nào.

Mục lục
  • Hàm tạo trong Java
  • Tại sao cần sử dụng hàm tạo trong Java
  • Quy tắc để viết hàm tạo trong Java
  • Cú pháp hàm tạo trong Java
  • Cách Hàm tạo hoạt động trong Java
  • Các loại mã lệnh trong Java
    • Hàm tạo mặc định
    • Hàm tạo tham số
    • Sự khác biệt giữa hàm tạo và phương thức trong Java
  • Điểm quan trọng cần chú ý