You are never a loser until you quit trying!

Hiển thị các bài đăng có nhãn Java. Hiển thị tất cả bài đăng
Hiển thị các bài đăng có nhãn Java. Hiển thị tất cả bài đăng

Lập trình hướng đối tượng trong JAVA - Java's Object Oriented Programming

Chào các bạn đến với phanlamcoder.blogspot.com !

Contents
  • Khái niệm cơ bản trong lập trình hướng đối tượng (OOP)
  • Tính chất của OOP
  • OOP trong Java
  • Những câu hỏi hay gặp về OOP  trong Java

lap-trinh-huong-doi-tuong-trong-java




Khái niệm cơ bản trong lập trình hướng đối tượng (OOP)


Quay trở lại thời kỳ trước khi khai sinh lập trình hướng đối tượng, các ngôn ngữ đã sử dụng lập trình hướng thủ tục : 
    Chương trình = Cấu trúc dữ liệu(CTDL) + Giải thuật(GT)

Nếu CTDL thay đổi thì GT cũng phải thay đổi theo, các bài toán được chia làm các function => khó xây dựng chương trình lớn, khó nâng cấp, khó tái sử dụng, ...

Vì vậy cần phải tìm ra mô hình/hướng lập trình mới để đáp ứng các nhu cầu trên, đó là lý do OOP ra đời.

OOP là một triết lý thiết kế, hay còn gọi là một mô hình trong lập trình. OOP được áp dụng trong hầu hết các ngôn ngữ lập trình như C++, Java, C#, PHP, JS,  ...

Khái niệm:
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, một số khái niệm cơ bản:

  • Đối tượng trong cụm từ "lập trình hướng đố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 bò, …
  • Class là một template (mẫu) thể hiện các đặc tính và hành vi của đối tượng.
  • Object là một thể hiện của class (class là tập hợp các object).

Để hiểu rõ hơn về Class và Object các bạn có thể tham khảo ví dụ sau:

Bạn muốn đem đối tượng "xe" vào chương trình của bạn?

Đầu tiên bạn phải biết xe có những thuộc tính gì (màu xe, tốc độ cao nhất, ...) và nó có thể thực hiện chức năng gì (chạy, hú còi, blabla...) 
Từ đó xây dựng một class Xe khai báo thuộc tính(properties) và chức năng(method) bên trong class. 
Sau đó ta sử dụng class Xe để tạo ra instances (các thể hiện của đối tượng - hay còn gọi là object :)) ) bằng toán tử "new" : 

Xe xe1 = new Xe("đỏ", 500); // tạo ra xe1 có màu đỏ, tốc độ cao nhất 500km/h

xe1.chay(); // xe1 thực hiện chức năng quay bánh

Xe xe2 = new Xe("xanh", 200); //tạo ra xe2 có màu xanh, tốc độ cao nhất 200km/h

xe2.chay(); // xe2 chạy

xe2.hucoi() //xe2 hú còi

Tổng quát như sau

ClassName objectName = new className(params);
// parameter(tham số) có thể có hoặc không, chúng ta sẽ tìm hiểu sau.

  Như vậy từ 1 class ta có thể tạo vô số các object, hay nói cách khác class là khuôn mẫu để tạo ra các object.

Tính chất của OOP

OOP có 4 tính chất quan trọng đó là:

  • Tính kế thừa (inheritance): một đối tượng có thể có được các thuộc tính hoặc hành vi của đối tượng khác.
  • Tính đa hình (polymorphism): một tác vụ có thể được thực hiện theo nhiều cách khác nhau.
  • Tính trừu tượng (abstraction): ẩn chi tiết bên trong và hiển thị tính năng.
  • Tính đóng gói (encapsulation): gắn kết code và dữ liệu cùng với nhau vào trong một đơn vị unit đơn.
Các khái niệm trên có thể hơi khó hiểu, nhưng đừng hoang mang, hãy xem phần tiếp theo để có thể hiểu rõ hơn về 4 tính chất này.

OOP trong Java

- Tính kế thừa: tính chất này thể hiện qua việc một class có thể kế thừa một class khác bằng từ khóa extends (trong java không có đa kế thừa), một class có thể triển khai nhiều interface bằng từ khóa implements.
- Tính đa hình: một method có thể được thực hiện theo nhiều cách khác nhau bằng các phương thức overriding(ghi đè) và overloading(nạp chồng).
- Tính trừu tượng: việc định nghĩa một method nhưng không khai báo cách triển khai thông qua từ khóa abstract.
- Tính đóng gói: client chỉ sử dụng method mà mình được phép sử dụng mà không quan tâm đến cách mà method đó triển khai, nội dung của tính chất này đc thể hiện qua các phương thức getter & setter và access modifier.

