Bài giảng Lập trình hướng đối tượng - Bài 8: Đa hình (Tiếp theo)

Upcasting và Downcasting

Chuyển đổi kiểu dữ liệu nguyên thủy

Java tự động chuyển đổi kiểu khi

Kiểu dữ liệu tương thích

Chuyển đổi từ kiểu hẹp hơn sang kiểu rộng hơn

int i;

double d = i;

Phải ép kiểu khi

Kiểu dữ liệu tương thích

Chuyển đổi từ kiểu rộng hơn sang kiểu hẹp hơn

int i;

byte b = i; byte b = (byte)i;

Chuyển đổi kiểu dữ liệu tham chiếu

Kiểu dữ liệu tham chiếu có thể được chuyển đổi kiểu khi

Kiểu dữ liệu tham chiếu (lớp) tương thích

Nằm trên cùng một cây phân cấp kế thừa

A var1 = new B();

A var1 = new A();

C var2 = (C)var1;

Hai cách chuyển đổi

Up-casting

Down-casting

Bài giảng Lập trình hướng đối tượng - Bài 8: Đa hình (Tiếp theo) trang 1

Trang 1

Bài giảng Lập trình hướng đối tượng - Bài 8: Đa hình (Tiếp theo) trang 2

Trang 2

Bài giảng Lập trình hướng đối tượng - Bài 8: Đa hình (Tiếp theo) trang 3

Trang 3

Bài giảng Lập trình hướng đối tượng - Bài 8: Đa hình (Tiếp theo) trang 4

Trang 4

Bài giảng Lập trình hướng đối tượng - Bài 8: Đa hình (Tiếp theo) trang 5

Trang 5

Bài giảng Lập trình hướng đối tượng - Bài 8: Đa hình (Tiếp theo) trang 6

Trang 6

Bài giảng Lập trình hướng đối tượng - Bài 8: Đa hình (Tiếp theo) trang 7

Trang 7

Bài giảng Lập trình hướng đối tượng - Bài 8: Đa hình (Tiếp theo) trang 8

Trang 8

Bài giảng Lập trình hướng đối tượng - Bài 8: Đa hình (Tiếp theo) trang 9

Trang 9

Bài giảng Lập trình hướng đối tượng - Bài 8: Đa hình (Tiếp theo) trang 10

Trang 10

Tải về để xem bản đầy đủ

pdf 40 trang duykhanh 9740
Bạn đang xem 10 trang mẫu của tài liệu "Bài giảng Lập trình hướng đối tượng - Bài 8: Đa hình (Tiếp theo)", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

Tóm tắt nội dung tài liệu: Bài giảng Lập trình hướng đối tượng - Bài 8: Đa hình (Tiếp theo)

Bài giảng Lập trình hướng đối tượng - Bài 8: Đa hình (Tiếp theo)
 Bộ môn Công nghệ Phần mềm
 Viện CNTT & TT
 Trường Đại học Bách Khoa Hà Nội
 IT3100
LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG
 Bài 08. Đa hình 
 Mục tiêu
◼ Giới thiệu về upcasting và downcasting
◼ Phân biệt liên kết tĩnh và liên kết động
◼ Nắm vững kỹ thuật đa hình
◼ Ví dụ và bài tập về các vấn đề trên với ngôn 
 ngữ lập trình Java
 2
 Nội dung
1. Upcasting và Downcasting
2. Liên kết tĩnh và Liên kết động
3. Đa hình (Polymorphism)
4. Ví dụ và bài tập
 3
1. Upcasting và Downcasting 
 4
 1. Upcasting và Downcasting
◼ Chuyển đổi kiểu dữ liệu nguyên thủy
 ◼ Java tự động chuyển đổi kiểu khi
 ◼ Kiểu dữ liệu tương thích
 ◼ Chuyển đổi từ kiểu hẹp hơn sang kiểu rộng hơn
 int i;
 double d = i;
 ◼ Phải ép kiểu khi
 ◼ Kiểu dữ liệu tương thích
 ◼ Chuyển đổi từ kiểu rộng hơn sang kiểu hẹp hơn
 int i;
 byte b = i; byte b = (byte)i;
 5
 1. Upcasting và Downcasting
