oop in java - ver1.1

238
Giảng viên: Vũ Duy Linh Email: [email protected] LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG JAVA Object-Oriented Programming in Java Version 1.1

Upload: vdlinh08

Post on 29-Jun-2015

1.265 views

Category:

Technology


10 download

DESCRIPTION

Lập trình Hướng đối tượng Java (Object-Oriented Programming in Java) Biên soạn bởi: Vũ Duy Linh

TRANSCRIPT

Page 1: OOP in Java -  Ver1.1

Giảng viên: Vũ Duy Linh Email: [email protected]

LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG JAVA Object-Oriented Programming in Java

Version 1.1

Page 2: OOP in Java -  Ver1.1

Chương 1. Tổng quan về ngôn ngữ

lập trình Java

Giảng viên: Vũ Duy Linh Email: [email protected]

Page 3: OOP in Java -  Ver1.1

3

© Vũ Duy Linh Java – Giới thiệu

Là ngôn ngữ lập trình mới, được phát triển bởi Sun

Microsystems vào năm 1991.

Phiên bản đầu tiên gọi là Oak do James Gosling phát triển.

Năm 1995 tên chính thức được gọi là Java

Một số Nhà phát triển Java: James Gosling, Arthur Van, Karl

Jacob và một số nhân vật nổi bật khác

Page 4: OOP in Java -  Ver1.1

4

© Vũ Duy Linh Tổng quan về Java SE 7

Java SE Development Kit (JDK) 7 và Java SE Runtime Environment (JRE) 7:

Page 5: OOP in Java -  Ver1.1

5

© Vũ Duy Linh Môi trường JRE

JRE: là môi trường đòi hỏi cần có để chạy các ứng dụng (Applet, stand alone) được viết bằng ngôn ngữ Java: Giao diện lập trình ứng dụng

Java API (Application Programming Interface)

Máy tính ảo Java (Java Virtual Machine): Sẽ tạo ra một môi trường để thực thi các lệnh bằng cách nạp các file.class, quản lý bộ nhớ và dọn rác,…

Mã nguồn

Page 6: OOP in Java -  Ver1.1

6

© Vũ Duy Linh Sơ đồ thực thi chương trình

Với Java, mọi hệ điều hành là một!

Tập tin mã nguồn .java Mã trung gian - Byte code Mã máy - Machine code Mã nhị phân -Binary code

Page 7: OOP in Java -  Ver1.1

7

© Vũ Duy Linh Cấu trúc thư mục chương trình

Byte code files

Source code files

Page 8: OOP in Java -  Ver1.1

8

© Vũ Duy Linh Sự khác biệt giữa 2 loại kiến trúc mã

Kiến trúc phụ thuộc (Architecture dependent): SưCSử dụng

kiến trúc mã không trung gian. Các ngôn ngữ như: C/C++, Pascal.

Page 9: OOP in Java -  Ver1.1

9

© Vũ Duy Linh Sự khác biệt giữa 2 loại kiến trúc mã

Kiến trúc độc lập (Architecture independent): Sử dụng kiến trúc mã

trung gian mà ngôn ngữ Java đã tạo nên một cuộc cách mạng mới: Write

once, run anywhere.

/* Giống nhau với mọi platform */

/* Khác nhau trên mỗi flatform */

Page 10: OOP in Java -  Ver1.1

10

© Vũ Duy Linh Các đặc tính Java (1)

Thân thiện, đơn giản và nhỏ gọn (Familiar, simple, small)

Được biên dịch (Compiled) và được thông dịch (Interpreted)

An toàn, bảo mật (Secure): Kiểm tra an toàn trước từng bước (ngôn ngữ biên dịch thực thi: tính đóng gói .java .class class loader machine code) Từ bên ngoài không thể xâm nhập vào chương trình được.

Kiến trúc mã trung gian (Architecture neutral ): Sinh mã bytecode -

Độc lập với hệ điều hành và có thể chạy ở mọi hệ điều hành

(platform).

Khả chuyển (Portable): JVM dựa trên nền tảng chính POSIX

(Portable Operating System Interface [for Unix]) – Giao diện hệ điều

hành linh động: cung cấp mã nguồn di động cho các thiết bị đầu cuối,

ngoại vi.

Page 11: OOP in Java -  Ver1.1

11

© Vũ Duy Linh Các đặc tính Java (2)

Hướng đối tượng (Object-oriented)

Hiệu suất cao (High performance): Có cơ chế hỗ trợ trình thông dịch

chạy ở tốc độ tối đa, cơ chế dọn rác (garbage) tự động,…

Mạnh mẽ (Robust): Định kiểu mạnh, tường minh

Phân tán (Distribution): Hỗ trợ TCP, UDP, Socket và Network

communication: Applets, servlets, aglets – hệ thống mobile agents,

remote method invocation (RMI), Common Object Request Broker

Architecture (CORBA) .

Đa tuyến đoạn (Multithreads)

Tính động (Dynamic): Ở thời điểm run-time, các file.class được liên

kết khi cần.

Page 12: OOP in Java -  Ver1.1

12

© Vũ Duy Linh Một số khác biệt với C++

Không có Typedefs, Defines, hoặc Preprocessor

Không có biến toàn cục: "Global variables are bad"

Không hỗ trợ lệnh Goto

Không có con trỏ số học (pointer arithmetic): Trong Java, hầu hết sự phức tạp và rắc rối cố hữu liên quan đến con trỏ đều được bỏ đi nhằm tạo ra một ngôn ngữ trong sáng, giản đơn.

Không hỗ trợ các cấu trúc không an toàn: Java không có kiểu struct.

Không có đa thừa kế (Multiple inheritance)

Không có nạp chồng toán tử (Operator overloading)

Không có ép kiểu tự động (Automatic coercions)

Page 13: OOP in Java -  Ver1.1

13

© Vũ Duy Linh Phạm vi ứng dụng Java

JAVA

Mobile

Console GUI

Network

Web Database

RMI

Applet

Cloud

Page 14: OOP in Java -  Ver1.1

14

© Vũ Duy Linh Các loại chương trình của Java

Có thể phát triển 2 loại chương trình Java: Các chương trình chạy độc lập (Stand-alone

applications): Có chứa phương thức “main” và có thể chạy từ dòng lệnh thông qua trình thông dịch Java.

Các chương trình Web (Web applications/ applets): Không chứa phương thức “main” và là chương trình được nhúng vào trang web và được chạy khi trang web được duyệt.

Page 15: OOP in Java -  Ver1.1

15

© Vũ Duy Linh Java Development Kit

javac: Trình biên dịch java

java: Trình thông dịch java: Chạy ứng dụng độc lập

jdb : Gỡ rối (Java Debugger)

appletviewer : Chạy ứng dụng applets

javap - to print the Java bytecodes

javaprof - Java profiler

javadoc - documentation generator

javah - creates C header files

Page 16: OOP in Java -  Ver1.1

16

© Vũ Duy Linh Ứng dụng Standalone

Java source: Hello_StandAloneApp.java

public class Hello_StandAloneApp { public static void main(String args[]) {

System.out.println("Hello! Stand alone application.");

}

}

Biên dịch và thực thi: javac Hello_StandAloneApp.java ↲

(Tạo file: Hello_StandAloneApp.class)

java Hello_StandAloneApp ↲ (Kết quả: Hello! Stand alone application.)

Page 17: OOP in Java -  Ver1.1

17

© Vũ Duy Linh Ứng dụng applet

Java source: Hello_AppletApp.java

import java.applet.Applet;

import java.awt.*;

public class Hello_AppletApp extends Applet {

public void paint(Graphics g) {

g.drawString ("Hello! Applet application.", 25, 25);

}

} Tạo trang web: Hello_AppletApp.html <HTML>

<TITLE> JAVA APPLET APPLICATION</TITLE>

<APPLET CODE="Hello_AppletApp.class” width=250 height=100>

</APPLET>

</HTML>

Page 18: OOP in Java -  Ver1.1

18

© Vũ Duy Linh Duyệt trang web

Duyệt trang web bằng trình duyệt FireFox, IE,… Address: [path] Hello_AppletApp.html

Page 19: OOP in Java -  Ver1.1

19

© Vũ Duy Linh Cài đặt môi trường phát triển ứng dụng Java

Gồm 2 bước:

1. Cài bộ JDK (Java Development Kit): Bộ công

cụ phát triển Java, bao gồm cả môi trường JRE

(Java Runtime Environment) vào hệ thống máy

tính để chạy Java applications và Applets.

2. Các phần mềm hỗ trợ source code:

a. Đơn giản: NotePad, WordPad, EditPlus,…

b. Chuyên nghiệp: NetBeans IDE, Eclipse IDE,

JDeveloper IDE, JCreator IDE.

Page 20: OOP in Java -  Ver1.1

20

© Vũ Duy Linh Số liệu thống kê

Lịch sử 2004-2013:

Page 21: OOP in Java -  Ver1.1

21

© Vũ Duy Linh Số liệu thống kê (3)

Hiện tại năm 2014:

Page 22: OOP in Java -  Ver1.1

22

© Vũ Duy Linh Số liệu thống kê (2)

Ngôn ngữ kịch bản (Client-side scripting):

Page 23: OOP in Java -  Ver1.1

Chương 2. Kiểu dữ liệu và cấu trúc

lệnh điều khiển

Giảng viên: Vũ Duy Linh Email: [email protected]

Page 24: OOP in Java -  Ver1.1

24

Cấu trúc chương trình Java đơn giản

1 //ProgramName.java

2 //Phần document

3 package packagename;

4 import packagename.ClassName;

5 public class ProgramName{

6 // Khai báo các biến

7 . . .

8 // Định nghĩa các phương thức

9 . . .

10 //Định nghĩa phương thức main.

11 public static main(String args[]){

12 // Phần thân phương thức main

13 } // Kết thúc main method.

14 } // Kết thúc lớp ProgramName

Phần mô tả chương trình

Câu lệnh package

Các câu lệnh import

Định nghĩa các Interface

Định nghĩa các class

Phương thức main của class{

}

Ở phần cơ bản này, chúng ta sử dụng phương pháp lập trình dựa

trên đối tượng Object-Based Programming (OBP) để minh hoạ:

Page 25: OOP in Java -  Ver1.1

25

© Vũ Duy Linh Chương trình Java cơ bản

1. /* Author: Vũ Duy Linh

2. Topic: A very simple stand-alone application in java

3. File name: HelloWorld.java

4. */

5. import java.lang.*;

