Sự Khác Biệt Giữa Class Và Object Trong Java

Class và Object là hai khái niệm quan trọng nhất của ngôn ngữ lập trình hướng đối tượng (OOP), ví dụ Java. Sự khác biệt chính giữa một Class và một Object trong Java đó là Class nó là một bản thiết kế chi tiết để tạo ra các đối tượng khác nhau cùng loại. Điều này có vẻ đơn giản với nhiều bạn nhưng nếu bạn là người mới bắt đầu hoặc chỉ nghe thuật ngữ “Ngôn ngữ lập trình hướng đối tượng” thì có thể không đơn giản như vậy. Tôi đã gặp nhiều sinh viên, người mới bắt đầu và lập trình viên, những người không biết sự khác biệt giữa lớp và đối tượng và thường sử dụng chúng thay thế cho nhau. Ngoài ra API Java có các lớp như java.lang.Object và java.lang.Class cũng gây thêm nhiều nhầm lẫn cho những người mới bắt đầu. Cả hai đều là những thứ hoàn toàn khác nhau, lớp và đối tượng trong OOP là các khái niệm và có thể áp dụng cho tất cả các ngôn ngữ lập trình hướng đối tượng khác, ví dụ như C++ hoặc Scala. Mặt khác, java.lang.Class và java.lang.Object là một phần của API Java. Cùng với các khái niệm OOP khác như Tính trừu tượng, Đóng gói, Kế thừa và Đa hình, đây cũng là một trong những điều cơ bản nhất của lập trình hướng đối tượng cần được hiểu rõ ràng trước khi tiến hành lập trình. Nếu không hiểu rõ về Class và Object, bạn sẽ dễ mắc lỗi hơn, bạn không thể hiểu được chương trình đã viết và bạn sẽ rất khó tìm ra lỗi hoặc sửa lỗi hoặc xử lý các ngoại lệ trong code của bạn. Hơn nữa sự khác biệt giữa lớp và đối tượng cũng là một câu hỏi phỏng vấn lập trình rất phổ biến, thường được hỏi ở các cuộc phỏng vấn.

Sự khác biệt giữa Class và Object trong Java

1) Lớp là bản thiết kế có nghĩa là bạn có thể tạo các đối tượng khác nhau dựa trên một lớp khác nhau.

Xe là tổng quát hơn so với Mercedes, BMW hay Audi có thể được coi là đối tượng vì thực chất chúng là đề là xe nhưng có kích thước, hình dạng, màu sắc và tính năng khác nhau.

2) Một lớp có thể tương tự như cấu trúc (struct) trong ngôn ngữ lập trình C với sự khác biệt duy nhất là cấu trúc không chứa bất kỳ phương thức hoặc hàm nào, trong khi lớp trong Java chứa cả trạng thái và hành vi, trạng thái được biểu thị bằng trường trong lớp. Còn hành vi được điều khiển bởi các chức năng, còn được gọi là các phương thức trong Java, ví dụ start() sẽ thay đổi trạng thái của xe từ dừng sang bắt đầu hoặc chạy và stop() sẽ làm ngược lại.

3) Đối tượng cũng được gọi là cá thể trong Java và mọi cá thể có các giá trị khác nhau.

ví dụ như trong đoạn code sau:

class Person { private String name; public Person(String name) { chúng tôi = name; } public String getName() { return name; }}Person p1 = new Person("Rakesh");Person p2 = new Person("Jimmy");Person p3 = new Person("Peter");

Ở đây Person là một lớp vì nó định nghĩa thiết kế các đối tượng person, tức là lớp Person sẽ quy định một đối tượng person sẽ trông như thế nào, nó sẽ có thuộc tính gì, v.v… Bằng cách đó, lớp được khai báo bởi từ khóa “class” trong Java và p1, p2, p3 là các đối tượng khác nhau của lớp Person . Một điểm khác biệt giữa Class và Object trong Java là chúng ta có từ khóa class để khai báo lớp nhưng không có từ khóa đối với đối tượng. Các đối tượng được tạo đáng chú ý nhất bằng toán tử new(), gọi constructor của lớp để khởi tạo đối tượng trong Java.

