ÔN JAVALẬP TRÌNH HƯỚNG ĐỐI TƯỢNG 0 JAVA CÓ PHẢI NGÔN NGỮ THUẦN HƯỚNG ĐỐI TƯỢNG KHÔNG. Bất cứ một ngôn ngữ lập trình nào nếu muốn được xem là một ngôn ngữ lập trình thuần hướng đối tượng nó phải thỏa mãn.
Trang 1ÔN JAVA/LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG
0 JAVA KHÔNG PHẢI NGÔN NGỮ THUẦN HƯỚNG ĐỐI TƯỢNG
Bất cứ một ngôn ngữ lập trình nào nếu muốn được xem là một ngôn ngữ lập trình thuần hướng đối tượng nó phải thỏa mãn các điều kiện sau:
1 Nó phải hỗ trợ được 4 đặc điểm của phương pháp lập trình hướng đối tượng đó là:
o Tính đóng gói dữ liệu (Encapsulation)
o Tính kế thừa (Inheritance)
o Tính trừu tượng (Abstraction)
o Tính đa hình (Polymorphism)
2 Những kiểu dữ liệu cơ bản được định nghĩa sẵn như int, string, float,
phải ở dạng đối tượng.
3 Những kiểu dữ liệu được người dùng định nghĩa cũng phải ở dạng đối tượng.
4 Những toán tử thực thi trên đối tượng phải ở dạng các phương thức.
Vậy ngôn ngữ lập trình Java vi phạm hai điều kiện (2) và (4).
Vi phạm điều kiện (2): Java hỗ trợ bạn khai báo các kiểu dữ liệu định nghĩa sẵn dưới dạng int, byte, long, v.v mà trong lập trình hướng đối tượng các kiểu dữ liệu này phải được đóng gói lại thành các đối tượng
như Integer, String, v.v, mặc dù Java cũng hỗ trợ đóng gói các kiểu dữ liệu được định nghĩa sẵn này nhưng đó chỉ là lớp ngoài, thực chất nó vẫn dưới dạng kiểu dữ liệu cơ bản.
Vi phạm điều kiện (4): Java có thể sử dụng toán tử để thực hiện một phép tính nào đó giữa hai đối tượng như String s = "123" + "ABC", điều này vi phạm nguyên tắc thực thi trên đối tượng phải ở dạng các phương thức của phương pháp lập trình hướng đối tượng.
1 LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VỚI JAVA
1.0 Lập trình HĐT là gì?
Lập trình HĐT là 1 phương pháp lập trình dựa trên khái niệm về lớp và đối tượng OOP tập trung vào các đối tượng hơn là chức năng hoặc logic chương trình
Đối tượng trong OOP bao gồm 2 thành phần chính:
Thuộc tính (Attribute): là những thông tin, đặc điểm của đối tượng Biểu diện trạng thái (state) của đối tượng.
Trang 2 Phương thức (Method): là những hành vi mà đối tượng có thể thực hiện.
Là các chức năng được định nghĩa bên trong lớp mô tả hành vi của đối tượng.
Fields với Properties khác nhau điểm gì:
Fields và Properties đều đại diện cho dữ liệu trong một class trong lập trình hướng đối tượng, nhưng chúng có một số điểm khác nhau như sau:
1 Fields là các biến thông thường, trong khi Properties là các phương thức đặc biệt được sử dụng
để truy cập và thay đổi giá trị của các biến trong class
2 Fields được truy cập trực tiếp thông qua tên biến, trong khi Properties được truy cập thông qua các phương thức getter và setter
3 Khi sử dụng Properties, chúng ta có thể kiểm soát cách các giá trị của dữ liệu được truy cập và thay đổi Ví dụ, ta có thể kiểm tra tính hợp lệ của giá trị trước khi cho phép giá trị mới được đặt
4 Khi sử dụng Properties, chúng ta có thể thêm các logic bổ sung, ví dụ như tính toán hoặc kiểm tra dữ liệu, trong các phương thức getter và setter
5 Properties thường được đặt tên theo quy tắc PascalCase, trong khi Fields thường được đặt tên theo quy tắc camelCase
6 Khi sử dụng IDE để tạo class, Properties thường được tạo ra tự động để tránh sử dụng các biến công khai quá nhiều
Tóm lại, Fields và Properties đều đại diện cho dữ liệu trong một class, nhưng Properties cho phép ta kiểm soát và bổ sung thêm các logic vào quá trình truy cập và thay đổi dữ liệu
Phân biệt lớp và đối tượng:
- Lớp là 1 bản thiết kế hoặc khuôn mẫu để tạo ra các đối tượng cụ thể Những đối tượng có đặc tính tương tự nhau sẽ được tập hợp lại thành 1 lớp Đối tượng thì chiếm bộ nhớ, lớp thì không
- Đối tượng được tạo ra từ lớp, 1 lớp có nhiều đối tượng Ví dụ Chó là 1 lớp, còn Chó Phú Quốc, chó Husky là các đối tượng
Lợi ích của lập trình HĐT:
- Tái sử dụng code
- Code dễ bảo trì (sửa đổi)
- Bảo mật (do đóng gói)
- Dễ mở rộng dự án
1.1 Tính đóng gói (Encapsulation)
Trang 3Đóng gói là cơ chế gói dữ liệu (attribute) và các hoạt động (method) thực hiện trên dữ liệu đó lại với nhau thành một thể thống nhất (class)
Các thuộc tính (hay biến) của class bị ẩn khỏi các lớp khác, và chỉ có thể được truy cập thông qua các phương thức của lớp đó
Để đạt được sự đóng gói trong java, ta cần:
- Khai báo các thuộc tính của class là private
- Cung cấp các phương thức public setter và getter cho việc sửa đổi và xem giá trị của các thuộc tính Lợi ích của đóng gói:
- Giấu thông tin bên trong của đối tượng để bên ngoài không thể nhìn thấy Để ngăn ngừa việc gán giá trị không hợp lệ vào dữ liệu của đối tượng Ví dụ đối tượng Student có thuộc tính gpa Thuộc tính này chỉ cho phép giá trị từ 0 – 4 Nếu gpa được truy cập trực tiếp, nó có thể được gán giá trị là -4 chẳng hạn Do
đó người ta sẽ đặt thuộc tính gpa là private và cung cấp một public method sau để gán giá trị cho gpa public void setGpa(double gpa){
if(gpa >=0 && gpa <= 4){
this.gpa = gpa;
}
else{
System.out.println(“Gpa is invalid.”);
}
}
- Giúp code dễ bảo trì: Việc thay đổi, cập nhật bên trong 1 lớp không ảnh hưởng đến các lớp khác, các phần khác của chương trình Điều này giúp giảm công sức và tiết kiệm thời gian cho các nhà phát triển Các access modifier:
- private: thuộc tính và phương thức khai báo private chỉ có thể được truy cập trong chính lớp mà khai báo thuộc tính và phương thức đó
- protected: thuộc tính và phương thức chỉ được truy cập bởi chính lớp đó hoặc subclass của lớp đó
- public: thuộc tính và phương thức có thể được truy cập bởi bất kỳ lớp nào khác
1.2 Tính kế thừa
Trang 4Tính kế thừa trong lập trình HĐT là thừa hưởng lại thuộc tính và phương thức của một lớp Khi một số lớp thường có các đặc điểm chung, vd: HocSinh, GiaoVien; Meo, Cho;… ta gom các đặc điểm chung này vào một lớp gọi là lớp cha (super class hoặc base class) và cho các lớp con (derived class hoặc subclass)
kế thừa lớp cha Các lớp con sẽ có các thuộc tính (nếu để protected hoặc public) và phương thức của lớp cha, ngoài ra có thêm các thuộc tính và phương thức của riêng nó
Có thể có đơn kế thừa hoặc đa kế thừa (C++ có đa kế thừa nhưng Java chỉ chấp nhận đơn kế thừa) Lợi ích của kế thừa:
- Giúp tái sử dụng code (code không bị lặp lại)
- Giảm chi phí bảo trì: Chỉ cần sửa đổi lớp cha, các lớp con đều được cập nhật
- Giảm thiểu code dư thừa và tăng khả năng mở rộng của chương trình
1.3 Tính đa hình (Polymorphism)
Đa hình được hiểu là cùng một vật nhưng trong nhiều hình thức (form) khác nhau Để hình dung bạn có thể liên tưởng đến việc một người đa nhân cách, tùy từng thời điểm mà người đó trở thành một người khác
Trong Java có 2 loại đa hình:
- static: loại này cho phép trình biên dịch (compiler) nhận ra phương thức nào đang được gọi Loại này còn được gọi là nạp chồng phương thức (method overloading) Các phương thức trong cùng 1 lớp có cùng 1 tên nhưng có số lượng tham số khác nhau hoặc kiểu dữ liệu của tham số khác nhau
- dynamic: loại đa hình hình này không cho phép trình biên dịch (compiler) xác định phương thức nào sẽ được thực thi như loại static mà phương thức thực thi sẽ được xác định trong thời gian chạy (runtime) bởi máy ảo JVM Loại này còn được gọi là ghi đè phương thức (override) Các lớp con cùng override phương thức của lớp cha (các phương thức có cùng tên, cùng tham số) nhưng cài đặt bên trong mỗi phương thức của mỗi lớp con là khác nhau Khi đó ta có thể sử dụng lớp cha để tham chiếu đến lớp con
Ví dụ: Lớp cha Animal có 2 lớp con là Cat và Dog Phương thức được override là sound() Khi đó code như sau:
Animal animal = new Dog();
animal.sound();
animal = new Cat();
animal.sound();
-KQ:
Trang 5Meo meo
Gâu gâu
Khi nào dùng đa hình: khi ta chưa thực sự biết ta cần sử dụng đối tượng nào (tùy thuộc vào điều kiện), khi đó ta có thể sử dụng đối tượng lớp cha để tham chiếu đến đối tượng lớp con Tùy thuộc vào điều kiện mà lớp cha sẽ được tham chiếu đến lớp con nào đó (lớp cha như 1 người đa nhân cách)
1.4 Tính trừu tượng (Abstraction)
Tính trừu tượng là một tính chất mà chỉ tập trung vào những tính năng (method) chính của đối tượng và
ẩn đi những thông tin không cần thiết, ẩn đi cách cài đặt chi tiết những tính năng này Người dùng (developer) chỉ cần biết chức năng và cách sử dụng của method mà không cần biết cài đặt chi tiết bên trong như thế nào (Định nghĩa này là chuẩn, không cần thắc mắc)
Tính trừu tượng cũng được thể hiện trong đời sống (Các ví dụ này cũng chuẩn luôn)
- Bạn khởi động ô tô bằng cách vặn chìa khóa và bấm nút khởi động là có thể khởi động và chạy xe mà không cần biết động cơ bên trong hoạt động như thế nào Giúp giảm sự phức tạp cho người dùng
- Bạn muốn rút tiền từ cây ATM, bạn chỉ cần bỏ thẻ vào và nhấn nút sẽ rút được tiền mà không cần biết cách hoạt động bên trong của cây ATM
Để cài đặt abstraction (hay nói cách khác để đạt được sự trừu tượng), trong Java có 2 cách:
- Sử dụng abstract class: Để tạo abstract class phải sử dụng từ khóa “abstract” Khai báo các phương thức abstract (cũng cần từ khóa abstract), các phương thức này chỉ có phần khai báo, không có phần thân Các lớp extends abstract class sẽ phải cài đặt cụ thể các phương thức abstract Không thể tạo đối tượng cho abstract class mà chỉ có thể tạo đối tượng con của nó
- Sử dụng interface: Abstract class chưa phải là trừu tượng hoàn toàn vì nó vẫn có thể có thuộc tính và các phương thức thông thường Nhưng dùng interface thì là trừu tượng hoàn toàn Trong interface chỉ được phép khai báo hằng số và khai báo phương thức Các lớp kế thừa interface sẽ phải cài đặt cụ thể các phương thức này Một lớp có thể kế thừa (implements) nhiều interface
Lợi ích của abstraction trong lập trình HĐT là nó làm giảm sự phức tạp trong code Lập trình viên chỉ cần biết các giao diện và cách sử dụng là có thể sử dụng, không cần biết sự cài đặt phức tạp bên trong Lợi ích nữa của abstraction là khi một số phương thức của lớp cha bắt buộc phải được override lại tại lớp con Ví dụ lớp cha là lớp NhanVien có 2 phương thức là getLoaiNhanVien() và tinhLuong() Có 2 lớp con kế thừa lớp NhanVien là NhanVienFullTime và NhanVienPartTime Trường hợp NhanVien là lớp bình thường, developer có thể quên mà không override lại hai phương thức getLoaiNhanVien() và
tinhLuong() -> dẫn đến kết quả sai Trường hợp để NhanVien là lớp abstract và 2 phương thức
getLoaiNhanVien() và tinhLuong() là phương thức abstract thì 2 lớp con bắt buộc phải override lại 2 phương thức đó nếu không trình biên dịch sẽ báo lỗi
Trang 6Phân biệt abstract class và 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 (hằng số).
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.
Abstract class có constructors Interface không có constructor
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%).
1.5 Lớp và đối tượng
1.6 Mối quan hệ giữa các đối tượng
//cái gì cũng có mục đích của nó cả -> hiểu về mục đích của chúng
2 JAVA CƠ BẢN
2.1 Ngôn ngữ Java
- Java là 1 ngôn ngữ lập trình hướng đối tượng (OOP) được phát triển bởi Sun Microsystem do James
Gosling khởi xướng và phát hành vào năm 1995
Trang 7- Tất cả các chương trình muốn thực thi được phải được biên dịch ra mã máy Mã máy của từng kiến trúc CPU là khác nhau, ví dụ: mã máy của CPU Intel, CPU Solarix, CPU macintosh,… là khác nhau Vì vậy trước đây một chương trình chạy được trên windows muốn chạy được trên HĐH khác chẳng hạn như LINUX thì phải chỉnh sửa và biên dịch lại Nhưng khi Java ra đời, nhờ vào máy ảo Java mà khó khăn đó đã được khắc phục Một chương trình viết bằng java sẽ được java compiler biên dịch thành mã bytecode (chính là các file đuôi class) Sau đó máy ảo java (JVM) sẽ chuyển bytecode thành mã máy tương ứng với hệ điều hành Nhờ đó chương trình java chỉ cần biên dịch 1 lần và có thể chạy trên nhiều nền tảng khác nhau, chỉ cần máy tính đó có cài máy ảo java
Về bản chất JVM chạy được trên nền tảng nào thì chương trình java sẽ chạy được trên nền tảng đó Nói java đa nền tảng thực chất nó được hỗ trợ JVM trên nhiều nền tảng
- JVM: máy ảo java, chuyển bytecode thành mã máy
- JDK: JDK (Java Development Kit- Bộ công cụ phát triển Java) là một bộ công cụ để phát triển các ứng dụng Java
JDK = JRE + Compiler + Debuger + Javadocs + …
Có 3 gói JDK:
+ Java SE (Java Standard Editon)
Còn được gọi là Java Core, đây là phiên bản chuẩn và cơ bản của Java, được dùng làm nền tảng cho các phiên bản khác.
Chứa các API chung (như java.lang, java.util ) và nhiều các API đặc biệt khác.
Bao gồm tất cả các tính năng, đặc trưng cơ bản của ngôn ngữ Java như biến, kiểu dữ liệu nguyên thủy, Arrays, Streams, Strings, Java Database Connectivity (JDBC)…
Tính năng nổi tiếng nhất của Java là JVM cũng chỉ được xây dựng cho phiên bản này.
Java SE được sử dụng với mục đích chính là để để tạo các ứng dụng cho môi trường Desktop.
+ Java ME (Java Micro Edition)
Đây là phiên bản được sử dụng cho việc tạo các ứng dụng chạy trên các hệ thống nhúng như thiết bị mobile và các thiết bị nhỏ.
Các thiết bị sử dụng Java ME thường có các hạn chế như giới hạn về khả năng xử lý, giới hạn về nguồn điện (pin), màn hình hiển thị nhỏ…
Trang 8 Java ME còn hỗ trợ trong việc sử dụng công nghệ nén web, giúp giảm dụng lượng sử dụng (network usage) và cải thiện khả năng truy cập internet giá rẻ.
Java ME sử dụng nhiều thư viện và API của Java SE và nhiều thư viện, API của riêng nó.
+ Java EE (Java Enterprise Edition)
Đây là phiên bản Enterprise của Java, được sử dụng để phát triển các ứng dụng web.
Java EE chứa các Enterprise APIs như JMS, EJB, JSPs/Servlets, JNDI
Java EE sử dụng nhiều thành phần của Java SE và có thêm nhiều tính năng của riêng nó như Servlet, JavaBeans…
Java EE sử dụng HTML, CSS, JavaScript… để tạo trang web và web service.
Nhiều ngôn ngữ khác cũng được dùng để phát triển ứng dụng web giống như Java EE (.Net, PHP ) nhưng Java EE được sử dụng nhiều bởi tính năng hoạt, khả năng bảo mật, khả chuyển…
Khi bạn tải Java EE hoặc Java ME, trong đó sẽ có luôn Java SE.
- JRE: JRE ( Java Runtime Environment) là gói phần mềm cung cấp các thư viện lớp Java, cùng với Máy ảo Java (JVM), và các thành phần khác để chạy các ứng dụng được viết bằng ngôn ngữ lập trình Java
JRE = JVM + Class libraries
- Mối quan hệ giữa JDK, JRE, JVM:
Trang 92.2 Generic
Thuật ngữ “generics” được hiểu là tham số hóa kiểu dữ liệu Việc tham số hóa kiểu dữ liệu giúp cho lập
trình viên có thể dễ bắt lỗi các kiểu dữ liệu không hợp lệ, đồng thời giúp dễ dàng hơn cho việc tạo và sử dụng các class, interface, method với nhiều kiểu dữ liệu khác nhau
Ta thường thấy Generic trong ArrayList Ví dụ: ArrayList<String> list = new ArrayList<>();
T: đại diện cho 1 wrapper class của kiểu dữ liệu nào đó Trong ví dụ trên T là String
Ta cũng có thể tạo class, interface, method sử dụng generic để có thể thao tác trên nhiều kiểu dữ liệu khác nhau
- Tạo class với generic
class Dictionary<K, V> {
private K key;
private V value;
public Dictionary(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
}
Trang 10Trong đó K, V là viết tắt của Key, Value đại diện cho một class nào đó.
- Tạo interface với generic
interface writer< T > {
void update ( T obj);
void delete ( T obj);
void write ( T obj);
}
T: đại diện cho 1 class nào đó
- Tạo phương thức với generic
public static < E > E getFirstElement ( ArrayList < E > arr) {
if (arr isEmpty ())
return null;
E first = arr get ( 0 );
return first;
}
E: đại diện cho phần tử trong collection, E có thể là 1 class nào đó
* Generic còn được thể hiện qua dấu ? Dấu ? đại diện cho một class nào đó
2.4 Collections
Collections framework của Java cung cấp các cấu trúc dữ liệu cho việc lưu trữ và tổ chức dữ liệu