◼ Chuyển đổi kiểu dữ liệu tham chiếu
 ◼ Kiểu dữ liệu tham chiếu có thể được chuyển đổi kiểu khi
 ◼ Kiểu dữ liệu tham chiếu (lớp) tương thích A
 ◼ Nằm trên cùng một cây phân cấp kế thừa
 A var1 = new B();
 A var1 = new A();
 C var2 = (C)var1; B
 ◼ Hai cách chuyển đổi
 ◼ Up-casting
 “dán cho nó một cái nhãn”
 ◼ Down-casting
 C
 6
 1.1 Upcasting
◼ Up casting: đi lên trên cây phân cấp thừa kế 
 (moving up the inheritance hierarchy)
◼ Up casting là khả năng nhìn nhận đối tượng thuộc 
 lớp dẫn xuất như là một đối tượng thuộc lớp cơ sở.
◼ Tự động chuyển đổi kiểu
 7
 1.1 Upcasting
◼ Ví dụ:
public class Test1 { Person
 public static void main(String arg[]) { - name: String
 Employee e = new Employee(); - birthday: Date
 Person p;
 + setName(String)
 p = e;
 p.setName(“Hoa”); ? + setBirthday(Date)
 p.setSalary(350000); + getDetails(): String 
 // compile error
}
 Employee
 - salary: double
 + setSalary(double)
 + getDetails(): String
 8
 1.1 Upcasting Person
 - name: String
 - birthday: Date
◼ Ví dụ: + setName(String)
class Manager extends Employee { + setBirthday(Date)
 Employee assistant;
 + getDetails(): String 
 // ...
 public void setAssistant(Employee e) {
 assistant = e; Employee
 } - salary: double
 // ... + setSalary(double)
} + getDetails(): String
public class Test2 {
 public static void main(String arg[]) {
 Manager
 Manager junior, senior;
 // ... - assistant: Employee
 senior.setAssistant(junior); + setAssistant(Employee)
 } + getDetails():String
} 9
 1.1 Upcasting Person
 - name: String
 - birthday: Date
◼ Ví dụ: + setName(String)
public class Test3 { + setBirthday(Date)
 String static teamInfo(Person p1,
 + getDetails(): String 
 Person p2) {
 return "Leader: " + p1.getName() +
 ", member: " + p2.getName(); Employee
 } - salary: double
 public static void main(String arg[]) { + setSalary(double)
 Employee e1, e2; + getDetails(): String
 Manager m1, m2;
 // ... 
 Manager
 System.out.println(teamInfo(e1, e2));
 System.out.println(teamInfo(m1, m2)); - assistant: Employee
 System.out.println(teamInfo(m1, e2)); + setAssistant(Employee)
 } + getDetails():String
} 10
 1.2 Downcasting
◼ Down casting: đi xuống cây phân cấp thừa kế 
 (move back down the inheritance hierarchy)
◼ Down casting là khả năng nhìn nhận một đối tượng 
 thuộc lớp cơ sở như một đối tượng thuộc lớp dẫn 
 xuất.
◼ Không tự động chuyển đổi kiểu 
 → Phải ép kiểu.
 11
 1.2 Downcasting Person
 - name: String
 - birthday: Date
◼ Ví dụ: + setName(String)
public class Test2 { + setBirthday(Date)
 public static void main(String arg[]) {
 + getDetails(): String 
 Employee e = new Employee();
 Person p = e; // up casting
 Employee e1 = (Employee) p; Employee
 // down casting - salary: double
 Manager m = (Manager) ee; + setSalary(double)
 // run-time error + getDetails(): String
 Person p2 = new Manager();
 Manager
 Employee e2 = (Employee) p2;
 } - assistant: Employee
} + setAssistant(Employee)
 + getDetails():String
 12
 Toán tử instanceof
◼ Kiểm tra xem một đối tượng có phải là thể hiện của 
 một lớp nào đó không
◼ Trả về: true | false (nếu đối tượng là null thì trả về 
 false)
 public class Employee extends Person {}
 public class Student extends Person {}
 public class Test{
 public doSomething(Person e) {
 if (e instanceof Employee) {...
 } else if (e instanceof Student) {...
 } else {...
 }
 }
 13
 }
2. Liên kết tĩnh và liên kết động
(Static binding & dynamic binding)
 14
 Liên kết lời gọi hàm
◼ Liên kết lời gọi hàm (function call binding) là quy 
 trình xác định khối mã hàm cần chạy khi một lời gọi 
 hàm được thực hiện
 ◼ C: đơn giản vì mỗi hàm có duy nhất một tên
 ◼ C++: chồng hàm, phân tích chữ ký kiểm tra danh sách 
 tham số
 15
 Trong ngôn ngữ Hướng đối tượng
◼ Liên kết lời gọi phương thức
◼ Đối với các lớp độc lập (không thuộc cây thừa kế 
 nào), quy trình này gần như không khác với 
 function call binding
 ◼ so sánh tên phương thức, danh sách tham số để tìm định 
 nghĩa tương ứng
 ◼ một trong số các tham số là tham số ẩn: con trỏ this
 bar.foo (); → lời gọi 
 này bị ràng buộc với định 
 nghĩa của phương thức 
 mà nó gọi
 16
 2.1 Liên kết tĩnh
◼ Liên kết tại thời điểm biên dịch
 ◼ Early Binding/Compile-time Binding
 ◼ Lời gọi phương thức được quyết định khi biên 
 dịch, do đó chỉ có một phiên bản của phương 
 thức được thực hiện
 ◼ Nếu có lỗi thì sẽ có lỗi biên dịch
 ◼ Ưu điểm về tốc độ
◼ C/C++ function call binding, và C++ method 
 binding cơ bản đều là ví dụ của liên kết tĩnh 
 (static function call binding)
 17
 2.1 Liên kết tĩnh
◼ Thích hợp cho các lời gọi hàm thông thường
 ◼ Mỗi lời gọi hàm chỉ xác định duy nhất một định 
 nghĩa hàm, kể cả trường hợp hàm chồng.
◼ Phù hợp với các lớp độc lập không thuộc cây 
 thừa kế nào
 ◼ Mỗi lời gọi phương thức từ một đối tượng của lớp 
 hay từ con trỏ đến đối tượng đều xác định duy 
 nhất một phương thức
 18
 2.2 Liên kết động
◼ Lời gọi phương thức được quyết định khi 
 thực hiện (run-time)
 ◼ Late binding/Run-time binding
 ◼ Phiên bản của phương thức phù hợp với đối 
 tượng được gọi
 ◼ Java trì hoãn liên kết phương thức cho đến thời 
 gian chạy (run-time) - đây được gọi là liên kết 
 động hoặc liên kết trễ
 ◼ Java mặc định sử dụng liên kết động
 19
 Ví dụ Person
 - name: String
 - birthday: Date
public class Test {
 + setName(String)
 public static void main(String arg[]){
 + setBirthday(Date)
 Person p = new Person();
 + getDetails(): String 
 // ...
 Employee e = new Employee();
 // ... Employee
 Manager m = new Manager(); - salary: double
 // ... + setSalary(double)
 Person pArr[] = {p, e, m}; + getDetails(): String
 for (int i=0; i< pArr.length; i++){
 System.out.println(
 pArr[i].getDetail()); Manager
 } - assistant: Employee
 } Tuỳ thuộc vào đối tượng + setAssistant(Employee)
} gọi tại thời điểm thực thi + getDetails():String
 chương trình (run-time) 20
 Câu hỏi
◼ Giả sử lớp Sub kế thừa từ lớp cha Sandwich. Tạo hai đối 
 tượng từ các lớp này:
 Sandwich x = new Sandwich();
 Sub y = new Sub();
◼ Phép gán nào sau đây là hợp lệ?
 1. x = y;
 2. y = x;
 3. y = new Sandwich();
 4. x = new Sub();
 21
3. Đa hình
(Polymorphism)
 22
 3. Đa hình
◼ Ví dụ: Một hoạt động có thể được thực hiện trên một đối 
 tượng 2DShape cũng có thể được thực hiện trên một đối 
 tượng thuộc một trong ba lớp Tam giác, Hình tròn, Tứ giác.
 ◼ Lớp cha 2DShape định nghĩa giao diện chung
 ◼ Các lớp con Tam giác, Vòng tròn, Tứ giác phải theo giao diện này (kế thừa), 
 nhưng cũng được phép cung cấp các triển khai riêng của chúng (ghi đè)
 Object
→ Khi một phương thức được 
yêu cầu thông qua tham chiếu 
lớp 2DShape, các đối tượng 
2DShape, Tam giác, Hình tròn và Shape .
Tứ giác phản ứng khác nhau
 2D Shape 3D Shape
 Circle Triangle Quadrilateral Sphere Polyhedron 
 23
 3. Đa hình
 ◼ Ví dụ:
public class 2DShape { public class Point extends 2DShape {
 public void display() { private int x, y; 
 System.out.println("2D Shape"); ...
 } public void display(){
} System.out.print("(" + x + "," + y + ")");
 }
 }
public class Circle extends 2DShape{
 public static final double PI = 
 public class Quadrilateral extends 2DShape {
 3.14159;
 private Point p1, p2, p3, p4;
 private Point p;
 private double r; //radious
 .....
 ...
 public void display(){
 public void display(){
 System.out.println("Quadrilateral: ");
 System.out.print("Circle: " + 
 r + ","); p1.display(); p2.display();
 p.display(); p3.display(); p4.display();
 System.out.println(); System.out.println();
 } }
} } 24
 3. Đa hình
◼ Ví dụ: Có nhiều sự lựa chọn một khi một phương thức được 
 gọi thông qua một tham chiếu lớp cha.
 Object of super 
 class Object of Circle class
 display() Circle: 1, (0,0) 
 Object of Point class
 Application 
 2DShape display() (0,1)
 program display()
 Object of Quadrilateral class
 Quadrilateral: 
 display() (0,0), (0,1), (1,0), (1,1)
 2D Shape
 25
 3. Đa hình
◼ Polymorphism: Nhiều hình thức thực hiện, nhiều 
 kiểu tồn tại
 ◼ Khả năng của một biến tham chiếu thay đổi hành vi theo 
 đối tượng mà nó đang giữ.
◼ Đa hình trong lập trình
 ◼ Đa hình phương thức:
 ◼ Phương thức trùng tên, phân biệt bởi danh sách tham số.
 ◼ Đa hình đối tượng
 ◼ Nhìn nhận đối tượng theo nhiều kiểu khác nhau
 ◼ Các đối tượng khác nhau cùng đáp ứng chung danh sách các 
 thông điệp có giải nghĩa thông điệp theo cách thức khác nhau.
 26
 3. Đa hình
◼ Polymorphism: gia tăng khả năng tái sử dụng 
 những đoạn mã nguồn được viết một cách tổng 
 quát và có thể thay đổi cách ứng xử một cách linh 
 hoạt tùy theo loại đối tượng
 ◼ Tính đa hình (Polymorphism) trong Java được hiểu là 
 trong từng trường hợp, hoàn cảnh khác nhau thì đối 
 tượng có hình thái khác nhau tùy thuộc vào từng ngữ 
 cảnh
◼ Để thể hiện tính đa hình:
 ◼ Các lớp phải có quan hệ kế thừa với 1 lớp cha nào đó
 ◼ Phương thức được ghi đè (override) ở lớp con
 27
 3. Đa hình Person
 - name: String
 - birthday: Date
◼
 Ví dụ: + setName(String)
◼ Các đối tượng khác nhau giải nghĩa + setBirthday(Date)
 các thông điệp theo các cách thức + getDetails(): String 
 khác nhau
 ◼ Liên kết động (Java) Employee
Person p1 = new Person(); - salary: double
Person p2 = new Employee(); + setSalary(double)
Person p3 = new Manager(); + getDetails(): String
// ...
System.out.println(p1.getDetail()); Manager
System.out.println(p2.getDetail()); - assistant: Employee
System.out.println(p3.getDetail()); + setAssistant(Employee)
 + getDetails():String
 28
 3. Đa hình Person
 - name: String
 - birthday: Date
◼
 Ví dụ: + setName(String)
class EmployeeList {
 Employee list[]; + setBirthday(Date)
 ... + getDetails(): String 
 public void add(Employee e) {...}
 public void print() {
 for (int i=0; i<list.length; i++) { Employee
 System.out.println(list[i]. - salary: double
 getDetail());
 + setSalary(double)
 }
 } + getDetails(): String
 ...
 EmployeeList list = new EmployeeList(); Manager
 Employee e1; Manager m1; - assistant: Employee
 ...
 + setAssistant(Employee)
 list.add(e1); 
 list.add(m1); + getDetails():String
 list.print(); 29
 3. Đa hình
◼ Ví dụ: Các đối tượng Triangle, Rectangle, Circle đều là các 
 đối tượng Shape
...
public static void handleShapes(Shape[] shapes){
 // Vẽ các hình theo cách riêng của mỗi hình
 for( int i = 0; i < shapes.length; ++i) {
 shapes[i].draw();
 }
 ...
 // Gọi đến phương thức xóa, 
 // không cần quan tâm đó là hình gì
 for( int i = 0; i < shapes.length; ++i) {
 shapes[i].erase();
 }
}
...
 30
 Câu hỏi
 ◼ Cho 
 biểu đồ lớp:
Phương thức printLine() của lớp nào sẽ được sử dụng trong mỗi trường 
hợp dưới đây, biết rằng z là một đối tượng của lớp F? Giải thích ngắn gọn?
1. z.printLine(1)
2. z.printLine(2, "Object-Oriented Programming")
3. z.printLine("Java")
4. z.printLine("Object-Oriented Programming", "Java")
 31
5. z.printLine("Object-Oriented Programming", 3)
 Câu hỏi
◼ Những điều kiện nào trả về true? (Có thể xem Java 
 documentation để biết các quan hệ thừa kế giữa các lớp) 
 Biết rằng System.out là một đối tượng của lớp PrintStream.
 1. System.out instanceof PrintStream
 2. System.out instanceof OutputStream
 3. System.out instanceof LogStream
 4. System.out instanceof Object
 5. System.out instanceof String
 6. System.out instanceof Writer
 32
Tổng kết
 33
 Tổng kết
◼ Upcasting và downcasting
 ◼ Nhìn nhận các đối tượng thuộc lớp cơ sở như đối 
 tượng thuộc lớp dẫn xuất (upcasting) và ngược 
 lại (down-casting)
◼ Liên kết tĩnh và liên kết động
 ◼ Liên kết lời gọi hàm lúc biên dịch (liên kết tĩnh) 
 hay lúc chạy chương trình (liên kết động)
◼ Đa hình
 ◼ Nhìn nhận một đối tượng dưới nhiều kiểu khác 
 nhau
 34
Bài tập
 35
 Bài tập 1
◼ Kiểm tra các đoạn mã sau đây và vẽ sơ đồ lớp 
 tương ứng
 36
 Bài tập 2
◼ Giải thích các đầu ra (hoặc các lỗi nếu có) cho 
 chương trình thử nghiệm sau:
 37
 Bài tập 3
◼ Phân tích xây dựng các lớp như mô tả sau:
 ◼ Hàng điện máy <mã hàng, tên hàng, nhà sản 
 xuất, giá, thời gian bảo hành, điện áp, công 
 suất>
 ◼ Hàng sành sứ < mã hàng, tên hàng, nhà sản 
 xuất, giá, loại nguyên liệu>
 ◼ Hàng thực phẩm <mã hàng, tên hàng, nhà sản 
 xuất, giá, ngày sản xuất, ngày hết hạn dùng>
◼ Viết chương trình tạo mỗi loại một mặt hàng 
 cụ thể. Xuất thông tin về các mặt hàng này.
 38
 PhongBan NhanVien
 - tenPhongBan: String - tenNhanVien: String
 1 1..*
 - soNhanVien: int + LUONG_MAX: double
 + SO_NV_MAX: int + tinhLuong(): double
 + themNV(NhanVien): + inThongTin()
 boolean
 + xoaNV(): NhanVien
 NhanVienCoHuu NhanVienHopDong
 + tinhTongLuong(): double
 - luongCoBan: double - luongHopDong: double
 + inThongTin()
 - heSoLuong: double + tinhLuong(): double
 Bài tập 4 + tinhLuong(): double + inThongTin()
 + tangHeSoLuong(double): 
◼ Xây dựng các lớp như boolean
 biểu đồ ở hình bên + inThongTin()
 ◼ Sửa lớp NhanVien 
 thành lớp CanBoCoHuu
 ◼ Cho lớp CanBoCoHuu TruongPhong
 thừa kế lớp abstract - phuCap: double
 NhanVien
 - soNamDuongChuc: int
 ◼ Tính tổng lương của tất 
 cả nhân viên trong + tinhLuong(): double
 39
 + inThongTin()
 phòng ban
41

File đính kèm:

  • pdfbai_giang_lap_trinh_huong_doi_tuong_bai_8_da_hinh_tiep_theo.pdf