Đó là tất cả về sự khác biệt giữa Class và Object trong Java. Như tôi đã nói sự khác biệt chính giữa lớp và đối tượng là Class là một thiết kế của một nhóm các đối tượng mà có các thuộc tính chung trong khi Object là một thực thể là một instance (ví dụ,trường hợp) của một lớp . Lớp sẽ xác định một đối tượng sẽ trông như thế nào và đối tượng thuộc về một lớp cụ thể. Trong ngôn ngữ lập trình hướng đối tượng, bạn có thể tìm thấy các ví dụ thực tế về lớp và đối tượng trong môi trường xung quanh, ví dụ: Nhà có thể là một lớp và nhà của bạn có thể được coi là đối tượng của lớp nhà, vì chúng là nhà nhưng nhà của bạn sẽ khác với các nhà khác.

Sự Khác Nhau Giữa Abstract Class Và Interface

Sự khác nhau giữa Abstract class và Interface

Abstract class và interface đều được sử dụng để có được sự trừu tượng mà ở đó chúng ta có thể khai báo các phương thức trừu tượng. Nhưng có một vài sự khác nhau giữa abstract class và interface được liệt kê trong bảng sau:

Abstract class Interface

1) Abstract class có phương thức abstract (không có thân hàm) và phương thức non-abstract (có thân hàm).

Interface chỉ có phương thức abstract. Từ java 8, nó có thêm các phương thức default và static.

2) Abstract class không hỗ trợ đa kế thừa.

Interface có hỗ trợ đa kế thừa

3) Abstract class có các biến final, non-final, static and non-static.

Interface chỉ có các biến static và final.

4) Abstract class có thể cung cấp nội dung cài đặt cho phương thức của interface.

Interface không thể cung cấp nội dung cài đặt cho phương thức của abstract class.

5) Từ khóa abstract được sử dụng để khai báo abstract class.

Từ khóa interface được sử dụng để khai báo interface.

6) Ví dụ: public abstract class Shape { public abstract void draw(); }

Ví dụ: public interface Drawable { void draw(); }

Đơn giản để hiểu, đó là abstract class có được trừu tượng 1 phần (0 tới 100%), còn interface có được trừu tường toàn phần (100%).

Ví dụ về abstract class và interface trong java

Ví dụ sau là sự kết hợp giữa abstract class và interface.

interface A { void a(); abstract void b(); public void c(); public abstract void d(); } abstract class B implements A { public void c() { System.out.println("I am C"); } } class M extends B { public void a() { System.out.println("I am a"); } public void b() { System.out.println("I am b"); } public void d() { System.out.println("I am d"); } } public class Test5 { public static void main(String args[]) { A a = new M(); a.a(); a.b(); a.c(); a.d(); } }

Output:

I am a I am b I am C I am d

Sự Khác Biệt Giữa Class Và Object Trong Lập Trình Hướng Đối Tượng

Lớp và đối tượng là các thành phần cơ bản trong OOP. Thường có sự nhầm lẫn giữa lớp và các đối tượng. Trong phần này, sẽ giải thích về sự khác biệt giữa lớp và đối tượng.

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

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.

ClassName referenceVariable = new ClassName();

là một kế hoạch chi tiết (blueprint) hoặc nguyên mẫu (prototype) gồm các biến và các phương thức (hàm) chung cho tất cả các đối tượng thuộc cùng một loại.

Một đối tượng là thực thể cụ thể của lớp. Các đối tượng phần mềm thường được sử dụng để mô hình hoá các đối tượng trong thế giới thực trong cuộc sống hàng ngày.

Đây là một ví dụ về việc phát triển một hệ thống quản lý thú cưng, đặc biệt dành cho chó. Bạn sẽ cần nhiều thông tin khác nhau về những chú chó như: giống chó, độ tuổi, cân nặng, kích cỡ v.v.

Bạn cần mô hình hóa những sinh vật ngoài đời thực, tức là chó thành các thực thể phần mềm.

Tuy nhiên, câu hỏi đáng giá triệu đô la là, bạn thiết kế phần mềm như thế nào?

Dừng lại ở đây ngay bây giờ! Liệt kê những khác biệt giữa chúng.

Một số khác biệt bạn có thể liệt kê ra có thể là giống, tuổi, kích cỡ, màu sắc, v.v. Nếu bạn nghĩ trong một phút, những khác biệt này cũng là một số đặc điểm chung được chia sẻ bởi những con chó này. Những đặc điểm này (giống, tuổi, kích thước, màu sắc) có thể tạo thành một thành viên dữ liệu cho đối tượng của bạn.