Các khái niệm, từ khóa quan trọng:
- Access modifier: dùng để giới hạn phạm vi truy cập của một thuộc tính, một method hoặc một class, nằm ở vị trí đầu tiên khi khai báo chúng. Nếu không chỉ rõ access modifier thì mặc định sẽ là Default.

oop-java-access-modifier
Class: lớp hiện tại, Package: lớp chung package với lớp hiện tại, Subclass: lớp con, Global: toàn cục

- Abstract: 
+ dùng để định nghĩa lớp hoặc method là abstract (thuần ảo) :
+ phương thức thuần ảo là phương thức không có khai báo cách triển khai (chỉ có vỏ, không có ruột :)) ).
+ lớp thuần ảo là lớp có thể chứa phương thức thuần ảo.
+ phương thức thuần ảo phải nằm trong một lớp thuần ảo, còn lớp thuần ảo có thể chứa hoặc không chứa phương thức thuần ảo.
+ chúng ta không thể tạo đối tượng bằng lớp thuần ảo.
- Interface: 
+ là một tập hợp các phương thức không được khai báo cách triển khai (giống như abstract method) và kết thúc bằng dấu chấm phẩy. (định nghĩa này còn được mở rộng trọng phiên bản java >7, các bạn có thể tìm hiểu ở bài học sau).
+ các class có thể implements interface và bắt buộc phải triển khai từng method trong nó.
+ trong interface có thể có thuộc tính nhưng đa phần thuộc tính đó đều là hằng số.
- Constructor: 
+ là phương thức đặc biệt có tên trùng với tên lớp và không có kiểu trả về.
+ phương thức khởi tạo đối tượng, khởi tạo các thuộc tính của đối tượng từ tham số bên ngoài hoặc tự khởi tạo mặc định.
- Overriding: lớp con ghi đè lên một phương thức của lớp cha hoặc của interface mà nó implements.
- Overloading: cho phép khai báo 2 hoặc nhiều phương thức cùng tên nhưng khác tham số truyền vào.
- Từ khóa quan trọng:
+ this: tham chiếu đến đối tượng của lớp hiện tại.
+ super: tham chiếu đến đối tượng lớp cha của lớp hiện tại.
+ static: chỉ định một thuộc tính, một method hay một khối lệnh là tĩnh, nghĩa là nó được khởi tạo/thực thi một lần duy nhất trong chương trình và được truy cập trực tiếp thông qua class mà không cần phải khởi tạo đối tượng. Mục đích để khai báo một tài nguyên dùng chung cho tất cả các đối tượng => giảm chi phí bộ nhớ.
+ final: dùng trong nhiều ngữ cảnh:
  •  thuộc tính: khi khai báo là hằng số (không thể thay đổi sau khi khai báo).
  •  method: khi không muốn method bị ghi đè.
  •  lớp: khi không muốn lớp bị kế thừa.

Truyền tham chiếu vào hàm trong Java??


Chào bạn đến với phanlamcoder.blogspot.com!

Kết quả hình ảnh cho tham chiếu java

 thì java không cho phép truyền tham chiếu. Vậy làm thế nào để thay đổi giá trị của một biến thông qua hàm?
Tuy Java chỉ cho phép truyền tham trị, nhưng đặc biệt, tham trị được truyền của kiểu dữ liệu object là địa chỉ mà object đó tham chiếu đến. Như vậy, ta có thể thay đổi giá trị của một biến thông thường bằng cách đặt nó trong kiểu dữ liệu object như sau:

class Obj
{
     int a;
     public void setA(int a)
     {
          this.a = a;
     }
     public int getA()
     {
          return a;
     }
}
public class Test {
public static void main(String[] args) {
    Obj = new Obj();
    a.setA(5);
    System.out.println("Before"+a.getA());  //a=5.
    Change(a);
    System.out.println("After: "+a.getA()); //a=0
}
static void Change(objA obj)
{
    Obj.setA(0);
    System.out.println("Change: "+Obj.getA()); //a=0
}
}
Chúc các bạn học tốt!
Góp ý tại mục bình luận bên dưới 💓

Tham trị (pass-by-value) và tham chiếu (pass-by-reference) trong Java




Chào bạn đến với phanlamcoder.blogspot.com!