6. public class HelloWorld {

7. public static void main( String args[ ] ) {

8. System.out.println( “Hello world!..." );

9. }

10. }

import: Từ khóa khai báo sử dụng gói (package) cần có trong chương trình

class: Từ khóa khai báo lớp

public, static: Access modifiers – các bổ từ truy cập

void: Kiểu giá trị trả về của phương thức

args[ ]: Các đối số nhập từ dòng lệnh

Page 26: OOP in Java -  Ver1.1

26

© Vũ Duy Linh Biên dịch và thực thi

Biên dịch

javac HelloWorld.java

Out file: HelloWorld.class

Thực thi

java HelloWorld

Kết quả: Hello world!...

Page 27: OOP in Java -  Ver1.1

27

© Vũ Duy Linh Một số lưu ý thêm (1)

Gói java.lang.* được import một cách mặc định nên lệnh

System.out.println(); chính là java.lang. System.out.println();

Tên đầy đủ - Fully qualified name

Page 28: OOP in Java -  Ver1.1

28

© Vũ Duy Linh Một số lưu ý thêm (2)

Cách sử dụng đối số từ dòng lệnh:

Gõ lệnh: java FullName_App Vu Duy Thuc

Các đối số: args[0] = Vu, args[1] = Duy, args[2] = Thuc

Từ khoá public: Phạm vi truy cập mọi nơi.

Phương thức static: là phương thức chỉ được phép truy cập tới các

biến static của lớp (do đã được fix sẵn bộ nhớ) và có thể gọi mà

không cần khởi tạo đối tượng của lớp chứa nó.

Từ khoá void: Phương thức không trả về (return;) giá trị nào cả.

Page 29: OOP in Java -  Ver1.1

29

© Vũ Duy Linh Tính căn bậc 2

// CanBac2.java

import java.lang.Math;

public class CanBac2 {

public static void main(String args []) {

double x = 4; //Giả sử x > 0

double y;

y = Math.sqrt(x);

System.out.println(“Can bac 2 cua " + x + "= " + y);

}

}

Page 30: OOP in Java -  Ver1.1

30

© Vũ Duy Linh Kiểu dữ liệu nguyên thủy

Kiểu Kích

thước

Khoảng giá trị

boolean 8 bit true hoặc false

byte 8 bit -128 đến 127

short 16 bit -32,768 đến 32,767

int 32 bit -2,147,483,648 đến +2,147,483,647

long 64 bit -9,223,372,036,854,775,808 đến

+9,223,372,036,854,775,807

char 16 bit \u0000 đến \uFFFF (chuẩn unicode)

float 32 bit -3.40292347E+38 đến +3.40292347E+38

double 64 bit -1.79769313486231570E+308 đến

+1.79769313486231570E+308

Kiểu nguyên thuỷ (Primitive data type): là

kiểu mà các phép toán được dịch trực tiếp

sang các lệnh của máy (operational data).

Page 31: OOP in Java -  Ver1.1

31

© Vũ Duy Linh Biến

Biến (Variable): Theo định nghĩa của Khoa học máy tính, biến gồm một số ô nhớ được định danh (duy nhất) bởi một định danh, đó chính là tên biến. Đây là cách thức thường xuyên được dùng trong lập trình, dùng để chứa một giá trị nào đó có thể thay đổi trong quá trình thực thi chương trình.

Quy tắc đặt tên biến

Bắt đầu bằng chữ cái, dấu gạch dưới (_) hoặc dấu dollard ($), không

có khoảng trắng giữa tên, không trùng với các từ khoá,… Lưu ý:

Java phân biệt chữ hoa chữ thường.

Ví dụ:

• Tên biến đúng: myList1, double_X1, luongCoBan,…

• Tên biến sai: my List1, 2nghiem, luong-Co-Ban,…

Cách khai báo và khởi tạo:

Cách 1: kiểu_nguyên_thuỷ tên_Biến;

tên_Biến = giá_trị;

Cách 2: kiểu_nguyên_thuỷ tên_Biến = giá_trị;

Page 32: OOP in Java -  Ver1.1

32

© Vũ Duy Linh Kiểu dữ liệu nguyên thủy (2)

Mỗi biến được khai báo chỉ tồn tại trong phạm vi (scope) của nó – tương tự

như ngôn ngữ C đã học.

Các ví dụ: Khai báo (tên) biến a kiểu (nguyên thuỷ) int, gán giá trị của biến a bằng 40

int a; a = 40;

a: tên biến, kiểu là int, và giá trị của a là 40.

double diemThi =9.5; //biến số thực diemThi bằng 9.5

int octVal = 032; int hexVal = 0x1a; char characterC = 'C';

unicodeC='\u1EE9'; (Java sử dụng UTF-16)

String hoTen = "Ch\u00e0o b\u00e9: V\u0169\u0020Duy\u0020Th\u1EE9c!"

0

a

40

a

Page 33: OOP in Java -  Ver1.1

33

© Vũ Duy Linh Cấp phát trên bộ nhớ

Cho đoạn lệnh Java:

int a = 10; int b;

b = a; a += 10;

Page 34: OOP in Java -  Ver1.1

34

© Vũ Duy Linh Hằng

Hằng (Constant): cũng tương tự như biến ngoại trừ nó giữ một giá trị cố định (hay được gọi là các biến chỉ đọc)

Chúng được khai báo bởi từ khóa final

final int SI_SO = 100;

final double PI = 3.1428;

Kiểu chữ in hoa thường được dùng để đặt tên cho các hằng.

Page 35: OOP in Java -  Ver1.1

35

© Vũ Duy Linh Hằng (2)

Ví dụ hằng:

public class DienTichHinhTron {

public static void main(String args[]) {

final double PI = 3.1428;

double bk = 5.5; // ban kinh

double dt; // dien tich

dt = PI * bk * bk

System.out.println("Ban kinh= "+ bk + ", dien tich= " + dt);

}

}

Page 36: OOP in Java -  Ver1.1

36

© Vũ Duy Linh Lệnh rẽ nhánh - if

Có 3 dạng: if (boolean_expression) { statement(s); }

if (boolean_expression) { statement(s); } else { statement(s); }

if (boolean_expression_1) { statement(s); } else if (boolean_expression_2){ statement(s); } else { statement(s); }

Kết quả: 7 <= 8

Ví dụ:

Với: boolean_expression: Là biểu thức lô-git đúng/sai,

statement: Biểu thức tính/câu lệnh

Page 37: OOP in Java -  Ver1.1

37

© Vũ Duy Linh Lệnh rẽ nhánh - switch

Cú pháp Swich:

switch (evaluated_expression) { case constant_expression_1: statements_1; … case constant_expression_n: statements_n; default: default_statements;

}

Biểu thức phân nhánh (evaluated_expression): có kiểu rời rạc như

int, char, hoặc enum.

Có kết hợp với các lệnh continue; hoặc break;

Page 38: OOP in Java -  Ver1.1

38

© Vũ Duy Linh switch (2)

Kết quả: Gia tri bien c KHONG la 'a' hoac 'b' ma la 'V'

Ví dụ:

Page 39: OOP in Java -  Ver1.1

39

© Vũ Duy Linh Lệnh lặp For và For-each

Cú pháp For:

for (initialization; boolean-expression; step){ statement(s);

}

Với Initialization: Khởi tạo biến chạy, boolean-expression: điều kiện dừng, step: bước nhảy tăng hoặc giảm

Ví dụ:

Kết quả: 1 3 5 7 9

Cú pháp For-each: for (type vaiable : collection){

statement(s);

}

hoặc for (type vaiable: array) {

statement(s);

}

Page 40: OOP in Java -  Ver1.1

40

© Vũ Duy Linh

Cú pháp:

while (boolean_expression) {

statement(s)

}

Sẽ lặp cho đến khi điều kiện trở thành false

Lệnh lặp While

Kết quả: 1 3 5 7 9

Page 41: OOP in Java -  Ver1.1

41

© Vũ Duy Linh Lệnh lặp Do while

Cú pháp:

do {

statement(s)

} while (boolean_expression);

Kết quả: 1 3 5 7 9

Page 42: OOP in Java -  Ver1.1

42

© Vũ Duy Linh

Cú pháp:

Access_modifiers return_type tênPhươngThức( [Các_tham_số]){ [Local_declaration(s);]

Statement(s);

}

Local declaration(s): Biến/hằng được khai báo bên trong phương thức là cục bộ và chỉ được hiểu trong phương thức chứa nó.

Access_modifiers: Các bổ từ truy cập

Return_type: Kiểu dữ liệu của kết quả trả về.

• void: Không trả về giá trị nào cả (return; )

• Chỉ có thể trả về tối đa giá trị của một kiểu dữ liệu.

Ví dụ: phương thức tính diện tích hình tròn có 1 tham số hình thức.

protected double tinhDienTich(double r){

return (Math.PI*Math.pow(r,2);

}

Phương thức

Page 43: OOP in Java -  Ver1.1

43

© Vũ Duy Linh Ví dụ

Giải phương trình bậc 2 theo OBP, gồm 2 lớp: PTB2 và LopChinh

Page 44: OOP in Java -  Ver1.1

44

© Vũ Duy Linh Ví dụ (2)

Page 45: OOP in Java -  Ver1.1

Chương 3. Khái niệm về thiết kế

hướng đối tượng

Giảng viên: Vũ Duy Linh Email: [email protected]

Page 46: OOP in Java -  Ver1.1

46

© Vũ Duy Linh Các mẫu hình lập trình

Mẫu hình lập trình tuần tự (Imperative paradigm)

Mẫu hình lập trình mô tả (Declarative paradigm)

Lập trình hàm (Functional programming)

Lập trình logic (Logic programming )

Mẫu hình lập trình hướng đối tượng (Object-oriented paradigm)

Mẫu hình lập trình hướng định dạng/khía cạnh (Aspect-oriented

paradigm)

Page 47: OOP in Java -  Ver1.1

47

© Vũ Duy Linh Mô hình lập trình tuần tự

Phục vụ cho thời kỳ đầu máy tính và ngôn ngữ asembler

Cách làm tuần tự từng bước (step-by-step) để cụ thể hóa bài toán được làm như thế nào (how to get sth)

Các biến được đại diện trong bộ nhớ

Sử dụng lệnh gán để thay đổi trị biến

Các ngôn ngữ tiêu biểu: Algol, Pascal, C, Ada

procedure Fibo(n: integer);

var a, b, kq: integer;

begin

a := 0; b:=1;kq:=0;

while (kq < n) do

begin

kq := q + b; write(kq:4);

a = b; b = kq;

end;

end;

Page 48: OOP in Java -  Ver1.1

48

© Vũ Duy Linh

Declarative programming: Để miêu tả bài toán cần giải quyết được định nghĩa như thế nào.

Nó dựa trên cách lập trình định nghĩa hàm (definition-based functional programming): Lập trình hàm (Functional programing)

Lập trình logic (Logic programing)

Lập trình hàm: Ước lượng các hàm toán học

Không làm thay đổi dữ liệu

Chương trình chính là một tập các hàm

Các ngôn ngữ tiêu biểu: Lisp, Refal, Perl, Planer,…

Lập trình logic: Xác định kết suy diễn của bài toán là thành công hay thất bại

Dựa vào một tập các phép logic được định nghĩa: các sự kiện/tiên đề, các luật logic

Các nguyên lý hợp nhất (Unification), nguyên lý giải (Resolution)

Ngôn ngữ tiêu biểu: Prolog

(+ x y) x + y

Mô hình lập trình mô tả

Page 49: OOP in Java -  Ver1.1

49

© Vũ Duy Linh Mô hình lập trình mô tả (2)

Ngôn ngữ LISP

(max 3 10 -10 15 7) 15

(defun factorial (N)

"Compute the factorial of N."

(if (<= N 1)

1

(* N (factorial (- N 1)))))

Bài toán n! được định nghĩa là:

“bằng 1 nếu n <=1 ngược lại bằng n*(n-1)!

Bài toán n! được định nghĩa theo cú pháp Prolog.

Ngôn ngữ Prolog

mortal(X) :- human(X).

human(socrate).

?- mortal(socrate).

Yes, Sorate is mortal.

fac(0,1).

fac(N,F) :- N>0,

M is N-1,

fac(M, Fm),

F is N * Fm.

Page 50: OOP in Java -  Ver1.1

50

© Vũ Duy Linh Mô hình lập trình hướng đối tượng

Dựa trên nền tảng đối tượng (Object)

Chương trình bao gồm nhiều tập quần thể đối tượng khác nhau, mỗi quần thể đối tượng thuộc vào một loài/ loại/ lớp (Class) riêng biệt.

Sự thực thi chương trình là sự trao đổi thông điệp (messages) giữa các đối tượng với nhau.

thuần OOP: Mọi thứ là đối tượng ngay cả các kiểu nguyên thủy (primitives)

Ngôn ngữ thuần OOP: Smalltalk, Eiffel.

1 lớp Xe

4 chiếc xe

4 đối tượng

thuộc lớp Xe

Page 51: OOP in Java -  Ver1.1

51

© Vũ Duy Linh Kết hợp các mô hình

Ngôn ngữ lập trình hiện đại thường có sự kết

hợp giữa các mô hình:

Imperative + OO Paradigms: C++, Java, Object

Pascal, Ada

Fuctional + OO Paradigms: Clos (Common Lisp

Object System)

Logic + OO Paradigms: Object Prolog

Page 52: OOP in Java -  Ver1.1

52

© Vũ Duy Linh Quá trình phát triển chương trình HĐT

1. Đặc tả bài toán 2. Phân rã bài

toán 3. Phân tích các thực thể tồn

tại trong bài toán (Trừu tượng hoá)

4. Viết mã lệnh Java 5. Kiểm thử

6. Chỉnh sửa lại.

1

2

3

4

5

6

Page 53: OOP in Java -  Ver1.1

53

© Vũ Duy Linh Sự ánh xạ thế giới thực vào OOP

- Được hực hiện thông qua

sự trừu tượng hóa.

- Sự trừu tượng hóa: là

quá trình xác định các thuộc

tính và các hành động liên

quan đến mỗi thực thể trong

môi trường ứng dụng đang

được phát triển (có nhiều

đối tượng thuộc các loại

khác nhau).

Page 54: OOP in Java -  Ver1.1

54

© Vũ Duy Linh Sự trừu tượng hóa - Abstraction

Trừu tượng dữ liệu ( Data abstraction): là các đặc tính (properties) của kiểu dữ liệu

và sự cài đặt cụ thể nó Định nghĩa kiểu dữ liệu (thực thể) ở mức trừu tượng interface

và cài đặt nó ở mức cụ thể.

Phép tính a = (1+2) * 5 được

thức hiện như thế nào trên

máy tính, dễ hay khó?

Abstract

properties

Sự trừu tượng hoá điều khiển ( Control abstraction): Là sự trừu tượng các thao tác/

phép toán ở mức thấp. Các ngôn ngữ lập trình đã làm sẵn việc này, giúp giảm bớt công

sức của lập trình viên.

Rất đơn giản nếu sử dụng NNLT

bậc cao, “mệt” nếu sử dụng ngôn

ngữ máy (Machine language)

Tính toán, xử lý ntn để

có kết quả a = 15?

Page 55: OOP in Java -  Ver1.1

55

© Vũ Duy Linh Sự trừu tượng hóa - Abstraction

Class (kiểu dữ liệu thực thể): Là sự kết hợp của data abstraction + Control abstraction

Page 56: OOP in Java -  Ver1.1

56

© Vũ Duy Linh Các đặc tính Java hướng đối tượng

Java OOP Paradigm

Encapsulation

Multiple Inheritance

Delegation

Concurrency

Polymorphism

Single Inheritance

Abstraction

Persistence

Genericity

Page 57: OOP in Java -  Ver1.1

57

© Vũ Duy Linh Sự đóng gói - Encapsulation

Sự đóng gói: Là việc cài đặt mã lệnh cho các phương thức nội tại và cách

thức truy xuất các thuộc tính của lớp thành một đơn vị duy nhất Cung cấp

một cơ chế bảo vệ dữ liệu (đối tượng): che dấu và bảo vệ dữ liệu khỏi người

dùng (can thiệp hoặc thao tác sai mục đích).

Outside code: Phần nhìn

thấy cho người dùng

Inside code: Phần che

khuất khỏi người dùng

Page 58: OOP in Java -  Ver1.1

58

© Vũ Duy Linh Sự trừu tượng - Abstraction

OOP sử dụng cả data và control abstraction.

Abstraction Class: tập các thuộc tính và thao tác (phương thức).

Lớp GiangVien: có 3 thuộc tính và 2 phương thức.

3 Attributes

2 Operations

V V

Page 59: OOP in Java -  Ver1.1

59

© Vũ Duy Linh Thừa kế- Inheritance

Thừa kế (Inheritance): Là một cơ chế cho phép lập trình viên định nghĩa một lớp con mới (Child/ sub/ derived class) bằng cách mở rộng từ (các) lớp cha (Parent/ super/ base class) đã tồn tại. Đây là đặc tính nổ bật nhất của OOP và là một cuộc cách mạng của lĩnh vực công nghệ phần mềm.

Lớp con thừa hưởng các đặc điểm (properties = attribute + operations) từ lớp cha trong phạm vi truy xuất được phép.

Quá trình phân tích tìm các lớp con dẫn xuất từ lớp cha được gọi là chuyên biệt hoá (Specialization).

Parent

Child

Phần chung: - Được kế thừa - Có thể reused vì không cài đặt lại

Page 60: OOP in Java -  Ver1.1

60

© Vũ Duy Linh Thừa kế

Chuyên biệt hoá là quá trình phân lớp quần thể các đối tượng chung của lớp cha ra thành những lớp quần thể con nhỏ hơn (có chung đặc tính) của các lớp con khác nhau phương pháp lập trình top-down.

Mối liên kết giữa lớp con và lớp cha là mối liên kết Là-Một (Is-A) của lớp cha.

c

à

n

g

tổng quát (trừu tượng)

chuyên biệt (cụ thể)

Ex: Nguoi Is-A DongVatCoVu: “Người là một loài động vật có vú”,…

Page 61: OOP in Java -  Ver1.1

61

© Vũ Duy Linh Các loại thừa kế lớp trong Java

Các dạng thừa kế trong lập trình hướng đối tượng Java là:

Thừa kế đơn (Single inheritance): Một con một cha

Thừa kế phân cấp (Hierarchical inheritance): Nhiều con một cha

Thừa kế đa cấp (Multi-level inheritance): Là dạng Thừa kế Hierarchical nhưng cho phép nhiều cấp (như: chắtkj cháuji coni cha)

Hierarchical

inheritance

Single

inheritance Multi-level

inheritance

Page 62: OOP in Java -  Ver1.1

62

© Vũ Duy Linh Các loại thừa kế lớp ngoài Java

Thừa kế bội (Multiple inheritance): Một con thừa kế từ nhiều cha. VD: C++

Thừa kế lai (Hybrid inheritance): Là sự kết hợp 2 trong 4 cách trên

Thừa kế đa lối (Multi-path inheritance): Giống như dạng Hybird nhưng được dẫn xuất cùng một lớp cha (base class).

Q & A

Page 63: OOP in Java -  Ver1.1

63

© Vũ Duy Linh Tính đa hình

Đa hình (Polymorphism): Là khả năng đảm nhận nhiều dạng - Một hoạt động (thông

qua phương thức) được đối tượng thực hiện bằng nhiều cách khác nhau, và các đối

tượng khác loại cùng thực hiện chung một ứng xử theo cách riêng của mình.

Giúp cho chương trình trở nên tổng quát hơn chứ không đơn điệu cá biệt

Có 2 hình thức đa hình:

1. Đa hình tĩnh (Static polymorphism):

được thực hiện thông qua phương pháp

nạp chồng (overloading) ở thời điểm

biên dịch chương trình (early binding)

Đa hình phương thức.

Biên dịch thành byte-code vì biết rõ

phương thức nào sẽ được thực thi

2. Đa hình động (Dynamic polymorphism):

được thực hiện thông qua phương pháp

ghi chồng (overriding) ở thời điểm thực

thi chương trình (late binding) Đa

hình đối tượng.

Chỉ xác định được phương thức

nào được thực hiện ở thời điểm

thực thi

Page 64: OOP in Java -  Ver1.1

64

© Vũ Duy Linh Tính bền vững

Tính bền vững (Persistence): Mục đích lưu giữ sự tồn tại của đối tượng lâu hơn sự thực thi của chương trình.

Với Native Java persistence bằng tuần tự hoá:

Bằng cách ghi đối tượng vào nơi an toàn (không bị xung đột) rồi sau đó đọc ra để sử dụng lại các thư viện hỗ trợ: java.io.FileInputStream; java.io.FileOutputStream; java.io.ObjectInputStream; java.io.ObjectOutputStream; Cơ chế để đảm bảo sự bền vững là sự tuần tự hóa (serialization) - java.io.Serializable;: Nó chuyển đổi dữ liệu (đối tượng) vào luồng (byte stream) và ghi nó vào tập tin (CSDL, bộ nhớ) để lưu trữ - sử dụng phương thức writeObject(). Chương trình sẽ được java bean khôi phục lại bằng cơ chế deserialization để có được trạng thái ban đầu của đối tượng - sử dụng phương thức readObject().

Page 65: OOP in Java -  Ver1.1

65

© Vũ Duy Linh Tính bền vững CSDL trong Java - Persistence database

Với các framework hỗ trợ persistence: JPO/OpenJPA, TopLink, EclipseLink, Hibernate,…

và với JPA trong Java EE, và Java Data Objects (JDO API) của Cộng đồng Java (Java Community Process):

Page 66: OOP in Java -  Ver1.1

66

© Vũ Duy Linh Đồng bộ hóa, sự ủy quyền

Đồng bộ hóa (Concurrency): Là cơ chế cho phép thực hiện

nhiều chức năng/công việc tại một thời điểm. VD như hệ điều

hành đa nhiệm - Java thực hiện thông qua cơ chế tiến trình

(processes) và tuyến đoạn (threads) và tuần tự hoá

(synchronization). Java API là gói java.util.concurrent;

Sự ủy quyền (Delegation): Cho phép một phương thức

method_A của lớp A thực hiện một nhiệm vụ thông qua một

phương thức method_B ở lớp B.

Point

xCoord yCoord

getXCoord() getYCoord()

Circle

centre

getCentreX() getCentreY()

Phương thức getCenterX()

của đối tượng lớp Circle

thực hiện tính xCord của

tâm hình tròn thông qua

phương thức getXCoord

thuộc đối tượng lớp Point

Page 67: OOP in Java -  Ver1.1

67

© Vũ Duy Linh Kỹ thuật tổng quát

Kỹ thuật Generic: Cho phép sự trừu tượng hóa các phần tử dữ liệu

mà không cụ thể chính xác kiểu của chúng. Các kiểu tổng quát

(chưa biết) này chỉ được xác định ở thời điểm sử dụng chúng.

E là tham số hình thức có kiểu tổng

quát ở thời điểm định nghĩa.

Khi sử dụng List<Integer> thì E được

thay thế bằng kiểu của đối số thực (là

Integer)

Page 68: OOP in Java -  Ver1.1

68

© Vũ Duy Linh Lợi ích của OOP

Sự tin cậy cao hơn: Phân các dự án phần mềm phức tạp

thành các mô đun các đối tượng nhỏ hơn (Package)

Khả năng bảo trì phần mềm: Với các gói nhỏ (mô-đun) sẽ

giúp dễ phát hiện lỗi và sửa lỗi hơn

Năng suất cao hơn thông qua tính sử dụng lại (Reused)

Inheritance: Làm giảm bớt sự dư thừa mã lệnh, mở rộng việc

sử dụng các class đang tồn tại

Encapsulation: Giúp cho xây dựng chương trình an toàn

hơn.

OOP dễ dàng ánh xạ các đối tượng trong miền xác định của

bài toán tới các đối tượng trong chương trình

Những hệ thống hướng đối tượng có thể được nâng cấp từ

hệ thống nhỏ sang lớn dễ dàng.

Page 69: OOP in Java -  Ver1.1

Chương 4. Lớp, đối tượng và gói

Class, Object, Package

Giảng viên: Vũ Duy Linh Email: [email protected]

Page 70: OOP in Java -  Ver1.1

70

© Vũ Duy Linh Khái niệm

Lớp (Class): đại diện cho một mẫu các đối tượng có chung những đặc điểm giống nhau, bao gồm các thuộc tính (attributes) và các hành vi (operations) của nó.

Trên sơ đồ, lớp có 03 phần: ClassName, Field(s), Method(s) như sau:

Ví dụ: Lớp Sinh viên, lớp Giảng viên, lớp Động vật có vú,…

Lớp Giảng viên, ta quan tâm đến 03 đặc điểm là: Mã số, họ tên, chuyên ngành, và 02 hoạt động là: dạy học và nghiên cứu khoa học.

Dữ liệu thành viên (trường và phương thức) được phân ra 2 nhóm: Thành viên thể hiện (Instance members): Là các biến thể hiện và các phương

thức thể hiện. Đây là phần dữ liệu dành riêng cho mỗi đối tượng được tạo ra Với cách này, địa chỉ của mỗi đối tượng được lưu trong vùng nhớ là khác nhau.

Thành viên lớp (Class/static members): Là các biến lớp (static variables) và phương thức lớp (static methods). Đây là phần dữ liệu dành riêng cho lớp và được truy xuất trực tiếp bởi tên lớp Với cách này, các đối tượng được tạo ra từ lớp này sẽ có chung địa chỉ của biến lớp biến chung cho các đối tượng.

Tên lớp

Các trường

Các phương thức

4 biến thể hiện

(instance variables)

1 biến lớp (static variable)

2 phương thức thể hiện

(instance methods)

Page 71: OOP in Java -  Ver1.1

71

© Vũ Duy Linh Khái niệm (2)

Đối tượng (Object): Là một thể hiện, instance, của một lớp là một biến thuộc kiểu dữ liệu lớp.

Đối tượng thì có trạng thái (states), còn lớp thì không. Trạng thái chính là giá trị riêng của mỗi đối tượng và được lưu vào trong các biến thể hiện.

Hệ thống hướng đối tượng là một tập các đối tượng tương tác với nhau.

Các phương thức là tập các lệnh tuần tự dùng để thao tác trên các trường.

Lớp GiangVien Hai đối tượng: gv1, gv2 thuộc lớp GiangVien

Page 72: OOP in Java -  Ver1.1

72

© Vũ Duy Linh Các loại lớp

Lớp chuẩn Java (Standard class): Là các lớp đã được xây dựng sẵn (thư viện Java - Java API). Lớp tổ tiên trong Java là:

java.lang.Object;

Lớp tự định nghĩa (Programmer-define class): Là các lớp được lập trình viên tự định nghĩa ra thông qua việc trừu hóa các lớp đối tượng trong môi trường bài toán.

Các lớp này được gọi chung là kiểu dữ liệu tham chiếu/ đối tượng (Reference/ Object data types)

Page 73: OOP in Java -  Ver1.1

73

© Vũ Duy Linh Lớp chuẩn

Các thư viện chuẩn: java.lang.*, java.awt.*, java.util.*

Ví dụ: Lấy căn hai của 25 ta sử dụng lệnh

Nạp thư viện vào: import java.lang.*

Gọi phương thức: double ketQua = Math.sqrt(25);

Page 74: OOP in Java -  Ver1.1

74

© Vũ Duy Linh Lớp tự định nghĩa

Cú pháp tổng quát:

Khai báo biến trường trong lớp (member variables):

[Modifier] data-type fieldName;

Khai báo phương thức trong lớp (member methods):

// hoặc Members

Page 75: OOP in Java -  Ver1.1

75

© Vũ Duy Linh Lớp tự định nghĩa (2)

[Modifier] class TênLớp { //Modifier ở mức lớp

[Modifier] data_type tênTrường_1; //Modifier ở thành viên

...

[Modifier] data_type tênTrường_n;

[Modifier] return_type tênPhươngThức_1([Các_Tham_số]) {

//…

return (giá trị trả về);

}

...

[Modifier] return_type tênPhươngThức_m([Các_Tham_số]) {

//…

return (giá trị trả về);

}

}

* Chú ý: Các thành phần tùy chọn (trong cặp [ ]) sẽ được đề cập sau.

Cú pháp chi tiết:

Page 76: OOP in Java -  Ver1.1

76

© Vũ Duy Linh Lớp tự định nghĩa (3)

Có 02 mức khác nhau của bổ từ truy cập (modifier): Mức lớp (Class level):

public: Lớp sẽ được truy cập ở mọi nơi trong dự án – anywhere.

Không có modifier: Lớp chỉ được truy cập trong phạm vi cùng gói (package).

Các bổ từ astract, final sẽ được học ở các chương sau.

Mức các thành viên của lớp (Member level: fields và Methods): private: Các thành viên chỉ có thể được truy xuất trong phạm vi bên

trong lớp chứa nó, ngay cả các thành viên ở lớp con cũng không thể truy xuất tới (không được thừa kế).

public: Các thành viên của lớp sẽ được truy cập ở mọi nơi

Không có modifier (friendly/ package access): Trong cùng gói là public còn khác gói là private.

protected: Các thành viên được truy xuất bởi các phương thức ở cùng lớp, các phương thức ở trong các lớp con (được thừa kế) và các phương thức ở khác lớp nhưng phải cùng gói

Các bổ từ final, synchronized, transient, native,… sẽ được học sau.

Page 77: OOP in Java -  Ver1.1

77

© Vũ Duy Linh Lớp tự định nghĩa (4)

Ví dụ 1: Định nghĩa kiểu dữ liệu lớp HinhTron mà các thành viên

chỉ gồm các biến và các phương thức thể hiện:

public class HinhTron { //Mức lớp: truy cập được mọi nơi

private int x, y; // Mức thành viên: riêng của lớp

private double banKinh; // 3 biến thể hiện

public double tinhChuVi() { // Mức thành viên: truy cập được mọi nơi

return 2 * Math.PI * banKinh; // 2 phương thức thể hiện

}

public double tinhDienTich() {

return Math.PI * banKinh * banKinh;

}

}

Phạm vi truy nhập ở mức lớp HinhTron là public, mức của 3 biến

thể hiện là private, và mức 2 phương thức thể hiện là public.

Page 78: OOP in Java -  Ver1.1

78

© Vũ Duy Linh Lớp tự định nghĩa (5)

Bảng phạm vi truy cập ở mức thành viên

Quyền truy xuất

Phạm vi

public protected default private

Ở cùng lớp Yes Yes Yes Yes

Ở khác lớp và cùng gói Yes Yes Yes No

Ở lớp con và cùng gói Yes Yes Yes No

Ở lớp con và khác gói Yes Yes No No

Ở khác lớp vàkhác gói Yes No No No

Page 79: OOP in Java -  Ver1.1

79

© Vũ Duy Linh Lớp tự định nghĩa (6)

Lớp hằng/tận cùng (Final class): được khai báo với bổ từ modifier là final, nghĩa là không cho phép mở rộng hoặc thừa kế cho lớp con nữa.

Phương thức hằng (Final method): có modifier là final và không cho phép ghi chồng lên nó.

Biến hằng (Final variable): sử dụng từ khóa final.

Page 80: OOP in Java -  Ver1.1

80

© Vũ Duy Linh Đối tượng

Đối tượng (Object): Là một thể hiện của lớp, do vậy nó được

khai báo, khởi tạo thông qua một lớp đã được định nghĩa.

Cách 1: Khai báo và khởi tạo riêng biệt

Khai báo: TênLớp tênBiếnĐốiTượng;

Ví dụ: HinhTron ht1;

(Đọc là: biến ht1 (có kiểu HinhTron và được) tham chiếu tới null)

Khởi tạo: tênBiếnĐốiTượng = new TênLớp([Các_đối_số]);

Ví dụ: ht1 = new HinhTron();

(Đọc là: biến tham chiếu đối tượng hình tròn ht1

biến ht1 tham chiếu tới đối tượng hình tròn

giá trị của ht1 là một tham chiếu tới đối tượng hình tròn

địa chỉ của đối tượng hình tròn được trỏ bởi biến ht1)

Cách 2: Khai báo và khởi tạo một lần

Cú pháp: Tên_Lớp tênBiếnĐốiTượng = new TênLớp([Các_đối_số]);

Ví dụ: HinhTron ht2 = new HinhTron();

ht1 null

HinhTron

ht1

ht2

HinhTron

Page 81: OOP in Java -  Ver1.1

81

© Vũ Duy Linh Đối tượng (2)

Sự cấp và quản lý biến trong Java: Java có kiểu nguyên thủy và kiểu đối tượng,

chúng được cấp phát và tham chiếu như hình sau.

Page 82: OOP in Java -  Ver1.1

82

© Vũ Duy Linh Đối tượng (3)

Ví dụ 2: Viết chương trình (theo OBP) để tạo một hình tròn có toạ độ tâm

O(50,100), bán kính bằng 30 và hiển thị thông tin và diện tích của nó.

Source code: OBP_HinhTron.java

class HinhTron{

int x=50; int y=100; double banKinh=30;

double tinhDienTich(){

return Math.PI*Math.pow(banKinh, 2);

}

}

public class OBP_HinhTron {

public static void main(String[] args) {

HinhTron ht= new HinhTron();

System.out.printf("Hinh tron vua tao co tam O(%d,%d)"

+ " va dien tich= %.4f\n",ht.x,ht.y,ht.tinhDienTich());

}

}

Page 83: OOP in Java -  Ver1.1

83

© Vũ Duy Linh Đối tượng (4)

Phương thức dựng (Constructors) : Dùng để tạo một đối tượng, khởi tạo giá trị ban đầu cho thuộc tính của đối

tượng được tạo ra (nếu có).

Tên phương thức cùng tên với tên lớp

Không có kiểu trả về (kiểu void: không có giá trị trả về)

Có thể có nhiều phương thức dựng: Sử dụng phương thức nạp chồng (Overloading) của tính đa hình để viết

Sử dụng từ khóa this để tham chiếu đến chính đối tượng được tạo. Nó được dùng để phân biệt giữa biến thể hiện (instance variables) và các tham số hình thức khi chúng giống tên nhau

Sử dụng từ khóa supper để tham chiếu tới đối tượng thuộc lớp cha. Nó được dùng để gọi các phương thức, các biến thể hiện từ lớp cha

Java có sẵn một phương thức dựng mặc định (không có tham số) để gán tất cả các biến thể hiện bằng zero. Chúng ta có thể ghi chồng (Overriding ) phương thức mặc định này.

Phương thức hủy (Destructors ): Khác với C and C++, sự thu hồi bộ nhớ được Java tự động thực hiện

Java cung cấp một phương thức được gọi bởi Garbage collector, giúp cho ta thực hiện các yêu cầu trước khi đối tượng bị hủy, đó phương thức finalize()

Ta có thể ghi chồng lại phương thức finalize() này để quản lý các đối tượng trong chương trình.

Page 84: OOP in Java -  Ver1.1

84

© Vũ Duy Linh Đối tượng (5)

Phương thức thiết lập (Setters):

Dùng để gán giá trị (set) các biến thể hiện (private) của mỗi lớp.

Được gọi là phương thức thay đổi (mutator methods)

Có sự kiểm tra sự hợp lệ dữ liệu trước khi thiết lập giá trị trong setters để trở nên an toàn hơn.

Phương thức đọc (Getters):

Dùng để lấy (get) giá trị các biến thành viên của mỗi lớp.

Được gọi là phương thức truy xuất (accessor methods)

Các phương thức setters/getters là một cách bao đóng dữ liệu – chúng thường là các phương thức public để tạo ra một “kênh” giao tiếp với người dùng bên ngoài, nhằm truy xuất các dữ liệu riêng (private) của đối tượng thuộc lớp vừa định nghĩa được an toàn, bảo mật.

Thông thường, mỗi một biến thành viên sẽ có một cặp phương thức getter, setter.

Page 85: OOP in Java -  Ver1.1

85

© Vũ Duy Linh Đối tượng (6)

Lớp Circle

Circle

get

x, y, radius

set

Ví dụ 3: Viết chương trình định nghĩa một lớp có tên Circle có chứa các phương thức: dựng, set, get và tính diện tích của nó.

class Circle{ private int x, y, radius; // 3 biến thể hiện //Các phương thức dựng public Circle() { // ghi chồng pthức dựng mặc định x = y = 10; radius = 1; } public Circle(int radius) { // có 1 tham số hình thức this.radius = radius; } public Circle(int x, int y, int radius) { // các tham số cùng tên this.x = x; // với biến thể hiện this.y = y; this.radius = radius; } //Các phương thức setters/getters public int getRadius() { return radius; }

Page 86: OOP in Java -  Ver1.1

86

© Vũ Duy Linh Đối tượng (7)

public void setRadius(int radius) {

if (radius > 0){ // kiểm tra tính hợp lệ dữ liệu

this.radius = radius;

} else{

System.err.println(“Ban kinh hinh tron phai lon hon khong. ");

}

}

public int getX() {

return x;

}

public void setX(int x) {

this.x = x;

}

//Phương thức thể hiện

public double computeArea(){

return Math.PI*Math.pow(radius, 2);

}

} // Kết thúc định nghĩa lớp Circle

Page 87: OOP in Java -  Ver1.1

87

© Vũ Duy Linh Đối tượng (8)

public class Main { // lớp chính

public static void main(String[] args) {

Circle c1 = new Circle(20,20,10); // ban đầu bán kính là 10

System.out.printf("Dien tich voi ban kinh= %d la: .2f\n",c1.getRadius(), c1. computeArea ());

c1.setX(40); // dời toạ độ x = 40,

c1.setRadius(5); // đổi bán kính = 5

System.out.printf("Dien tich voi ban kinh= %d la: %.2f\n",c1.getRadius(), c1. computeArea ());

}

} (0,0) x

y

Page 88: OOP in Java -  Ver1.1

88

© Vũ Duy Linh Đối tượng (9)

Ví dụ 4: Tính n giai thừa theo OBP:

import java.util.Scanner;

public class GiaiThua {

int n;

public GiaiThua() { //Nhập n thông qua phương thức dựng

/*super(); */ Scanner in = new Scanner(System.in);

System.out.print("Nhap so nguyen n="); n= in.nextInt(); in.close();

}

public void tinhGiaiThua(){

long gt=1;

if(n<0) System.out.println("n= "+n+": Khong tinh giai thua.");

else{ for(int i=1; i<=n; i++) gt = gt*i;

System.out.println(n+"!= " + gt); }

}

public static void main(String[] args) {

GiaiThua gt = new GiaiThua(); gt.tinhGiaiThua(); }

}

Page 89: OOP in Java -  Ver1.1

89

© Vũ Duy Linh Đối tượng (10)

Biến và phương thức lớp - Static members:

Java cung cấp cách định nghĩa phương thức và biến “toàn cục” của lớp để mà các đối tượng thuộc lớp này sẽ có “điểm chung” kết dính cho nhau. Các phương thức và biến đảm nhận được nhiệm vụ như thế được gọi là biến và phương thức lớp.

Biến lớp (Class variables)và Phương thức lớp (Static methods):

Được khai báo với từ khóa static

Được tham chiếu thông qua tên lớp (không cần tạo đối tượng của lớp)

Biến lớp là phần dữ liệu dành riêng cho lớp và là biến chung cho tất cả các đối tượng được tạo ra từ lớp.

Phương thức lớp chỉ tham chiếu đến các biến lớp và các phương thức lớp (khác) và không sử dụng từ khóa this và sufer

Là phương thức được sử dụng để thiết kế các lớp mà các phương thức trong lớp không phụ thuộc vào các biến thể hiện của chúng. Chẳng hạn như thư viện chuẩn java.lang.Math

Page 90: OOP in Java -  Ver1.1

90

© Vũ Duy Linh Đối tượng (11)

Ví dụ 5: Viết chương trình để định nghĩa kiểu lớp Circle, sau đó

đếm số đối tượng được tạo ra/ được huỷ khi chạy chương trình?

Page 91: OOP in Java -  Ver1.1

91

© Vũ Duy Linh Đối tượng (12)

Page 92: OOP in Java -  Ver1.1

92

© Vũ Duy Linh Đối tượng (13)

Run

Page 93: OOP in Java -  Ver1.1

93

© Vũ Duy Linh Truyền tham số

Khi gọi phương thức có chứa tham số, ta cần phải truyền đối số

cho nó. Trong Java, vì không có khái niệm con trỏ, nên tất cả các

kiểu dữ liệu đều được truyền bằng tham trị (Pass by value).

Đối với biến kiểu nguyên thủy (Primitive type variable): Khi ta

ra lời gọi phương thức thì Java sẽ tạo một bản sao của biến tham

số thực (tst) và bản sao này sẽ truyền cho tham số hình thức (tsht)

giá trị của biến bản sao tst này sẽ bằng với giá trị của biến tsht

nhưng KHÔNG ảnh hưởng đến giá trị của tst ban đầu.

Đối với biến kiểu tham chiếu/ đối tượng (Reference/ Object

type variable): Java cũng truyền đối số bằng trị, nghĩa là giá trị

(của) biến tham chiếu của tst sẽ được truyền cho biến tham chiếu

của tsht. Như vậy, biến tst và tsht đều tham chiếu đến cùng một đối

tượng giá trị của chúng sẽ ẢNH HƯỞNG đến nhau.

Page 94: OOP in Java -  Ver1.1

94

© Vũ Duy Linh Truyền tham số (2)

Ví dụ 6 - Dự án gồm 3 lớp: HinhTron, TruyenThamSo, LopChinh

/**

* @author Vu Duy Linh

* Object-Based Programming, Truyen tham so...

*/

class HinhTron{

private int bk;

private String trThai;

public void setBk(int bk) {this.bk = bk;}

public void setTrThai(String trThai) {

this.trThai = trThai;

}

@Override

public String toString() {

return "\n\t>>> Trang thai: \""+ trThai+

"\" va ban kinh= "+ bk ;

}

}

Page 95: OOP in Java -  Ver1.1

95

© Vũ Duy Linh Truyền tham số (3)

public class PassParametters {

static void testPassObj(HinhTron ht2){

ht2.setTrThai("Da cap nhat"); // thay doi tsht

ht2.setBk(400);

}

static void testPassPri(int a){

a = 200; // thay doi tsht

}

public static void main(String[] args) {

int x = 100; //tst

System.out.println("Gia tri x TRUOC khi goi testPassPri= "+x);

testPassPri(x);

System.out.println("Gia tri x SAU khi goi testPassPri= "+x);

Page 96: OOP in Java -  Ver1.1

96

© Vũ Duy Linh Truyền tham số (4)

HinhTron ht1 = new HinhTron(); //tst

ht1.setTrThai("Ban dau");

ht1.setBk(300);

System.out.println("Thong tin hinh tron TRUOC khi goi testPassObj:"+ht1.toString());

testPassObj(ht1);

System.out.println("Thong tin hinh tron SAU khi goi testPassObj"+ht1.toString());

}

}

Kết quả:

Gia tri x TRUOC khi goi testPassPri= 100

Gia tri x SAU khi goi testPassPri= 100

Thong tin hinh tron TRUOC khi goi testPassObj:

>>> Trang thai: "Ban dau" va ban kinh= 300

Thong tin hinh tron SAU khi goi testPassObj

>>> Trang thai: "Da cap nhat" va ban kinh= 400

Page 97: OOP in Java -  Ver1.1

97

© Vũ Duy Linh Truyền tham số (5)

Ban đầu ht1

* Biến kiểu nguyên thủy:

Tham số thực Phương thức được gọi đang hoạt động

100 x-copy

100 a 200

Phương thức được gọi kết thúc

100 x

a

N/A

giải phóng

biến bởi GC

Phương thức được gọi đang hoạt động Tham số thực

Ban đầu ht1

ht2

Đã

cập nhật ht1

ht2

Đã

cập nhật ht1

ht2

null

giải phóng biến

Phương thức được gọi kết thúc

* Biển kiểu tham chiếu:

100 x

Thay đổi

Thay đổi

Sơ đồ minh hoạ:

x-copy

Page 98: OOP in Java -  Ver1.1

98

© Vũ Duy Linh Gói

Gói (Package): Là một cách để gom chung các kiểu dữ liệu (lớp, giao

diện,…) có liên hệ với nhau thành một nhóm với phạm vi quyền truy xuất

nhất định - việc quan trọng đối với những dự án phát triển theo phương

pháp lập trình HĐT.

Cú pháp:

package tên_gói[.tên_gói_con];

Ví dụ: package mycalculator;

package mycalculator.display;

package mycalculator.processing;

Quyền truy xuất

Phạm vi

public protected default private

Ở cùng lớp Yes Yes Yes Yes

Ở khác lớp và cùng gói Yes Yes Yes No

Bảng phạm vi truy cập ở mức thành viên

Page 99: OOP in Java -  Ver1.1

99

© Vũ Duy Linh Gói (2)

Ví dụ 7: Phương trình bậc hai có 2 lớp khác nhau và chung gói

Page 100: OOP in Java -  Ver1.1

100

© Vũ Duy Linh Gói (3)

Page 101: OOP in Java -  Ver1.1

101

© Vũ Duy Linh Gói (4)

Error

Successful

Page 102: OOP in Java -  Ver1.1

102

© Vũ Duy Linh Gói (5)

Ví dụ: Tạo một dự án (Project) có 02 gói

Gói 1 - package1: gồm (các) lớp chứa các phương thức để tính

cộng, và trừ hai số nguyên: x+y, x-y

Gói 2 - package2: gồm (các) lớp có chứa phương thức sau:

• phép nhân a * b = a + a + … +a (b lần): thông qua lời gọi phương

thức cộng ở package1

• Sử dụng hai phương thức cộng ở package1 và nhân ở cùng gói

(package2) để tính biểu thức S= 1*2 + 2*3 +…+n*(n+1)

• V.v…

Hướng dẫn: trên lớp

Page 103: OOP in Java -  Ver1.1

Chương 5. Kiểu dữ liệu mảng - Array

Giảng viên: Vũ Duy Linh Email: [email protected]

Page 104: OOP in Java -  Ver1.1

104

© Vũ Duy Linh Giới thiệu

Mảng (Array): Là một kiểu dữ liệu có cấu trúc, gồm một dãy liên tục

các phần tử cùng kiểu và được đại diện chung một tên biến.

Vì Java xem mảng là dữ liệu tham chiếu/ đối tượng, nên nó phải

được khai báo và khởi tạo trước khi sử dụng

Giá trị (value) mỗi phần tử được lưu trữ ở một chỉ số index (vị trí)

cụ thể, chỉ số đầu tiên bắt đầu từ 0.

Page 105: OOP in Java -  Ver1.1

105

© Vũ Duy Linh Mảng 1 chiều

Mảng 1 chiều myList đã được khai báo, khởi tạo và gán giá

trị vào 10 phần tử.

Page 106: OOP in Java -  Ver1.1

106

© Vũ Duy Linh

Khai báo: Cú pháp 1: kiểu_dữ_liệu[] tênBiến; // phổ biến

Vd: double[] myList;

Cú pháp 2: kiểu_dữ_liệu tênBiến[];

Vd: double myList[];

Chú ý: Kích thước của mảng sẽ được xác định khi khởi tạo.

Khởi tạo: Cách 1: Sử dụng toán tử new để tạo giá trị mặc định

Vd: double[] myList = new double[10]; // tạo mảng 10 phần tử

GiangVien[] bmTHUD = new GiangVien[15]; //15 giảng viên

Cách 2: Vừa khai báo vừa tạo giá trị cụ thể (không cần sử dụng new):

Vd: double[] myList = {5.6, 4.5, 3.3, 13.2, 4.0, 34.33, 34.0, 45.45, 99.993, 11123};

Mảng 1 chiều (2)

Page 107: OOP in Java -  Ver1.1

107

© Vũ Duy Linh Mảng 1 chiều (3)

Ví dụ 1: Viết chương trình (OBP) để in mảng một chiều lên màn hình, tính

tổng và tìm phần tử lớn nhất

Page 108: OOP in Java -  Ver1.1

108

© Vũ Duy Linh Mảng 1 chiều (4)

Kết quả: In mang - su dung lenh for:

2.0 1.5 3.5 -3.0

In mang - su dung lenh foreach:

2.0 1.5 3.5 -3.0

Tong la 4.0, va gia tri lon nhat la 3.5

Page 109: OOP in Java -  Ver1.1

109

© Vũ Duy Linh Mảng 1 chiều (5)

Java API có xây dựng sẵn các thư viện xử lý liên quan

đến kiểu mảng:

java.util.Arrays;

java.util.ArrayList;

Đề nghị sinh viên trang bị thêm kiến thức này.

Page 110: OOP in Java -  Ver1.1

110

© Vũ Duy Linh

Mảng 2 (nhiều) chiều được xem như là mảng của (các) mảng.

Khai báo:

Cú pháp: Kiểu_dữ_liệu[][] tênBiến;

Vd: int[][] mang2Chieu;

Khởi tạo: tương tự như 1 chiều Ví dụ:

double[][] a = new double[2][3];

double b[][] = new double[2][3];

double[][] c = new double[2][];

double[][] u; u = new double[2][3];

int[][] mang2D = { {12, 08, 67}, {78,10, 100}}

Mảng 2 chiều

Page 111: OOP in Java -  Ver1.1

111

© Vũ Duy Linh Mảng 2 chiều (2)

Minh họa khai báo, khởi tạo, gán trị và truy xuất biến mảng a:

Copyright © by Robert Sedgewick, Kevin Wayne

Page 112: OOP in Java -  Ver1.1

112

© Vũ Duy Linh

Ví dụ 2: Viết chương trình tạo ra một mảng 2

chiều có số lượng phần tử trên mỗi hàng khác

nhau (xem hình bên), giá trị của chúng được

nhập từ bàn phím.

Mảng 2 chiều (3)

Page 113: OOP in Java -  Ver1.1

113

© Vũ Duy Linh Mảng 2 chiều (4)

Kết quả:

Nhập các giá trị: 3, 5, 9, 7, -10, 15, 77, 25, 40, 12

In mang 2 chieu:

3 5 9

7 -10

15 77 25 40 12

Page 114: OOP in Java -  Ver1.1

114

© Vũ Duy Linh Truyền đối số bằng mảng

Ví dụ: Thay đổi nội dung của mảng bằng lời gọi phương thức

Page 115: OOP in Java -  Ver1.1

115

© Vũ Duy Linh Truyền đối số mảng (2)

Page 116: OOP in Java -  Ver1.1

116

© Vũ Duy Linh Truyền đối số mảng (3)

Page 117: OOP in Java -  Ver1.1

Chương 6.

Lớp bao kiểu nguyên thủy (Wrapper class),

lớp String, StringBuffer, StringTokenizer

Giảng viên: Vũ Duy Linh Email: [email protected]

Page 118: OOP in Java -  Ver1.1

118

© Vũ Duy Linh Lớp bao kiểu nguyên thủy

Ý nghĩa: Khi lập trình, nếu chúng ta cần biến kiểu tham chiếu/đối tượng thuộc vào một lớp chứa kiểu nguyên thủy (Primitive types) thì sử dụng lớp bao kiểu nguyên thủy (Wrapper class). Nói cách khác: Để sử dụng các biến trường và các phương thức được xây dựng sẵn của lớp chứa kiểu nguyên thủy, ta sử dụng wrapper class.

Ví dụ: double diemTrBinh = 8.5; //biến kiểu nguyên thủy double

Double diemTrB = new Double(8.5); //biến kiểu đối tượng của lớp Double

Page 119: OOP in Java -  Ver1.1

119

© Vũ Duy Linh Các lớp bao kiểu nguyên thủy

Các lớp bao kiểu nguyên thủy (Wrapper classes):

Đề nghị: Sinh viên tự nghiên cứu phần căn bản này từ:

Giáo trình: Lập trình Java căn bản,…

Ebook: Laura Lemay, Charles L. Perkins, Teach your self Java in 21days,…

Internet:

• http://www.syntax-example.com/Code/wrapper-classes-1357.aspx

• http://download.oracle.com/javase/tutorial/java/data/numberclasses.html

• …

Page 120: OOP in Java -  Ver1.1

120

© Vũ Duy Linh Lớp String

Khai báo

Cú pháp: String tênBiếnChuỗi;

Ví dụ: String hoTen;

Khởi tạo: Có 2 cách

Cú pháp 1 – String literals: tênBiếnChuỗi = "Chuỗi cần tạo"; • Ý nghĩa: Sử dụng 1 địa chỉ vùng nhớ chung cho các biến

chuỗi có giá trị chuỗi giống nhau.

• Ví dụ: hoTen1 = "Nguyễn Huệ";

Cú pháp 2 – String class: tênBiếnChuỗi = new String ("Chuỗi cần tạo"); • Ý nghĩa: Sử dụng địa chỉ vùng nhớ riêng cho mỗi biến chuỗi.

• Ví dụ: hoTen2 = new String("Lý Thường Kiệt");

Page 121: OOP in Java -  Ver1.1

121

© Vũ Duy Linh Lớp String (2)

Khai báo và khởi tạo:

Cú pháp: • String tênBiếnChuỗi = "Chuỗi cần tạo";

• String tênBiếnChuỗi = new String ("Chuỗi cần tạo");

Ví dụ: • String monHoc = "Lập trình hướng đối tượng Java";

• String chuyenNganh = new String("Tin học ứng dụng");

Chú ý: Đối tượng chuỗi có tính bất biến (Immutable) và không thể thay đổi nội dung khi chúng đã được tạo ra.

Page 122: OOP in Java -  Ver1.1

122

© Vũ Duy Linh Lớp String (3)

Một số phương thức quan tâm: String() chuỗi rỗng (null string) ;

String(String value) Tạo chuỗi value.

length(str) độ dài chuỗi str

charAt(int index) ký tự ở chỉ số index

trim(str) cắt bỏ khoảng trắng thừa bên trái và phải của str

compareTo(String anotherStr) <0: nhỏ hơn, 0: bằng nhau, >0: lớn hơn

compareToIgnoreCase( String anotherStr); // không phân biệt hoa thường

toLowerCase(str) chuyển thành chữ thường của str

toUpperCase(str) chuyển thành chữ in hoa cho chuỗi str

substring(int beginIndex) Tạo chuỗi con mới bắt đầu ở chỉ số beginIndex

substring(int beginIndex, int endIndex) chuỗi con từ beginIndex đến endIndex

equals(Object anObject) So sánh giá trị của đối tượng: true nếu bằng và ngược lại.

toán tử firstObjectString == secondObjectString So sánh địa chỉ đối tượng (địa chỉ reference chứa chuỗi): true nếu hai đối tượng bằng nhau và ngược lại.

Read more… http://docs.oracle.com/javase/7/docs/api/java/lang/String.html

Page 123: OOP in Java -  Ver1.1

123

© Vũ Duy Linh Lớp String (4)

Ví dụ : Tạo, so sánh giá trị và địa chỉ của chuỗi

Page 124: OOP in Java -  Ver1.1

124

© Vũ Duy Linh Lớp String (5)

/**

* @author Vu Duy Linh

* Pass parameter with String type

*/

public class PassStr {

static void kiemTra_Str(String tsht) {

tsht = “Chuoi da cap nhat!";

}

public static void main(String[] args) {

String tst = new String("Chuoi ban dau!");

System.out.println("Gia tri cua tham so thuc, tst: ");

System.out.println("\t>> TRUOC khi ra loi goi kiemTra_Str: "+tst);

kiemTra_Str(tst);

System.out.println("\t>>SAU khi kiemTra_Str hoan thanh: " + tst);

}

}

Giá trị của

tst có

thay đổi?

Truyền tham số bằng chuỗi String

? o

Page 125: OOP in Java -  Ver1.1

125

© Vũ Duy Linh Lớp String (6)

Vậy: Trước và sau khi gọi phương thức kiemTraStr(…) thì tst KHÔNG có bất kỳ

sự tác động nào từ tsht.

Hình minh họa truyền tham số bằng chuỗi - String

Page 126: OOP in Java -  Ver1.1

126

© Vũ Duy Linh Lớp String (7)

Ví dụ 2: Kiểm tra một từ có phải là Palindrome không?

Page 127: OOP in Java -  Ver1.1

127

© Vũ Duy Linh Lớp String (8)

Page 128: OOP in Java -  Ver1.1

128

© Vũ Duy Linh Lớp StringBuffer

Đối tượng String khi tạo ra thì nội dung cố định

Đối tượng StringBuffer khi tạo ra thì có thể thay đổi được Linh hoạt hơn String.

Sử dụng toán tử new để khởi tạo đối tượng

Khi đối tượng StringBuffer chứa chuỗi ký tự: Độ dài của chuỗi, String.length(), có thể khác với độ dài/khả năng chứa (capacity) của StringBuffer và ta có thể thay đổi độ dài của nó bằng setLength(int newLength)

Có thể cập nhật thêm append(…) , chèn insert(…), xóa delele(…)

Các phương thức dựng thường dùng: new StringBuffer() khởi tạo đối tượng StringBuffer có độ dài mặc

định là16 và không chứa ký tự nào cả.

new StringBuffer(int length) tương tự nhưng có độ dài length

new StringBuffer(String s) chứa chuỗi s và có độ dài = 16 + s.length()

Sử dụng phương thức toString() để đổi StringBuffer sang String.

Page 129: OOP in Java -  Ver1.1

129

© Vũ Duy Linh Lớp StringBuffer (2)

/**

* @author Vu Duy Linh

* Pass by StringBuffer

*/

public class PassStrBuffer {

static void kiemTra_Str(StringBuffer tsht) {

System.out.println("\t\tTruoc khi cap nhat, tsht= "+ tsht);

tsht.delete(0,tsht.length()).append("Chuoi ban dau da thay doi!");

System.out.println("\t\tSau khi da cap nhat, tsht= "+ tsht);

}

public static void main(String[] args) {

StringBuffer tst = new StringBuffer("Chuoi ban dau!...");

System.out.println("Gia tri cua tham so thuc, tst: ");

System.out.println("\t>>TRUOC khi ra loi goi kiemTra_Str: "+tst);

kiemTra_Str(tst);

System.out.println("\t>>SAU khi kiemTra_Str hoan thanh: "+tst);

}

}

Page 130: OOP in Java -  Ver1.1

130

© Vũ Duy Linh

Ứng dụng: Tách từng nhóm ký tự (token) dựa vào (các) ký tự phân tách – delimiters

Ví dụ: Tách các token của một chuỗi

Lớp StringTokenizer

Page 131: OOP in Java -  Ver1.1

131

© Vũ Duy Linh Lớp StringTokenizer (2)

}

Page 132: OOP in Java -  Ver1.1

132

© Vũ Duy Linh

Ví dụ: Kiểm tra một chuỗi (nhiều từ) có phải là Palindrome không?

Lớp StringTokenizer (3)

Page 133: OOP in Java -  Ver1.1

133

© Vũ Duy Linh Lớp StringTokenizer (4)

Page 134: OOP in Java -  Ver1.1

Chương 7. Đóng gói, Thừa kế,

và Đa hình

Giảng viên: Vũ Duy Linh Email: [email protected]

Page 135: OOP in Java -  Ver1.1

135

© Vũ Duy Linh Sự đóng gói

Đây là một trong những đặc điểm quan trọng của OOP.

Phương pháp để thực hiện việc đóng gói là sử dụng:

Phương thức setters, getters: để thiết lập một cơ chế truy xuất

đến các thuộc tính riêng của lớp

Các phương thức nội tại chi tiết bên trong

Lợi ích: Việc các đặt, sửa chữa nội dung bên trong lớp không ảnh

hưởng đến các lớp khác liên quan

Ví dụ:

1. Khi uống thuốc Aspirin, người dùng có cần biết

công thức hóa, cách trị bệnh của nó không?

2. Duyệt web, người dùng có cần biết mã lệnh HTML, CSS, framework,

thuật toán,… của chúng là gì không?

3. Xem các ví dụ trong phần thừa kế và đa hình (phía dưới).

Page 136: OOP in Java -  Ver1.1

136

© Vũ Duy Linh Thừa kế

Thừa kế là một cơ chế cho phép lập trình viên mở rộng một lớp cha cho một lớp con. Trong Java, thừa kế được sử dụng bởi 02 phương cách:

Thừa kế lớp (Class inheritance): Tạo một con lớp mới như là

một sự mở rộng (extends) của lớp khác (giúp cho việc tái sử dụng mã lệnh - code) - Java hỗ trợ thừa kế lớp đơn (single class inheritance )

Thừa kế giao diện (Interface inheritance): Tạo một lớp mới để cài đặt (implements) các phương thức đã được định nghĩa trong giao diện. Java hỗ trợ thừa kế bội giao diện - multiple interface inheritance (sẽ được trình bày ở chương Interface).

Page 137: OOP in Java -  Ver1.1

137

© Vũ Duy Linh Thừa kế lớp (2)

Phương pháp thiết kế:

Tạo mới/sử dụng một lớp cha (tổng quát) không phải là lớp final để định nghĩa những đặc điểm chung của các lớp con (nếu có) Xác định các thành viên (inherited members) của lớp cha có thể được thừa kế cho (các) lớp con.

Tạo (các) lớp con để mở rộng các thuộc tính và phương thức của lớp cha bằng cách thêm vào: Các thuộc tính, phương thức đặc trưng của lớp con

phương thức trùng tên được gọi là overriding methods, các biến trùng tên được gọi là biến phủ lấp (shadowing variables)

Các private members ở lớp cha không thừa kế cho lớp con, tuy nhiên ta có thể sử dụng phương thức setters/getters để truy xuất các biến riêng ở lớp cha.

Quyền truy xuất ở mức thành viên của các lớp, các lớp con thừa kế ở chung gói, khác gói được thể hiện ở bảng “phạm vi truy cập ở mức thành viên” (slide phía dưới)

Truy xuất các phương thức ở lớp cha thông qua từ khóa super, hoặc phương thức super()

Page 138: OOP in Java -  Ver1.1

138

© Vũ Duy Linh Thừa kế lớp (3)

Cú pháp định nghĩa lớp con thừa kế:

[modifier] class Subclass extends Superclass {

//Class body;

}

Từ khóa extends: là lớp con được mở rộng (dẫn xuất) từ lớp cha nó.

class HinhTron { private int x, y; private double bk; public HinhTron{…} public setBK(doble bk){…} protected double dienTich(){…} } class HinhTru extends HinhTron { private double chieuCao; public HinhTru(double chieuCao){ //… } // v.v… }

Page 139: OOP in Java -  Ver1.1

139

© Vũ Duy Linh Thừa kế lớp (4)

Bảng phạm vi truy cập ở mức thành viên

Quyền truy xuất

Phạm vi

public protected default private

Ở cùng lớp Yes Yes Yes Yes

Ở khác lớp và cùng gói Yes Yes Yes No

Ở lớp con và cùng gói Yes Yes Yes No

Ở lớp con và khác gói Yes Yes No No

Ở khác lớp và khác gói Yes No No No

Yêu cầu: Sinh viên viết chương trình hoàn

chỉnh để tính thể tích hình trụ theo:

a. Sơ đồ lớp đã thiết kế sẵn

b. Nếu đổi từ protected của dienTich()

thành private thì tính được không?

c. Sau khi xong câu a, chương trình có thể

coding lại để thay đổi tọa độ và/hoặc kích

thước của hình trụ không?

d. v.v…

Page 140: OOP in Java -  Ver1.1

140

© Vũ Duy Linh Thừa kế lớp (5)

Ví dụ: Giải OOP-PTB2, các lớp chung gói.

Page 141: OOP in Java -  Ver1.1

141

© Vũ Duy Linh Thừa kế lớp (6)

Page 142: OOP in Java -  Ver1.1

142

© Vũ Duy Linh Thừa kế lớp (7)

Page 143: OOP in Java -  Ver1.1

143

© Vũ Duy Linh Mối liên kết - Relationships

Đối tượng kiểu A có một (Has-A) biến thể hiện thuộc kiểu B

Kết tập chặt (Composition): Vòng đời (lifecycle) của đối tượng kiểu B

phụ thuộc nội tại vào vòng đời của A A được tạo thì B được tạo (sử

dụng final), A hủy thì B bị hủy theo. VD: “Mỗi người có một ngày sinh”,

“Mỗi xe có một động cơ”,…

Kết tập lỏng (Aggregation): Vòng đời của đối tượng kiểu B không phụ

thuộc vào vòng đời của A A hủy thì B có thể không bị hủy theo. VD:

“Mỗi TV có một Remote”, “Mỗi laptop có 1 ổ đĩa CD”

[public] class TV{

private Remote itsRmt;

}

[public] class Nguoi{

private final Ngay ngSinh;

public Nguoi(){

ngSinh=new Ngay();

}

}

Page 144: OOP in Java -  Ver1.1

144

© Vũ Duy Linh Mối liên kết (2)

Đối tượng kiểu A có nhiều (* Has-Many) biến thể hiện kiểu B

Liên kết (Association): Vòng đời của đối tượng kiểu B không phụ

thuộc vào vòng đời của A. VD: “Mỗi niên giám điện thoại có nhiều số

điện thoại”, “Mỗi GV có đăng hoặc không nhiều bài báo khoa học”.

Hỏi: “Mỗi người có tứ chi” hoặc “Mỗi căn nhà có từ một đến 10

phòng”, “Mỗi sinh viên học nhiều GV, mỗi GV dạy nhiều SV”,… thì

mối liên kết sẽ ntn?

[public] class BoMon{

private GiangVien soGV[15];

//private Vector<T> soGV; // nếu *

}

Theo nguyên lý SOLID, nên ưu tiên xét HAS-A trước khi IS-A

Page 145: OOP in Java -  Ver1.1

145

© Vũ Duy Linh Mối liên kết (3)

Ví dụ: Demo trên lớp

Page 146: OOP in Java -  Ver1.1

146

© Vũ Duy Linh Mối liên kết (4)

Page 147: OOP in Java -  Ver1.1

147

© Vũ Duy Linh Đa hình

Có 3 dạng đa hình (Polymorphism) phân biệt trong

ngôn lập trình Java 7:

Nạp chồng phương thức

Ghi chồng phương thức của thừa kế lớp

• Lớp thường (Class)

• Lớp trừu tượng (Abstract class )

• Lớp tổng quát (Generic class)

Ghi chồng phương thức của thừa kế giao diện

(Interface)

Page 148: OOP in Java -  Ver1.1

148

© Vũ Duy Linh Đa hình (2)

Dạng 1 – Nạp chồng (Overloading): Có nhiều phương thức cùng tên ở trong cùng một lớp với số lượng và kiểu tham số khác nhau

Giả sử trong lớp ViDu_Overloading có 04 phương thức:

• Phương thức 1: cong()

• Phương thức 2: cong(int a, int b)

• Phương thức 3: cong(int a, double b)

• Phương thức 4: cong(String a, String b)

Trong phương thức main của lớp ViDu_Overloading, các phương thức được gọi dựa vào đối số nhập vào như sau:

• cong() // phương thức 1 được gọi 0

• cong(2, 4) // phương thức 2 được gọi 6

• cong(5, 6.5) // phthức 3 được gọi 11.5

• cong("OOP" ,“in Java") // phthức 4 được gọi "OOP in Java"

Dạng 2- Ghi chồng (Overriding): Phương thức ở lớp con ghi đè lên

phương thức cùng tên ở lớp cha. Nó cho phép một phương thức có nhiều dạng tác động khác nhau trên các loại đối tượng khác nhau.

Page 149: OOP in Java -  Ver1.1

149

© Vũ Duy Linh Đa hình (3)

Ví dụ 1 - Ghi chồng, nhiều lớp nhiều gói khác nhau.

Page 150: OOP in Java -  Ver1.1

150

© Vũ Duy Linh Đa hình (4)

Page 151: OOP in Java -  Ver1.1

151

© Vũ Duy Linh Đa hình (5)

Page 152: OOP in Java -  Ver1.1

152

© Vũ Duy Linh Đa hình (6)

* Kết quả: Toi la doi tuong hinh tron, co dien tich= 7853.98

Toi la doi tuong hinh cau, co dien tich= 31415.93

Page 153: OOP in Java -  Ver1.1

153

© Vũ Duy Linh Đa hình (7)

c

a

s

t

i

n

g

Up

Down Ví dụ:

DongVat dv = new BoSat(); // Upcasting: OK

BoSat bs = (BoSat) dv; // Downcasting: OK (tường minh)

DongVatCoVu dvcv = dv; // Downcasting Error: type mismatch

DongVatCoVu dvcv2 = new DongVatCoVu();

Nguoi nguoi = new Nguoi();

nguoi = (Nguoi) dvcv2; /* Downcasting:

Biên dịch : OK; chạy: ErrorRuntime exception ClassCastException */

Ép (chuyển) kiểu Ép kiểu lên (Upcasting): đối tượng

kiểu lớp con được gán cho đối tượng

kiểu lớp cha/tổ tiên đối tượng của

lớp con được tham chiếu bởi biến

thuộc lớp cha của nó (theo thừa kế

phân cấp).

Chuyển kiểu xuống (Downcasting):

Theo thứ tự ngược lại của upcasting

và có thể thực hiện bằng ép kiểu

tường minh.

Page 154: OOP in Java -  Ver1.1

154

© Vũ Duy Linh Đa hình (8)

Ví dụ 2: Đa hình thông qua nạp chồng và ghi chồng ở cùng gói

Page 155: OOP in Java -  Ver1.1

155

© Vũ Duy Linh Đa hình (9)

/**

* @author Vu Duy Linh

* Polymorphism by overriding, overloading

*/

class LopCha{

protected int x = 10; //not private

void hienThi(){

System.out.println("Toi la phuong thuc trong LopCha."); }

int cong(int a, int b){ return a + b; }

private double cong(int a, double b){ return a + b; }

public Double cong(double a, Double b){ return a + b; }

String cong(String a, String b){ return a + " " + b; }

}

Page 156: OOP in Java -  Ver1.1

156

© Vũ Duy Linh Đa hình (10)

class LopConA extends LopCha{

//shadow variable – biến bóng: bị che phủ bởi biến cùng tên ở lớp cha

int x = 50;

void cong(LopConA lConA1, LopCha lCha ) {//overloading methods

}

void cong(LopConA lConA1, LopConA lConA2 ) { }

@Override

void hienThi(){ //over-riding method

System.out.println("Toi la phuong thuc trong LopConA."); }

}

class LopConB extends LopCha{

int x = 150;

void cong(LopConB lConB, LopConA lConA ) {

}

@Override

void hienThi(){ //over-riding method

System.out.println("Toi la phuong thuc trong LopConB."); }

}

Page 157: OOP in Java -  Ver1.1

157

© Vũ Duy Linh Đa hình (11)

public class DaHinh {

public static void main(String[] args) {

LopCha lCha = new LopCha();

lCha.hienThi();

System.out.printf("lCha1.x = %d\n\n",lCha.x);

LopCha lCha2 = new LopConA(); //upcasting

lCha2.hienThi(); //Không bị override bởi shadow var

System.out.printf("lCha2.x = %d\n\n",lCha2.x);

LopConA lCon = new LopConA();

lCon.hienThi();

System.out.printf("lCon.x = %d\n\n", lCon.x);

/* Error: LopCha khong the convert sang LopCon

LopCon lcon2 = new LopCha(); */

Page 158: OOP in Java -  Ver1.1

158

© Vũ Duy Linh Đa hình (12)

LopCha[] a= new LopCha[3]; a[0]=new LopCha();

a[1]=new LopConA(); a[2]=new LopConB(); //upcasting

int so_dtLopCha=0, so_dtLopConA = 0;

for (LopCha lopCha : a) {

lopCha.hienThi(); //run-time <=> late binding

if (lopCha instanceof LopCha) so_dtLopCha++;

if (lopCha instanceof LopConA) so_dtLopConA++;

}

System.out.println("So doi tuong \"Is-A\" cua LopCha=" +so_dtLopCha);

System.out.println("So doi tuong \"Is-A\" cua LopConA=" +so_dtLopConA);

}

}

Run

Toi la phuong thuc trong LopCha.

lCha1.x = 10

Toi la phuong thuc trong LopConA.

lCha2.x = 10

Toi la phuong thuc trong LopConA.

lCon.x = 50

Toi la phuong thuc trong LopCha.

Toi la phuong thuc trong LopConA.

Toi la phuong thuc trong LopConB.

So doi tuong "Is-A" cua LopCha= 3

So doi tuong "Is-A" cua LopConA= 1

Page 159: OOP in Java -  Ver1.1

Chương 8. Lớp trừu tượng và giao diện Abstract class và Interface

Giảng viên: Vũ Duy Linh Email: [email protected]

Page 160: OOP in Java -  Ver1.1

160

© Vũ Duy Linh Lớp trừu tượng

Trong quá trình thiết kế chương trình, chúng ta thường đi

theo quy trình: Từ tổng quát đến cụ thể.

Tổng quát (General):

• Là trường hợp chung chung, ở mức khái niệm

• Sự chung chung đó được xem như là sự trừu tượng

• Lớp mà có tính tổng quát như thế được gọi là lớp trừu tượng

(Abstract class): không thể cài đặt các hành vi (phương thức) một

cách chi tiết/cụ thể được.

Cụ thể (Specific):

• Là trường hợp riêng biệt, một cách rõ ràng: có thể cài đặt các hành

vi (phương thức) một cách chi tiết.

• Lớp có tính riêng biệt được gọi là lớp cụ thể (concrete class): cài

đặt hoàn chỉnh tất cả các hành vi (phương thức).

• Từ lớp tổng quát cho đến lớp cụ thể có thể có nhiều cấp độ trừu

tượng giảm dần khác nhau (cụ thể dần mức độ trừu tượng).

Page 161: OOP in Java -  Ver1.1

161

© Vũ Duy Linh Lớp trừu tượng (2)

Lớp cụ thể là: Không có từ khóa abstract

Chỉ chứa các phương thức cụ thể (concrete methods)

Phương thưc cụ thể không có từ khóa abstract và được cài đặt hoàn chỉnh

Cần được sử dụng từ khóa new để tạo đối tượng (instances/objects)

Có thể làm lớp cha, lớp con (superclass, subclass): nhưng tất cả các phương thức ở cha con đều được cài đặt hoàn chỉnh

Ví dụ: Tất cả các ví dụ đã học ở phần trên

Lớp trừu tượng là: Được định nghĩa bởi từ khóa abstract

Tồn tại một hoặc tất cả các phương thức trừu tượng (abstract method)

Phương thức trừu tượng được khai báo với từ khóa abstract và chỉ có phần tên phương thức (prototype): Phần thân chưa cài được đặt

Lớp trừu tượng đóng vai trò làm lớp cha. Lớp con thừa kế từ lớp trừu tượng cha có thể là lớp trừu tượng con hoặc là lớp cụ thể

Là thực thể trừu tượng Không được sử dụng từ khóa new để tạo đối tượng

Lớp trừu tượng thường được dùng để gắn kết các lớp cụ thể - cài đặt đầy đủ các phương thức ở superclass.

Bổ từ của lớp là khác private và không chứa abstract static methods.

Page 162: OOP in Java -  Ver1.1

162

© Vũ Duy Linh Lớp trừu tượng (3)

[Modifier] abstract class TênLớpTrừuTượng {

[Modifier] data_type tênTrường_1;

[Modifier] data_type tênTrường_m;

// Khai báo các phần tên phương thức trừu tượng

[Modifier] abstract return_type tênPhươngThức_1([Các_Tham_số]);

[Modifier] abstract return_type tênPhươngThức_i([Các_Tham_số]);

// Định nghĩa các phương thức cụ thể

[Modifier] return_type tênPhươngThức_j([Các_Tham_số]){

//…

return (giá trị trả về);

}

[Modifier] return_type tênPhươngThức_n([Các_Tham_số]){

//…

return (giá trị trả về);

}

}

Cú pháp khai báo

Page 163: OOP in Java -  Ver1.1

163

© Vũ Duy Linh Lớp trừu tượng (4)

Ví dụ 1

Page 164: OOP in Java -  Ver1.1

164

© Vũ Duy Linh Lớp trừu tượng (5)

Mã lệnh:

Page 165: OOP in Java -  Ver1.1

165

© Vũ Duy Linh Lớp trừu tượng (6)

Page 166: OOP in Java -  Ver1.1

166

© Vũ Duy Linh Lớp trừu tượng (7)

Page 167: OOP in Java -  Ver1.1

167

© Vũ Duy Linh Lớp trừu tượng (8)

Page 168: OOP in Java -  Ver1.1

168

© Vũ Duy Linh Lớp trừu tượng (9)

Ví dụ: Cho các loại động vật. Hãy viết chương trình hiển thị lên tiếng kêu của

từng loài (vd: gâu gâu, meo meo, cạp cạp,…) bằng 02 cách:

1. Sử dụng ép kiểu (Downcasting)

2. Sử dụng đa hình (Polymorphism) //sử dụng lớp trừu tượng

• Source code DongVat.java

Page 169: OOP in Java -  Ver1.1

169

© Vũ Duy Linh Lớp trừu tượng (10)

• Source code DongVat.java

Page 170: OOP in Java -  Ver1.1

170

© Vũ Duy Linh Lớp trừu tượng (11)

Page 171: OOP in Java -  Ver1.1

171

© Vũ Duy Linh Giao diện

Giao diện (Interface): Là một thực thể trừu tượng ở mức cao hơn cả lớp trừu tượng

Lớp là mẫu (template) cho việc hình thành đối tượng, còn interface là mẫu để hình thành lớp.

Một interface cụ thể hóa một loạt các chức năng mà một lớp được cài đặt từ nó cần làm những gì (what) chứ không cần phải biết làm như thể nào (how)

Sử dụng từ khóa interface, nó chỉ chứa các biến hằng và các phương thức trừu tượng

Khác với lớp, Java hỗ trợ thừa kế bội giao diện thông qua từ khóa extends

Không thể new đối tượng

Page 172: OOP in Java -  Ver1.1

172

© Vũ Duy Linh Giao diện (2)

[public] interface TênGiaoDiện {

//Khai báo các hằng, ngầm định là: public static final

data_type tênTrường_1 = value_1;

data_type tênTrường_m = value_m;

// Khai báo các tên phương thức trừu tượng, ngầm định: public abstract

return-type tênPhươngThức_1([Các_Tham_số]);

return-type tênPhươngThức_n([Các_Tham_số]);

}

* Ví dụ:

interface GiaoDienDongVat {

String TEN_GIAO_DIEN = "giao dien dong vat";

void tuGioiThieu();

}

GiaoDienDongVat

Cú pháp khai báo

Page 173: OOP in Java -  Ver1.1

173

© Vũ Duy Linh Giao diện (3)

Sự cài đặt giao diện (Implementing Interfaces): Interface được xem như là một mẫu (template) để hình thành lớp. Do đó cần có một lớp làm nhiệm vụ cài đặt cụ thể, bằng từ khóa implements, các phương thức (ảo) trong interface để các chức năng này trở nên hiệu lực và được gọi là lớp cài đặt giao diện (implementation class).

Cú pháp:

[Modifiers] [abstract] class TênLớp implements TênGiaoDiện [, TênGiaoDiện2,…]{

// cài đặt cụ thể các phương thức ảo

}

Ví dụ:

class Meo implements GiaoDienDongVat{

public void tuGioiThieu(){

System.out.println("Xin chào! Tôi là Doremon thuộc họ nhà mèo.");

}

}

Page 175: OOP in Java -  Ver1.1

175

© Vũ Duy Linh Giao diện (5)

Sự thừa kế lớp và cài đặt giao diện: Việc định nghĩa lớp con thừa kế đơn từ lớp cha và được cài đặt từ (nhiều) giao diện có dạng tổng quát sau.

Cú pháp:

[Modifiers] class TênLớpCon extends TênLớpCha implements TênGiaoDiện [,TênGiaoDiện 2,…] {

//cài đặt cụ thể các phương thức ảo

}

Ví dụ:

public class PhepTinh1Ngoi extends PhepTinh implements ICong, ITru, INhan, IChia{

private final Screen s;

public void cong(){

s.setKetQua(String.format("%.2f", s.getA() + s.getB()));

}

//...

}

Page 176: OOP in Java -  Ver1.1

176

© Vũ Duy Linh Giao diện (6)

* Ví dụ 2: Sự cài đặt từ nhiều giao diện

Page 177: OOP in Java -  Ver1.1

177

© Vũ Duy Linh Giao diện (7)

Screen.java

package vdlinh.package1;

public class Screen {

private double a, b;

private String ketQua;

public Screen(double a, double b){

this.a = a; this.b = b;}

public double getA() {

return a;}

public double getB() {

return b;}

public String getKetQua() {

return ketQua; }

public void setKetQua(String ketQua){

this.ketQua = ketQua;}

}

Page 178: OOP in Java -  Ver1.1

178

© Vũ Duy Linh Giao diện (8)

PhepTinh.java

package vdlinh.package2;

import vdlinh.package1.Screen;

interface ICong{ void cong(); } interface ITru{ void tru(); }

interface INhan{ void nhan(); } interface IChia{ void chia(); }

public class PhepTinh implements ICong, ITru, INhan, IChia{

private final Screen s;

public PhepTinh(Screen s) { this.s = s; }

public Screen getS() { return s; }

public void cong(){

s.setKetQua(String.format("%.2f", s.getA() + s.getB())); }

public void tru(){

s.setKetQua(String.format("%.2f", s.getA() - s.getB())); }

public void nhan(){

s.setKetQua(String.format("%.2f", s.getA() * s.getB())); }

public void chia(){

if (s.getB() == 0) {s.setKetQua(“Loi: Chia cho khong!");}

else s.setKetQua(String.format("%.2f", s.getA() / s.getB()));}

}

Page 179: OOP in Java -  Ver1.1

179

© Vũ Duy Linh Giao diện (9)

OOP_SimpleCalc.java

package vdlinh.package3; import java.util.Scanner;

import vdlinh.package1.Screen; import vdlinh.package2.PhepTinh;

public class OOP_SimpleCalc {

public static void main(String[] args) {

double th1,th2; char c;

Scanner in=new Scanner(System.in);

do {

out.print("Nhap toan hang 1= "); th1 = in.nextDouble();

out.print("Nhap toan hang 2= "); th2 = in.nextDouble();

PhepTinh pt = new PhepTinh(new Screen(th1,th2));

out.print(“Chon phep tinh (+, -,* , /), T de thoat? ");

String s = in.next(); c = s.charAt(0);

switch (c) {

case '+':

pt.cong();

out.println("Tong= "+ pt.getS().getKetQua());

break;

Page 180: OOP in Java -  Ver1.1

180

© Vũ Duy Linh Giao diện (10)

case '-':

pt.tru();

out.println("Hieu= "+ pt.getS().getKetQua());

break;

case '*':

pt.nhan();

out.println("Tich= "+ pt.getS().getKetQua());

break;

case '/':

pt.chia();

out.println("Thuong= "+ pt.getS().getKetQua());

break;

}

} while (Character.toUpperCase(c) != 'T');

System.out.println("Chuong trinh ket thuc...");

in.close();}

} //end main class

Page 181: OOP in Java -  Ver1.1

181

© Vũ Duy Linh Giao diện (11)

Thừa kế bội bằng

giao diện

Java cho phép định

nghĩa một giao diện

con được thừa kế từ

nhiều giao diện cha.

Điều này giúp cho

việc trừu tượng hóa

trong những dự án

lớn được dễ dàng

hơn.

Ví dụ: Minh họa dự án

có 4 interface

Page 182: OOP in Java -  Ver1.1

182

© Vũ Duy Linh Giao diện (12)

/** @author Vu Duy Linh */

interface IOne{

String TITLE ="Interface one";

void doSomeThing(); }

interface ITwo{

String TITLE ="Interface two";

void doSomeThing(); }

interface IThree extends IOne, ITwo {

String TITLE ="Interface three";

void doSomeThing3(); }

interface IFour {

String TITLE ="Interface four";

void doSomeThing4(); }

class ConcreteClassImp implements IThree, IFour{

@Override

public void doSomeThing() {

System.out.println("Cai dat doSomeThing()"); }

Ví dụ

Page 183: OOP in Java -  Ver1.1

183

© Vũ Duy Linh Giao diện (13)

public void doSomeThing3() {

System.out.println("Cai dat doSomeThing3()"); }

public void doSomeThing4() {

System.out.println("Cai dat doSomeThing4()"); }

}

public class MIITest {

public static void main(String[] args) {

ConcreteClassImp cci = new ConcreteClassImp();

cci.doSomeThing();cci.doSomeThing3();

cci.doSomeThing4();

out.println("Title of IOne= "+IOne.TITLE);

out.println("Title of ITwo= "+ITwo.TITLE);

out.println("Title of IThree= "+IThree.TITLE);

out.println("Title of IFour= "+IFour.TITLE);

//out.println("Title of cii= "+cci.TITLE); // ambiguous

}

}

Page 184: OOP in Java -  Ver1.1

184

© Vũ Duy Linh Giao diện (14)

Đa hình bằng giao diện

Ví dụ: Trên lớp

Page 185: OOP in Java -  Ver1.1

185

© Vũ Duy Linh Giao diện (15)

Page 186: OOP in Java -  Ver1.1

Chương 9. Ngoại lệ và xử lý ngoại lệ Exceptions và Exception handle

Giảng viên: Vũ Duy Linh Email: [email protected]

Page 187: OOP in Java -  Ver1.1

187

© Vũ Duy Linh Giới thiệu

Một chương trình được viết ra thường gặp các lỗi sau: Lỗi cú pháp (Syntax errors): Do LTV không tuân theo đúng cú pháp

của ngôn ngữ lập trình và được trình biên dịch hỗ trợ sửa lỗi.

VD: int a = (5 +7; boolean kt := true;

Lỗi ngữ nghĩa (Semantic errors): Sử dụng câu lệnh không đúng cách. Nó được phân ra 2 loại: Lỗi ngữ nghĩa tĩnh (static semantic errors) ở thời điểm biên dịch và lỗi ngữ nghĩa động (dynamic semantic errors) ở thời điểm runtime.

. VD: char c = “A”; // type mismatch/incompatibility;

int[] a = new int [3];

a[3]=5; // java.lang.ArrayIndexOutOfBoundsException

Lỗi logic (Logical errors): Chương trình cho ra những kết quả sai hoặc không mong muốn.

VD: int cong(int a, int b) { return a*b; }

Để giúp cho người viết chương trình có thể kiểm soát và quản lý được các lỗi compiler/runtime, Java cung cấp một cơ chế "Ngoại lệ" và "Xử lý ngoại lệ"

Page 188: OOP in Java -  Ver1.1

188

© Vũ Duy Linh Ngoại lệ

Ngoại lệ (Exception): Là một cơ chế để thông báo và xử lý các lỗi trong chương trình gặp phải. Khi chương trình phát hiện ra lỗi thì một ngoại lệ tương ứng với lỗi sẽ được thẩy ra. Có 2 loại ngoại lệ:

Ngoại lệ được kiểm tra (Checked exception): Bao gồm tất cả các lỗi

cú pháp và một số lỗi ngữ nghĩa tĩnh. Chúng sẽ được phát hiện bởi trình biên dịch Java

Ví dụ:

Biên dịch: lỗi.

Chạy: lỗi. ☻

Page 189: OOP in Java -  Ver1.1

189

© Vũ Duy Linh Ngoại lệ (2)

Chạy: lỗi.

Biên dịch:

thành công.

Ngoại lệ không được kiểm tra (Unchecked exception): Là lỗi không được phát hiện trong quá trình biên dịch mà chúng chỉ được phát hiện khi chạy chương trình (Runtime). Chúng bao gồm các lỗi ngữ nghĩa động và các lỗi logic.

Ví dụ:

Page 191: OOP in Java -  Ver1.1

191

© Vũ Duy Linh Ngoại lệ (4)

Các loại ngoại lệ được thẩy/tung/ném lên thông qua lớp Throwable

lớp Object

lớp Throwable

lớp Error lớp Exception

lớp RuntimeException Các lớp con Exception

khác RuntimeException

Thuộc loại:

Unchecked exceptions

Thuộc loại:

Checked exceptions

Các phương thức thường

được sử dụng:

1. getCause()

2. getMessage()

3. getStackTrace()

4. toString()

Page 192: OOP in Java -  Ver1.1

192

© Vũ Duy Linh Ngoại lệ (5)

* Lớp chuẩn Error: Là các lỗi nghiêm trọng gây nguy hiểm (fatal) cho sự thực thi chương trình và KHÔNG được Java phát hiện trong quá trình biên dịch và thuộc loại unchecked exception.

AssertionError

Page 193: OOP in Java -  Ver1.1

193

© Vũ Duy Linh Ngoại lệ (6)

Các lớp

chuẩn Exception Standard Java exception classes

o Lớp Exception: Bao gồm lớp RuntimeException cùng với các lớp con của nó (Unchecked exception) và các lớp con khác (Checked exception)

Page 194: OOP in Java -  Ver1.1

194

© Vũ Duy Linh Ngoại lệ (7)

Link: http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Exception.html

o Các lớp con của Exception trong JDK 1.5

Page 195: OOP in Java -  Ver1.1

195

© Vũ Duy Linh Ngoại lệ (8)

Một số minh họa phát sinh lỗi ngoại lệ RuntimeException: Trong gói java.util:

1. EmptyStackException: Lỗi khi ngăn xếp rỗng (empty stack) Stack stack = new Stack();

stack.pop(); // java.util.EmptyStackException

2. NoSuchElementException: Không có phần tử cần tìm trong kiểu liệt kê (enum) ArrayList al = new ArrayList();

al.add(new String("Hi!"));

Iterator iterator = al.iterator();

iterator.next(); // ok

iterator.next(); // hết còn phần tử: java.util.NoSuchElementException

Trong gói: java.lang:

1. ArithmaticException: khi tính toán số học sai, như chia cho 0 int a = 10/0; // java.lang.ArithmeticException: / by zero.

2. ArrayStoreException: khi lưu đối tượng khác kiểu vào mảng kiểu đối tượng Object[] x = new Integer[5];

x[0] = new String("Java"); // java.lang.ArrayStoreException: java.lang.String

3. ClassCastException: khi ép kiểu cho một đối tượng chưa được khởi tạo Object y = new Integer(10); /* y = new Double(y.toString()); // ok */

y = (Double) y; /*java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Double */

Page 196: OOP in Java -  Ver1.1

196

© Vũ Duy Linh Ngoại lệ (9)

Trong gói: java.lang:

4. IllegalArgumentException: Lỗi truyền đối số sai.

IllegalThreadStateException: phát sinh một ngoại lệ nếu gọi phương thức start() mà Thread này đã được bắt đầu chạy (start) khởi hoạt (được học ở chương sau)

NumberFormatException: Lỗi chuyển đổi một chuỗi số không hợp lệ sang số.

Integer.parseInt("Java2010"); //java.lang.NumberFormatException: For input string: "Java2010"

5. IllegalMonitorStateException: thực hiện các phương thức của đối tượng monitor (đối tượng giám sát tuyến đoạn) không hợp lệ (học ở chương sau)

6. IndexOutOfBoundsException: Chỉ số vượt ra ngoài phạm vi của đối tượng

ArrayIndexOutOfBoundsException: Lỗi sai chỉ số của mảng

int[] a = {5, 10, 15};

int v = a[3]; // java.lang.ArrayIndexOutOfBoundsException: 3

StringIndexOutOfBoundsException: Lỗi sai chỉ số của chuỗi

7. NegativeArraySizeException: lỗi do kích thước mảng âm.

double[] mang = new double[-10]; //java.lang.NegativeArraySizeException

8. NullPointerException: lỗi truy xuất đối tượng chưa được khởi tạo

double[][] array2D = new double[5][];

array2D[0][0]=8.0; //java.lang.NullPointerException

9. SecurityException: Lỗi không được quyền truy cập

Page 197: OOP in Java -  Ver1.1

197

© Vũ Duy Linh Xử lý ngoại lệ

Xử lý ngoại lệ (Exception Handling):

Khi một ngoại lệ xảy ra, một đối tượng thuộc lớp ngoại lệ cụ thể liên quan đến lỗi đó được tạo ra. Nhờ đó người lập trình có thể bắt được đối tượng này để xử lý lỗi, giúp cho chương trình không bị ngắt ngang một cách đột ngột.

Java cung cấp rất đa dạng các lớp ngoại lệ giúp hiệu quả trong việc bắt lỗi ngoại lệ

Ví dụ: Lớp ArithmaticException để quản lý lỗi ngoại lệ của phép toán chia 0, lớp NullPointerException để xử lý lỗi truy xuất đối tượng chưa được khởi tạo

Page 198: OOP in Java -  Ver1.1

198

© Vũ Duy Linh Xử lý ngoại lệ (2)

some bugs: có lỗi runtime

phát sinh ngoại lệ

kết thúc cách

bất thường

Bắt đầu kết thúc cách

bình thường

Bad

program

Xử lý ngoại lệ

thẩy lỗi

(throw)

Bắt đầu kết thúc cách

bình thường

Good

program

bắt lỗi

(catch)

* Là một dạng như cấu trúc điều khiển:

Khi gặp phải một lỗi, luồng chương

trình đang chạy sẽ bị dừng, ngoại lệ

sẽ được xử lý sao cho nó được kết

thúc một cách bình thường (theo kịch

bản sẵn có của người lập trình)

throw(s) và catch

Page 199: OOP in Java -  Ver1.1

199

© Vũ Duy Linh Xử lý ngoại lệ (3)

1. Từ khóa throw: để thẩy/ném ra một ngoại lệ (do JVM hoặc LTV)

* Cú pháp: throw throwableObject;

Với throwableObject: là một đối tương thuộc lớp Throwable hoặc lớp con nó

* Ví dụ: throw new ArrayIndexOutOfBoundsException("Lỗi chỉ số mảng");

2. Từ khóa throws: để thẩy ra một hoặc nhiều ngoại lệ của phương thức

* Cú pháp: [modifiers] returntype methodName(params) throws

class_Exception1,... , class_Exception_n {

// thân phương thức

}

Với class_Exception_i: là lớp Throwable hoặc lớp con của nó

* Ví dụ:

void tinhMang(int[] a) throws NullPointerException,

ArithmeticException{

// có thể mảng chưa được khởi tạo

// có thể lỗi chia cho zero

}

Page 200: OOP in Java -  Ver1.1

200

© Vũ Duy Linh Xử lý ngoại lệ (4)

Câu lệnh try .. catch.. Finally

try {

// Câu lệnh thực hiện. Nếu không có lỗi thì chạy bình thường, ngược lại sẽ

// thẩy lên một ngoại lệ để bắt (catch ) nó …

} catch (Loại Exception 1 e1) {

// … và khối lệnh để xử lý với ngoại lệ loại e1

} catch (Loại Exception 2 e2) {

// … và xử lý với loại e2

} catch (Loại Exception 3 e3) {

// … và xử lý với loại e3

} catch (Exception e) { // Loại Exception thứ n

// … và xử lý với mọi ngoại lệ e

} finally { // luôn được thi hành

// Khối lệnh thích hợp sau khi đã bắt mọi lỗi ngoại lệ

} * Chú ý: lệnh try có thể

- có một hoặc nhiều catch và/hoặc một finally

- nếu có finally thì có thể không cần catch

Page 201: OOP in Java -  Ver1.1

201

© Vũ Duy Linh Xử lý ngoại lệ (5)

Ví dụ: JVM sẽ tự động thẩy ra ngoại lệ

Page 202: OOP in Java -  Ver1.1

202

© Vũ Duy Linh Xử lý ngoại lệ (6)

Ví dụ: LTV quản lý thẩy và bắt ngoại lệ - throw

Page 203: OOP in Java -  Ver1.1

203

© Vũ Duy Linh Xử lý ngoại lệ (7)

Ví dụ: LTV quản lý thẩy và bắt ngoại lệ bằng throw và throws

Page 204: OOP in Java -  Ver1.1

204

© Vũ Duy Linh Xử lý ngoại lệ (8)

Ví dụ về throws, throw, try..catch..finally

Page 205: OOP in Java -  Ver1.1

205

© Vũ Duy Linh Xử lý ngoại lệ (9)

run:

3. Loi duoc thay ra: java.lang.NullPointerException - (Phan tu) mang chua duoc 'new'.

Lenh sau cung duoc thuc hien trong khoi Try..catch..finally.

Page 206: OOP in Java -  Ver1.1

206

© Vũ Duy Linh Xử lý ngoại lệ (10) Phép chia zero:

double a = 1/0; java.lang.ArithmeticException: / by zero

double a = 1/0.0; Infinity (vô cực)

Lan truyền ngược (exception propogation)

Lan truyền ngược

Page 207: OOP in Java -  Ver1.1

207

© Vũ Duy Linh Xử lý ngoại lệ (11)

Từ khóa assert (khẳng định)

Cú pháp: assert biểuThứcLogic [: “Chuỗi thông báo lỗi”];

Sẽ kiểm tra biểu thức logic xem có phải là khẳng định đúng (true)

không, nếu sai thì sinh ra lỗi java.lang.AssertionError, ngược lại thì chương trình

tiếp tục. Nếu có thêm phần tùy chọn, LTV tự đưa ra thông báo lỗi bằng “Chuỗi

thông báo lỗi” thay vì thông báo lỗi mặc định của JVM.

Lớp AssertionError:

Khi gặp một khẳng định sai thì JVM sẽ thẩy ra lỗi java.lang.AssertionError

Chú ý: Để chương trình không bị ngắt ngang, LTV cần sử dụng câu lệnh

try..catch..finally để bắt lỗi ngoại lệ phát sinh (nếu có)

Ví dụ: Xem slides sau…

Page 208: OOP in Java -  Ver1.1

208

© Vũ Duy Linh Xử lý ngoại lệ (12)

Page 209: OOP in Java -  Ver1.1

209

© Vũ Duy Linh Xử lý ngoại lệ (13)

// 1a. Ket qua chia so nguyen= 5.0

// 1b. Loi ngoai le la: java.lang.ArithmeticException: / by zero

// 2a. Ket qua chia so thuc= 5.0

// 2a. Ket qua chia so thuc= Infinity

// 3a. Ket qua chia so thuc =5.0

// 3b. Bat ngoai le sinh ra: java.lang.AssertionError

// java.lang.AssertionError: 4a. Loi chia 0 va bi ngat ngang

Page 210: OOP in Java -  Ver1.1

210

© Vũ Duy Linh Kết chương

Ở ví dụ và bài tập ở các chương trước, Sinh

viên hãy viết lại chương trình mà có phần bắt

lỗi ngoại lệ phát sinh (nếu có) chương

trình sẽ an toàn và professional hơn.

Đề nghị:

Page 211: OOP in Java -  Ver1.1

Chương 10. Kỹ thuật tổng quát Generics

Giảng viên: Vũ Duy Linh Email: [email protected]

Page 212: OOP in Java -  Ver1.1

212

© Vũ Duy Linh Generics

Tóm ý:

Kiến thức lập trình Java quan trọng

Phần bắt buộc trong học phần TN196

Sẽ được trình bày sau

Page 213: OOP in Java -  Ver1.1

Chương 11. Tập các cấu trúc dữ liệu Java Collection Framework

Giảng viên: Vũ Duy Linh Email: [email protected]

Page 214: OOP in Java -  Ver1.1

214

© Vũ Duy Linh Collections

Tóm ý:

Kiến thức lập trình Java quan trọng

Phần tùy chọn trong học phần TN196

Page 215: OOP in Java -  Ver1.1

Chương 12. Tuyến và đa tuyến đoạn Thread and Multi-threads

Giảng viên: Vũ Duy Linh Email: [email protected]

Page 216: OOP in Java -  Ver1.1

216

© Vũ Duy Linh Thread and Multi-threads

Tóm ý:

Kiến thức lập trình Java quan trọng

Phần tùy chọn trong học phần TN196

Sẽ được biên soạn sau

Page 217: OOP in Java -  Ver1.1

Chương 13. Luồng và tập tin Streams and files

Giảng viên: Vũ Duy Linh Email: [email protected]

Page 218: OOP in Java -  Ver1.1

218

© Vũ Duy Linh Luồng và tập tin

Luồng (Stream):

Nền tảng nhất của lập trình I/O trong Java dựa tên luồng (Stream).

Một luồng đại diện cho luồng / dòng chảy của dữ liệu. Nó là một dãy

tuần tự các byte với chiều dài không xác định

về mặt lý thuyết, được gắn với một đầu ghi là writer và đầu khác để

đọc là reader.

Đọc và ghi nguồn dữ liệu từ chương trinh bằng luồng

Source: Claudius Gros

Page 219: OOP in Java -  Ver1.1

219

© Vũ Duy Linh Luồng và tập tin (2)

Page 220: OOP in Java -  Ver1.1

220

© Vũ Duy Linh Luồng và tập tin (3)

Page 221: OOP in Java -  Ver1.1

221

© Vũ Duy Linh Luồng và tập tin (4)

Link: http://docs.oracle.com/javase/7/docs/api/java/io/package-tree.html

Hierarchy For Package java.io

Page 222: OOP in Java -  Ver1.1

222

© Vũ Duy Linh Luồng và tập tin (5)

InputStream và OutputStream (abstract class): định nghĩa các chức chính để

đọc/ghi dãy các byte không có cấu trúc (unstructured sequence of bytes).

Tất cả các luồng byte khác trong Java được xây dựng trên nền tảng cơ bản

của hai lớp này.

Reader, Writer (abstract class): định nghĩa các chức chính để đọc/ghi dãy

các dữ liệu ký tự (character data) với cả sự hỗ trợ unicode.

DataInputStream, DataOutputStream: luồng lọc (filter streams) được chuyên

biệt để có thể đọc và ghi các kiểu dữ liệu nhiều byte (multibyte) như short,

long, VARCHAR(100 BYTE) trong DB.

ObjectInputStream, ObjectOutputStream: là các luồng filter chuyên biệt để

ghi một toàn bộ nhóm các đối tượng java tuần tự (serialization) và tái tạo

(xây dựng) lại chúng.

BufferedInputStream, BufferedOutputStream, BufferedReader,

BufferedWriter: Là các luồng filter chuyên biệt để đọc ghi các dữ liệu I/O ở

thế giới thực như các bộ nhớ ngoài – giúp tăng hiệu quả đọc ghi dữ liệu.

PrintStream, PrintWriter: Luồng để in văn bản

FileInputStream, FileOutputStream, FileReader, FileWriter: đọc và ghi tập tin

Page 223: OOP in Java -  Ver1.1

223

© Vũ Duy Linh Luồng và tập tin (6)

Basic I/O:

InputStream stdin = System.in;

OutputStream stdout = System.out;

OutputStream stderr = System.err;

Đoạn lệnh định nghĩa mảng buff kiểu byte và phương thức read() để

điền dữ liệu vào mảng với khả năng chứa nhiều nhất có thể và trả về

số bytes đọc được:

và tạo ra một mảng data với đúng kích thước của nó:

Page 224: OOP in Java -  Ver1.1

224

© Vũ Duy Linh Luồng và tập tin (7)

Character Streams

Page 225: OOP in Java -  Ver1.1

225

© Vũ Duy Linh Luồng và tập tin (8)

Stream Wrappers: I/O streams thường được xếp lớp/kết nối (Layered/

Chained streams) lại với nhau để thực hiện cho coongnhững mục đích

khác nhau mà các stream khác nhau (có nhiều đặc tính khác nhau) mang

lại, ví dụ như: tạo vùng đệm (buffering), lọc (filtering) hoặc chuyển đổi các

định dạng dữ liệu (data-format conversion) và được gọi chung là các luồng

lọc (filter streams).

VD:

Source: Claudius Gros

BufferedInputStream in in = new BufferedInputStream(

new FileInputStream(fileName));

Page 226: OOP in Java -  Ver1.1

226

© Vũ Duy Linh Luồng và tập tin (9)

Data streams:

VD: DataInputStream dis = new DataInputStream( System.in );

double d = dis.readDouble();

Buffered streams:

BufferedInputStream bis = new

BufferedInputStream(myInputStream, 32768);

bis.read();

PrintWriter and PrintStream:

Page 227: OOP in Java -  Ver1.1

227

© Vũ Duy Linh Luồng và tập tin (10)

Pipes: Những ứng dụng cần hai phía của luồng ví dụ như sự trao đổi giữa

các tuyến đoạn.

Java cung cấp gói: import java.nio.channels.Pipe;

Piped streams:

Hoặc:

Lựa chọn một luồng làm phía thứ nhất, sau đó dựng luồng phía còn

lại bằng cách sử dụng luồng thứ nhất làm đối số cho nó.

Page 228: OOP in Java -  Ver1.1

228

© Vũ Duy Linh Luồng và tập tin (11)

Ví dụ: PrintStream

Page 229: OOP in Java -  Ver1.1

229

© Vũ Duy Linh Luồng và tập tin (12)

Ví dụ: PrintWriter

Page 230: OOP in Java -  Ver1.1

230

© Vũ Duy Linh Luồng và tập tin (13)

Ví dụ về BufferInputStream

Kết quả: ABCDE A: 65| B: 66| C: 67| D: 68| E: 69|

Page 231: OOP in Java -  Ver1.1

231

© Vũ Duy Linh Luồng và tập tin (14)

Tập tin (File I/O):

Lớp java.IO.File,

java.nio.file.Files: Tạo file và

kiểm tra sự tồn tại, thư mục

đường dẫn thư mục, quyền

tập tin,…

FileStream: FileInputStream

và FileOutputStream

RandomAccessFile

Page 232: OOP in Java -  Ver1.1

232

© Vũ Duy Linh Luồng và tập tin (15)

Ví dụ: chép file bằng BufferedInputStream

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.File; import java.io.IOException;

//Source: http://www.ntu.edu.sg/

public class FileCopyBufferedStreamJDK7 {

public static void main(String[] args) {

String inFileStr = "d:/OOPJava/LearningJava.pdf";

String outFileStr = "d:/OOPJava/LearningJava-out.pdf";

long startTime, elapsedTime; // for speed benchmarking

File fileIn = new File(inFileStr);

System.out.println("File size is "+ fileIn.length()+" bytes");

Page 233: OOP in Java -  Ver1.1

233

© Vũ Duy Linh Luồng và tập tin (16)

try (BufferedInputStream in = new BufferedInputStream(

new FileInputStream(inFileStr)) BufferedOutputStream out= new BufferedOutputStream(

new FileOutputStream(outFileStr))){

startTime = System.nanoTime(); int byteRead;

while ((byteRead = in.read()) != -1) {

out.write(byteRead);}

elapsedTime = System.nanoTime() - startTime;

System.out.println("Elapsed Time is "+ (elapsedTime / 1000000.0) + " msec");

} catch (IOException ex) {

ex.printStackTrace();}

}

} File size is 25743822 bytes

Elapsed Time is 2756.206114 msec

Page 234: OOP in Java -  Ver1.1

234

© Vũ Duy Linh Luồng và tập tin (17)

Ví dụ chương: Viết chương trình OOP cho việc nhập xuất các đối

tượng sinh viên (cao đẳng, đại học, sau đại học). Mỗi loại sinh viên

có chung các thông tin về: Mã số (String), ngày sinh (Date), số tín

chỉ tích lũy (int).

Lưu ý: Sinh viên tự chuyên biệt hóa cho 3 trường hợp Cao đẳng, Đại

học, Sau đại học

Hãy tạo ra 10 đối tượng thuộc vào 3 loại đối tượng tên và lưu vào tập

tin D:/Danhsach.dat

Đọc từ file Danhsach.dat và phân ra 3 danh sách: Cao đẳng, Đại học,

Sau đại học và cho biết số tin chỉ tích lũy nhiều nhất và nhỏ nhất

Xem mã lệnh OOP_IO.java

Page 235: OOP in Java -  Ver1.1

Chương 14. Kết nối cơ sở dữ liệu Java Database Connectivity

Giảng viên: Vũ Duy Linh Email: [email protected]

Page 236: OOP in Java -  Ver1.1

236

© Vũ Duy Linh Database Connectivity

Tóm ý:

Lập trình ứng dụng CSDL

Sẽ được trình bày sau

Phần tùy chọn (option) trong học phần TN196

Page 237: OOP in Java -  Ver1.1

237

© Vũ Duy Linh Tài liệu tham khảo

1. Anban Pilla, Object Oriented Programming using Java, 2007

2. Buyya, Selvi, Chu (2009), Object Oriented Programming with Java: Essentials and Applications, TATA MC-GRAW HILL PUBLISHING CO.LTD.-NE.

3. Bruce Eckel (1998), Thinking in Java, Prentice Hall PTR.

4. Cay S. Horstmann (2004), Gary Cornell, Core JavaTM 2 Volume I - Fundamentals, Seventh Editition, Prentice Hall PTR.

5. Cay S. Horstmann (2004), Gary Cornell, Core JavaTM 2 Volume II – Advanced Features, Seventh Editition, Prentice Hall PTR.

6. Daniel Liang (2003), Introduction to Java Programming, Fifth Edition.

7. Eric Armstrong, Jennifer Ball, Stephanie Bodoff, Debbie Bode Carson, Ian Evans, Dale Green, Kim Haase, Eric Jendrock, (2006), The J2EETM 1.4 Tutorial: For Sun Java System Application Server Platform Edition 8.2, Sun Microsystems.

8. Joshua Block (2001), Effective Java: Programming Language Guide, Addison Wesley.

9. Paul Deitel, Harvey Deitel, JavaTM How to Program, 9th, 2012

10. Patrick Niemeyer and Daniel Leuck, Learning Java, 4th, 2012, O’REILLY, 2013

11. R. Morelli, R. Walde, Java, Java, Java Object-Oriented Problem Solving, 3rd Edition, 2012.

13. Robert Cecil Martin, UML for Java Programmers, Prentice Hall, 2002

14. Simon Kendal, Object Oriented Programming using Java, 2009

Page 238: OOP in Java -  Ver1.1

238

© Vũ Duy Linh Tài liệu tham khảo

15. Trần Minh Châu, Nguyễn Việt Hà, Giáo trình: Lập trình hướng đối tượng với Java, NXB ĐHQG 2013 (draft)

16. V.v…

17. Và nhiều links được cập nhật sau