Tiếp theo, liệt kê các hành vi phổ biến của những con chó này như ngủ, ngồi, ăn, v.v … Đây sẽ là những hành động của các đối tượng phần mềm của chúng ta.

Vậy chúng ta đã xác định những điều sau đây:

Bây giờ, đối với các giá trị khác nhau của các thành viên dữ liệu (kích thước giống, tuổi và màu sắc) trong lớp Java, bạn sẽ nhận được các đối tượng chó khác nhau.

Bạn có thể thiết kế bất kỳ chương trình nào bằng cách sử dụng phương pháp OOP này.

Ví dụ: Tạo lớp và đối tượng

Breed is: Maltese Size is:Small Age is:2 color is: white

Trong chương trình trước, chúng ta đang tạo phương thức main() bên trong lớp Dog. Bây giờ, chúng ta định nghĩa phương thức main() trong một lớp khác ( lớp Exceute). Đây là một cách làm tốt hơn so với cách trước.

Breed is: Maltese Size is:Small Age is:2 color is: white

Lớp Java 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 Một đối tượng Java là một thành phần độc lập bao gồm các phương thức và thuộc tính để tạo thành một kiểu dữ liệu mới.

Phần 22: Class Và Object

Ở phần trước chúng ta đã đề cập tới định nghĩa và các tính chất của Lập trình Hướng đối tượng (OOP). Trong phần này chúng ta sẽ bắt đầu ứng dụng những lí thuyết ấy vào thực hành với C++.

Hãy đọc lại bài Cấu trúc dữ liệu – struct và class. Cài đặt class cũng gần giống như struct, ta sử dụng cú pháp sau:

Ví dụ

Vậy có gì khác biệt giữa struct và class? Có 2 sự khác biệt ở đây

Về mặt ngữ nghĩa, struct thường được sử dụng để định nghĩa các kiểu dữ liệu Plain-Old-Data (dữ liệu không, không bao gồm các chương trình con hay các yếu tố đóng gói). class thường được sử dụng trong lập trình OOP đầy đủ.

Quyền truy cập mặc định tới các yếu tố trong struct là public, còn với class là private.

struct có thể chỉnh sửa được thành class và ngược lại, và có thể sử dụng được các yếu tố của OOP như nhau. Để thống nhất, từ nay trở đi ta sẽ chỉ sử dụng class.

Sau khi định nghĩa class xong, ta có thể định nghĩa các object như các biến thông thường.

Ta cũng truy cập các yếu tố public của object bằng toán tử dấu chấm ..

Ở trên ta có nhắc tới quyền truy cập. Đối với các yếu tố trong class, quyền truy cập mặc định là private – các yếu tố trong class chỉ có thể được truy cập từ nội bộ bên trong class, và từ bên ngoài không thể gọi vào.

Ngoài private ra, còn có 2 kiểu quyền truy cập khác:

public: Yếu tố public có thể được truy cập từ bên ngoài đối tượng.

protected: Yếu tố protected không thể được truy cập từ bên ngoài đối tượng, nhưng có thể truy cập được từ các đối tượng thuộc class con của class hiện tại. Class con và sự thừa kế sẽ được đề cập kĩ hơn trong các bài viết sau.

Để có thể thiết lập quyền truy cập cho đối tượng, ta sử dụng các từ khóa private, public và protected đi kèm cùng dấu hai chấm :. Các yếu tố tiếp theo sau từ khóa sẽ được áp dụng quyền truy cập tương ứng, cho tới khi có một từ khóa mới xuất hiện.

Trong class ví dụ ở trên, void privateVoid() chỉ có thể được gọi từ bên trong đối tượng thuộc vào class Cat, void publicVoid() có thể gọi được từ bất kì đâu, còn void protectedVoid() chỉ có thể gọi từ bên trong đối tượng thuộc class Cat, hoặc các đối tượng thuộc vào class con của Cat.

Đây chính là encapsulation – tính đóng gói của lập trình hướng đối tượng. Với cách đặt quyền truy cập cho các yếu tố trong class, ta có thể giới hạn sử dụng của class tới những chức năng cần thiết đối với bên ngoài.

Tương tự đối với struct, ta cũng có thể viết hàm khởi tạo để khởi tạo các yếu tố của object thuộc class. Ví dụ:

Output

