Khái niệm Hướng đối tượng trong JAVA(OOP)
Hôm nay mình sẽ giới thiệu đến các bạn một trong những kiến thức cơ bản nhưng cũng rất quan trọng trong JAVA đó là Hướng đối tượng trong Java (OOP). Đâylà một trong những chìa khóa giúp chúng ta thành công cũng như học hỏi ngôn ngữ JAVA dễ dàng hơn (Và hầu như Các công ty về JAVA sẽ thường đặt ra các câu hỏi về Hướng đối tượng trong Java đối với các Fresher khi phỏng vấn).
Đầu tiên, Hướng đối tượng OOP trong Java được hình thành từ các khái niệm bao gồm (Bạn nên nắm vững những kiến thức này):
Tính đóng gói (encapsulation) và che giấu thông tin (information hiding): Tức là trạng thái của đối tượng được bảo vệ không cho các truy cập từ code bên ngoài như thay đổi trong thái hay nhìn trực tiếp.
Việc cho phép môi trường bên ngoài tác động lên các dữ liệu nội tại của một đối tượng theo cách nào là hoàn toàn tùy thuộc vào người viết mã. Đây là tính chất đảm bảo sự toàn vẹn, bảo mật của đối tượng Trong Java, tính đóng gói được thể hiện thông qua phạm vi truy cập (access modifier). Ngoài ra, các lớp liên quan đến nhau có thể được gom chung lại thành package
Tính kế thừa (inheritance): là khả năng cho phépta xây dựng một lớp mới dựa trên các định nghĩa của một lớp đã có. Lớp đã có gọi là lớp Cha, lớp mới phát sinh gọi là lớp Con và đương nhiên kế thừa tất cả các thành phần của lớp Cha, có thể chia sẻ hay mở rộng các đặc tính sẵn có mà không phải tiến hành định nghĩa lại.
Tính đa hình(polymorphism): Khi một tác vụ được thực hiện theo nhiều cách khác nhau được gọi là tính đa hình. Đối với tính chất này, nó được thể hiện rõ nhất qua việc gọi phương thức của đối tượng. Các phương thức hoàn toàn có thể giống nhau, nhưng việc xử lý luồng có thể khác nhau.
Nói cách khác: Tính đa hình cung cấp khả năng cho phép người lập trình gọi trước một phương thức của đối tượng, tuy chưa xác định đối tượng có phương thức muốn gọi hay không. Đến khi thực hiện (run-time), chương trình mới xác định được đối tượng và gọi phương thức tương ứng của đối tượng đó. Kết nối trễ giúp chương trình được uyển chuyển hơn, chỉ yêu cầu đối tượng cung cấp đúng phương thức cần thiết là đủ. Trong Java, chúng ta sử dụng nạp chồng phương thức (method overloading) và ghi đè phương thức (method overriding) để có tính đa hình.
Nạp chồng (Overloading): Đây là khả năng cho phép một lớp có nhiều thuộc tính, phương thức cùng tên nhưng với các tham số khác nhau về loại cũng như về số lượng. Khi được gọi, dựa vào tham số truyền vào, phương thức tương ứng sẽ được thực hiện.
Ghi đè (Overriding): là hai phương thức cùng tên, cùng tham số, cùng kiểu trả về nhưng thằng con viết lại và dùng theo cách của nó, và xuất hiện ở lớp cha và tiếp tục xuất hiện ở lớp con. Khi dùng override, lúc thực thi, nếu lớp Con không có phương thức riêng, phương thức của lớp Cha sẽ được gọi, ngược lại nếu có, phương thức của lớp Con được gọi.
Tính trừu tượng (abstraction): Tính trừu tượng là một tiến trình ẩn các chi tiết trình triển khai và chỉ hiển thị tính năng tới người dùng. Tính trừu tượng cho phép bạn loại bỏ tính chất phức tạp của đối tượng bằng cách chỉ đưa ra các thuộc tính và phương thức cần thiết của đối tượng trong lập trình. Tính trừu tượng giúp bạn tập trung vào những cốt lõi cần thiết của đối tượng thay vì quan tâm đến cách nó thực hiện. Trong Java, chúng là sử dụng abstract class và abstract interface để có tính trừu tượng.
Lợi Ích của lập trình hướng đối tượng trong JAVA
Vì mục đích của các khái niệm OOP trong Java là để tiết kiệm thời gian mà không làm mất tính bảo mật và dễ sử dụng, nên các thực tiễn tốt nhất đều hướng đến việc thúc đẩy mục tiêu chính đó.
Lợi thế của OOP khi so với ngôn ngữ lập trình hướng thủ tục (procedure-oriented) – Không Hướng đối tượng:
- OOP giúp việc thiết kế, phát triển và bảo trì dễ dàng hơn trong khi với lập trình hướng thủ tục thì việc quản lý code là khá khó khăn nếu lượng code tăng lên. Điều này làm tăng hiệu quả có quá trình phát triển phần mềm.
- OOP cung cấp Data Hiding (ẩn dữ liệu) trong khi đó trong hướng thủ tục một dữ liệu toàn cục có thể được truy cập từ bất cứ đâu.
- OOP cung cấp cho bạn khả năng để mô phỏng các sự kiện trong thế giới thực một cách hiệu quả hơn. Chúng ta có thể cung cấp giải pháp cho các vấn đề trong thế giới thực nếu chúng ta sử dụng Lập trình hướng đối tượng.
Ví Dụ:
Đầu tiên, để có thể hiểu được các ví dụ phía dưới thì bạn cần phải hiểu rõ khái niệm về Object. Object (đối tượng) nghĩa là một thực thể trong thế giới thực, chẳng hạn như bàn, quả bóng, con mèo, …
Lập trình hướng đối tượng là một phương pháp để thiết kế một chương trình bởi sử dụng các lớp và các đối tượng. Nó làm đơn giản hóa việc duy trì và phát triển phần mềm bằng việc cung cấp một số khái niệm: Đối tượng: Một thực thể có trạng thái và hành vi. Ví dụ như xe đạp, bàn, ghế, … Nó có thể mang tính vật lý hoặc logic. Lớp: Một tập hợp các đối tượng. Nó là một thực thể logic.
Tiếp theo mình sẽ thực hiện các hướng dẫn cụ thể để các có thể hiểu rõ hơn về Hướng đối Tượng Trong JAVA (OOP):
Tạo ra các lớp sau:
Animal.java
package sinhvientot.net.java.oop;
public abstract class Animal {
//Đây là một hàm ảo(Trừu tượng)
//nên chúng ta chỉ khai báo tên hàm và kiểu dữ liệu trả về.
public abstract void sayHello();
}
- Từ khóa “package” để thể hiện tính đóng gói của Hướng đối tượng trong java. Vì thế mỗi Lớp(Class) trong java sẽ đều được đóng gói trong một package. Từ khóa “public” cũng dùng để thể hiện tính đóng gói và độ bảo mật của JAVA.
- Ví Dụ: Ở class Animal ta có hàm “sayHello()” ở trước hàm này chúng ta khai báo từ khóa “public” thì các lớp Khác không cùng package “sinhvientot.net.java.oop” vẫn có thể gọi đến hàm này để sử dụng.
- Hàm “sayHello()” được khai báo từ khóa “abstract” thì có thể hiểu hàm này là một hàm trừu tượng thì chúng ta sẽ chỉ khai báo tên hàm và input không thực hiện viết nội tại hàm.
Cat.java
package sinhvientot.net.java.oop;
public class Cat extends Animal{
private String name;
private int age;
private String type;
private String sex;
//Constructor
public Cat() {
}
//Constructor được custom
public Cat(String name, int age, String type, String sex) {
this.name = name;
this.age = age;
this.type = type;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public void sayHello() {
// TODO Auto-generated method stub
System.out.println("Cat say: Hello! I'm" + name + ".I'm a" + type + ".");
}
}
- Lớp này sẽ mô tả đối tượng là con mèo bao gồm: Tên, tuổi, loại, giới tính.
- Tướng ứng với các biến trong Lớp trên ví dụ “private String name” biến này được khai báo từ khóa “private” để đảm bảo rằng các biến này sẽ chỉ được sử dụng trong Lớp đó(ở đây là Cat) và các lớp khác(Không thuộc class Cat) phải truy suất thông qua các phương thức getter và setter ví dụ:
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
- Thì lúc này biến “name” sẽ chỉ được sử dụng trong Lớp Cat còn các Lớp khác phải truy xuất thông qua 2 hàm đã được chúng ta “public” bao gồm:
- “getName()” : lấy ra giá trị của biến “name”.
- “setName(String name)” : set Giá trị chobiến “name”.
- Tiếp theo ở đầu class Cat ta thấy nó sử dụng từ khóa “extends” để thực hiện kế thừa từ class Animal thì lúc này. Phương thức “sayHello()” sẽ được tạo ra ở class Cat cùng từ khóa “@Override”(Ghi đè – và tính đahình). Chúng ta sẽ thực thi phương thức này ở class Cat.
- Constructor trong Java là một kiểu phương thức đặc biệt mà được sử dụng để khởi tạo đối tượng. Constructor được triệu hồi tại thời gian tạo đối tượng. Nó xây dựng giá trị, cung cấp dữ liệu cho đối tượng, đó là lý do nó được gọi là Constructor. Có hai loại Constructor: Loại thứ nhất là Constructor mặc định, loại này không có tham số. Và loại thứ hai là Constructor được tham số hóa.
Ghi Chú: Nếu không có Constructor nào được xác định trong một lớp, thì Compiler tự động tạo một Constructor mặc định.
Tương tự như trên chúng ta tiếp tục tạo ra Class Dog
Dog.java
package sinhvientot.net.java.oop;
public class Dog extends Animal{
private String name;
private int age;
private String type;
private String sex;
public Dog() {
super();
}
public Dog(String name, int age, String type, String sex) {
super();
this.name = name;
this.age = age;
this.type = type;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Dog [name=" + name + ", age=" + age + ", type=" + type + ", sex=" + sex + "]";
}
@Override
public void sayHello() {
// TODO Auto-generated method stub
System.out.println("Dog say: Hello! I'm" + this.name + ".I'm a" + this.type + ".");
}
}
Zoo.java
package sinhvientot.net.java.oop;
import java.util.ArrayList;
import java.util.List;
public class Zoo {
private List animals = new ArrayList();
public void add(Animal animal) {
this.animals.add(animal);
}
public void remove(Animal animal) {
this.animals.remove(animal);
}
public void showListAnimal() {
for(Animal animal : this.animals){
animal.sayHello();
}
}
}
Main.java (Test)
package sinhvientot.net.java.oop;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Cat cat = new Cat();
Dog dog = new Dog();
cat.setName("Tom");
cat.setType("Mèo Mun");
dog.setName("Ken");
dog.setType("Husky");
Zoo zoo = new Zoo();
zoo.add(cat);
zoo.add(dog);
zoo.showListAnimal();
}
}
Kết quả test:
Như vậy các tính chất của lập trình hướng đối tượng đươc sử dụng thông qua ví dụ trên:
- Tạo abstract class Animal có phương thức sayHello. abstract class này thể hiện tính trừu tượng, có nghĩa ta định ra rằng dù là con vật gì đi nữa thì nó cũng có phương thức sayHello.
- Tạo 2 lớp Cat và Dog kế thừa từ Animal. Khi khởi tạo chúng sẽ có tên. Chúng override lại phương thức sayHello để chào hỏi theo cách riêng của chúng. Điều này thể hiện tính đóng gói (đóng gói biến tên và phương thức sayHello với nhau) và tính thừa kế (Cat và Dog mang đặc điểm chung là có sayHello từ Animal).
- Tạo lớp Zoo để quản lí nhiều Animal, có (1) phương thức add, remove để thêm, bớt các Animal (các đối tượng của các lớp thừa kế từ Animal), (2) phương thức showListAnimal để gọi sayHello của tất cả đối tượng nó quản lí. Điều này thể hiện tính đa hình, Zoo gọi chỉ gọi một phương thức sayHello, nhưng tùy con vật mà lời chào hỏi sẽ khác nhau.
Chúc các Bạn Thành Công!
Đây là link projectExample các bạn có thể Import ở đây: https://github.com/nguyentrungthaoit/JAVA-Basics/tree/master/OOP-Example