Ở bài viết này chúng ta sẽ tìm hiểu về Tham trị (pass-by-value) và tham chiếu (pass-by-reference) trong Java


 pass by value java


Khi thao tác với các hàm trong Java, với những người mới bắt đầu sẽ thường lúng túng với việc truyền tham số vào cho các hàm. Tại sao một số trường hợp khi truyền tham số vào cho hàm xong khi thoát ra khỏi hàm giá trị của tham số lúc thì bị thay đổi theo logic của hàm, lúc thì không thay đổi gì? Vấn đề ở đây chính là sự khác nhau của các loại tham số được truyền vào hàm mà đôi lúc người lập trình không để ý đến. Các loại tham số này được chia làm 2 kiểu là truyền giá trị và truyền tham chiếu.
·         Truyền tham trị là gì? Truyền tham chiếu là gì?
Mình tạm áp dụng một cách nhớ có vẻ hơi thô thiển của mình để tránh nhầm lẫn trong trường hợp này: tham trị là cùng giá trị, tham chiếu là cùng chiếu đến một vùng nhớ.

1.      Truyền tham trị

 là truyền / copy giá trị của một biến (A) vào một biến khác (B) để sử dụng trong phạm vi của một hàm. Ở đây mình nói đến từ copy dùng để nhấn mạnh giá trị được truyền vào là một bản sao và lúc này (A) và (B) hoàn toàn độc lập nhau, việc dùng (B) để xử lý trong hàm hoàn toàn không ảnh hưởng gì đến biến ban đầu (A).

2.     Truyền tham chiếu

 là làm biến (B) thành một alias (bí danh) của (A), lúc này (A) gần như là (B) và (B) gần như là (A) vì cả 2 đều tham chiếu đến cùng một đối tượng, mọi thay đổi trên (B) thực tế cũng là thay đổi trên (A)  (việc tại sao lại nói (A) va (B) lúc này gần như nhau sẽ được giải thích rõ hơn ở phần dưới). Từ đó, sau khi thoát ra khỏi hàm, dữ liệu trên vùng nhớ được (A) tham chiếu tới sẽ bị thay đổi theo các thao tác mà ta đã dùng để thay đổi dữ liệu trên vùng nhớ được (B) tham chiếu tới.
·         Làm sao xác định đâu là tham chiếu, đâu là tham trị trong Java?
Sau một hồi giảng giải dài dòng ở trên, có thể bạn sẽ nói mình khùng khi mình phát biểu tiếp câu này:
Java chỉ truyền tham trị, không truyền tham chiếu.
Thêm một câu khẳng định lại:
Phát biểu trên luôn đúng và không có ngoại lệ!
Mình không khùng đâu, cái này từng là lầm tưởng của mình trong một thời gian dài và lầm tưởng này nó phổ biến đến mức có thể xếp vào hàng những lầm tưởng phổ biến nhất đối với các lập trình viên Java. Lầm tưởng đó thường được phát biểu như sau:Kiểu dữ liệu cơ sở được truyền theo tham trị, kiểu object được truyền theo tham chiếu.
Giải thích tiếp Java chỉ truyền tham trị, vậy nó truyền tham trị như thế nào trong trường hợp với kiểu dữ liệu cơ sở và kiểu object.
1.      Kiểu dữ liệu cơ sở: đối với kiểu dữ liệu cơ sở, Java đơn giản là copy giá trị của biến để gán vào tham số. Và như đã nói ở trên, lúc này biến và tham số sử dụng trong hàm là riêng biệt, khi thoát ra khỏi hàm biến không bị thay đổi giá trị.
2.     Kiểu object: khi truyền một biến có kiểu object vào một hàm thì lúc đó có nghĩa ta đã truyền giá trị của biến đó để sử dụng trong hàm, chứ không phải truyền đối tượng được biến đó tham chiếu tới. Vậy giá trị của một biến kiểu object là gì??? Nói có vẻ hơi lạ nhưng có thể nói giá trị của biến kiểu object là địa chỉ của object mà biến đó tham chiếu đến đến. Cho nên lúc này việc thay đổi giá trị của biến kiểu object này bằng cách gán cho một biến kiểu object khác thì object được tham chiếu đến lúc đầu không bị ảnh hưởng, chỉ khi sử dụng các method của chính các object được tham chiếu này thì dữ liệu của object mới được thay đổi sau khi ra khỏi hàm.
 Chúc các bạn học tốt!
Góp ý tại mục bình luận bên dưới 💓