Hàm phá hủy (destructor) là một loại chương trình con đặc biệt khác, được gọi ra khi object bị phá hủy (ví dụ: khi chương trình kết thúc và bộ nhớ được giải phóng). Hàm phá hủy được định nghĩa theo cú pháp

Ví dụ như khi áp dụng vào class Cat ở trên:

Output

Ta có thể sử dụng destructor để dọn dẹp dữ liệu sau khi đối tượng bị phá hủy, lưu trữ thông tin quan trọng, vân vân…

Copy constructor là một loại hàm khởi tạo đặc biệt – nó được gọi ra khi một object của class được gán giá trị bằng một object khác (ví dụ như khi gán bằng nhau, khi đặt giá trị cho tham số của hàm, vân vân). Khi đó ta có thể sử dụng copy constuctor để can thiệp vào quá trình gán đó.

Một class thường không bắt buộc phải có copy constructor – trình dịch sẽ tự động xử lý việc gán nếu như không có, tuy nhiên các class có biến kiểu con trỏ và có khả năng cấp phát bộ nhớ động thì bắt buộc phải có copy constructor.

Cú pháp của copy constructor là

const là từ khóa hằng số – nó mang ý nghĩa rằng biến được khai báo sau nó là hằng số và sẽ không bao giờ bị thay đổi. Chú ý kiểu dữ liệu ở đây là truyền tham biến (toán tử &).

Ví dụ:

Output

Tất cả các object thuộc class đều có thể truy cập tới giá trị con trỏ bộ nhớ của mình thông qua từ khóa this. Ví dụ:

Hai giá trị được in ra sẽ khác nhau, do hai đối tượng được lưu ở hai vị trí bộ nhớ khác nhau.

Các thao tác đối với con trỏ bộ nhớ trên class cũng tương tự như với struct.

Giả sử bây giờ ta muốn đếm số lượng object Cat đã được sử dụng trong chương trình. Ta có thể sử dụng một biến global catNumber, và mỗi khi chạy hàm khởi tạo một object Cat thì ta tăng catNumber lên một. Tuy nhiên mỗi khi sử dụng class Cat, ta sẽ lại phải khai báo bên ngoài một biến catNumber, trong khi rõ ràng biến catNumber này vẫn luôn luôn gắn kèm về mặt ý nghĩa với class Cat. Điều này có thể sinh ra nhiều rắc rồi trong tương lai.

Giải phải là thay vì để catNumber là một biến global, ta sẽ khai báo catNumber thành một biến tĩnh – static – của class. Các yếu tố static hoàn toàn độc lập với các object của class – cho dù có bao nhiêu object thuộc class trong chương trình, các yếu tố static sẽ luôn luôn chỉ có một, và có thể truy cập thông qua toán tử :: (toán tử truy cập scope).

Các biến static sẽ được khởi tạo cùng với object đầu tiên được tạo ra của class. Nếu như chưa có object nào được tạo ra, nhưng ta vẫn muốn truy cập vào biến static, ta phải khai báo giá trị của biến static ở bên ngoài, sử dụng toán tử ::.

Tương tự, ta cũng có thể định nghĩa các chương trình con static độc lập với toàn bộ object của class bằng từ khóa static.

Ví dụ:

Output

Một ứng dụng quan trọng của các yếu tố static là Design Pattern Singleton – thiết kế chương trình đảm bảo chỉ có một object của class tồn tại trong suốt quá trình chạy của chương trình.

Giả sử ta có một class rất to và nặng, chỉ cần tạo ra một lần trong toàn bộ chương trình (ví dụ như database). Khi đó ta sẽ lưu một object của class đó dưới dạng static, và cho phép gán giá trị của object static này cho các đối tượng thông qua một hàm getInstance() thay vì phải khởi tạo lại từ đầu.

Phần sau: [C++ Cơ bản] Phần 23: Tính thừa kế – Class con (subclass)

Sự Khác Nhau Giữa Abstract Class Và Interface Trong Java

Ở những bài trước, chúng ta đã biết đến tính trừu tượng, và đi song song đó là abstract class và interface để triển khai tính trừu tượng trong java.

Chúng ta cùng xem thử nó sẽ khác nhau ở điểm nào qua bảng liệt kê sau

1

Abstract class chỉ có thể thừa kế một class hoặc một abstract class khác.

Interface có thể thừa kế một hoặc nhiều interface khác.

2

Abstract class có thể chứa abstract method và method thông thường(method có thân hàm).

Interface chỉ có abstract method.

3

Abstract class có thể chứa protected hoặc public abstract method.

Interface chỉ có public abstract method.

4

Abstract class có thể chứa static, final hoặc static final biến.

Interface chỉ có public static final biến.

Abstract class chỉ có thể thừa kế một class hoặc một abstract class khác public class Example1{ public void display1(){ System.out.println("method ex1"); } } public abstract class Example2 extends Example1{ abstract void display2(); } public class Example3 extends Example2{ public void display3(){ System.out.println("method ex3"); } } public class Main{ public static void main(String args[]){ Example3 obj=new Example3(); obj.display3(); } }

Output: method ex3

Interface có thể thừa kế một hoặc nhiều interface khác public interface Example1{ public void display1(); } public interface Example2 { public void display2(); } public interface Example3 extends Example1,Example2{} public class Example4 implements Example3{ public void display1(){ System.out.println("method ex1"); } public void display2(){ System.out.println("method ex2"); } } public class Main{ public static void main(String args[]){ Example4 obj=new Example4(); obj.display1(); obj.display2(); } }

Output:

method ex1

method ex2

Abstract class có thể chứa abstract method và method thông thường(method có thân hàm) public abstract class Example1 { abstract void display1(); public void display2(){ System.out.println("method" ex2); } } public class Example2 extends Example1{ public void display1(){ System.out.println("method ex1"); } } public class Main { public static void main(String args[]){ Example2 obj=new Example2(); obj.display1(); obj.display2(); } }

Output:

method ex1

method ex2

Interface chỉ có abstract method public interface Example1{ public abstract void display(); } public class Example2 implements Example1{ public void display(){ System.out.println("method dispaly="); } } public class Main{ public static void main(String args[]){ Example2 obj=new Example2(); obj.display(); } }

Output: display

Abstract class có thể chứa protected hoặc public abstract method public abstract class Example1{ protected abstract void display1(); public abstract void display2(); public abstract void display3(); } class Example2 extends Example1{ public void display1(){ System.out.println("method ex1"); } public void display2(){ System.out.println("method ex2"); } public void display3(){ System.out.println("method ex3"); } } public class Main{ public static void main(String args[]){ Example2 obj=new Example2(); obj.display1(); obj.display2(); obj.display3(); } }

Output:

method ex1

method ex2

method ex3

Interface chỉ có public abstract method public interface Example1{ void display1(); } public class Example2 implements Example1{ public void display1(){ System.out.println("method ex1"); } public void display2(){ System.out.println("method ex2"); } } public class Main{ public static void main(String args[]){ Example2 obj=new Example2(); obj.display1(); obj.display2(); } }

Output:

method ex1

method ex2

Abstract class có thể chứa static, final hoặc static final biến public abstract class Example1{ private int num_1 = 1; protected final int num_2 = 2; public static final int num_ 3 = 3; public void display1(){ System.out.println("Num1="+num_1); } } public Example2 extends Example1{ public void display2(){ System.out.println("Num2="+num_2); System.out.println("Num3="+num_3); } } public class Main{ public static void main(String args[]){ Example2 obj=new Example2(); obj.display1(); obj.display2(); } }

Output:

1

2

3

Interface chỉ có public static final biến public interface Example1{ int num_1=10; } public class Example2 implements Example1{ public void display1(){ System.out.println("Num1="+num_1); } } public class Main{ public static void main(String args[]){ Example2 obj=new Example2(); obj.display1(); } }

Output: 10

Note:

Interface thường được dùng để mô tả một tập các chức năng. Một class thừa kế một interface A, ta nói rằng class đó có thể thực hiện các năng của interface A khai báo, mà chưa cần xem code.

Ví dụ: Chúng ta có Mail là một interface và MailImpl implements Mail

public class MailImpl implements Mail

Chúng ta sẽ hiểu rằng class MailImpl sẽ có thể thực hiện được các chứng năng mà Mail khai báo.

Abstract class thường được dùng trong mối quan hệ thừa kế, vì tính linh hoạt của nó có thể chứa abstract method và method thông thường. Dựa vào đó mà chúng ta có thể định nghĩa các khuôn mẫu hay triển khai những thuộc tính, method mà các class con có thể dùng chung.