Bài giảng Lập trình hướng đối tượng - Bài 3: Đóng gói và xây dựng lớp, tạo và sử dụng đối tượng

pdf 17 trang Gia Huy 17/05/2022 4670
Bạn đang xem tài liệu "Bài giảng Lập trình hướng đối tượng - Bài 3: Đóng gói và xây dựng lớp, tạo và sử dụng đối tượng", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfbai_giang_lap_trinh_huong_doi_tuong_bai_3_dong_goi_va_xay_du.pdf

Nội dung text: Bài giảng Lập trình hướng đối tượng - Bài 3: Đóng gói và xây dựng lớp, tạo và sử dụng đối tượng

  1. 8/31/17 Mục tiêu bài học Bộ môn Công nghệ Phần mềm n Nêu được bản chất, vai trò của trừu tượng hóa Viện CNTT & TT n Giải thích về đóng gói và che giấu thông tin Trường Đại học Bách Khoa Hà Nội n Xây dựng lớp n Định nghĩa lớp, thực hiện ẩn LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG n Tạo các phương thức, các trường/thuộc tính n Tạo và sử dụng đối tượng Bài 03. Đóng gói và xây dựng lớp, n Phương thức khởi tạo tạo và sử dụng đối tượng n Khai báo và khởi tạo đối tượng n Sử dụng đối tượng 2 Nội dung Nội dung 1. Trừu trượng hóa dữ liệu 1. Trừu trượng hóa dữ liệu 2. Đóng gói và xây dựng lớp 2. Đóng gói và xây dựng lớp 3. Tạo và sử dụng đối tượng 3. Tạo và sử dụng đối tượng 3 4 1
  2. 8/31/17 1.1. Trừu tượng hóa 1.1. Trừu tượng hóa (2) n Giảm thiểu và tinh lọc các chi tiết nhằm tập n Trừu tượng hóa điều khiển: Sử dụng các trung vào một số khái niệm/vấn đề quan tâm chương trình con (subprogram) và các luồng điều khiển (control flow) tại một thời điểm. n Ví dụ: a := (1 + 2) * 5 n “abstraction – a concept or idea not associated n Nếu không có trừu tượng hóa điều khiển, LTV phải chỉ ra with any specific instance”. tất cả các thanh ghi, các bước tính toán mức nhị phân n Ví dụ: Các định nghĩa toán học n Trừu tượng hóa dữ liệu: Xử lý dữ liệu theo các cách khác nhau n 2 loại trừu tượng hóa n Ví dụ: Kiểu dữ liệu n Trừu tượng hóa điều khiển (control abstraction) n Sự tách biệt rõ ràng giữa các đặc tính trừu tượng của kiểu dữ liệu và các chi tiết thực thi cụ thể của kiểu dữ liệu đó. n Trừu tượng hóa dữ liệu (data abstraction) 1.2. Trừu tượng hóa dữ liệu trong OOP n Đối tượng trong thực tế phức tạp n Cần đơn giản hóa, bỏ qua những chi tiết không cần thiết n Chỉ “trích rút” lấy những thông tin liên quan, thông tin quan tâm, quan trọng với bài toán 7 8 2
  3. 8/31/17 1.2. Trừu tượng hóa dữ liệu (2) n Trừu tượng hóa là một cách nhìn hoặc cách biểu diễn một thực thể chỉ bao gồm unclassified các thuộc tính liên quan "things" trong một ngữ cảnh nào đó. n Tập hợp các thể hiện của các thực thể thành các nhóm có chung các thuộc tính gọi là Lớp (class). 9 11 n organisms, n organisms, mammals, mammals, humans dangerous mammals 12 13 3
  4. 8/31/17 1.3. Lớp vs. Đối tượng Biểu diễn lớp trong UML u n Lớp là mô hình khái Đối tượng là sự vật thật, n Lớp (class) được biểu diễn bằng 1 hình chữ là thực thể thực sự niệm, mô tả các thực nhật với 3 thành phần: thể u Đối tượng là một thể Professor hiện (instance) của một - name n Lớp như một bản - employeeID : UniqueId n lớp, dữ liệu của các đối Tên lớp - hireDate mẫu, định nghĩa các tượng khác nhau là khác - status thuộc tính và phương nhau - discipline - maxLoad thức chung của các n Cấu trúc (thuộc tính) đối tượng u Mỗi đối tượng có một + submitFinalGrade() lớp xác định dữ liệu và + acceptCourseOffering() + setMaxLoad() hành vi của nó. n Hành vi (thao tác) + takeSabbatical() n Một lớp là sự trừu + teachClass() tượng hóa của một tập các đối tượng 14 Thuộc tính (attribute) là gì? Lớp và đối tượng trong UML Class n Một thuộc tính là một đặc tính được đặt tên :Student của một lớp mô tả khoảng giá trị mà các thể - name = “M. Modano” - address = “123 Main St.” hiện của đặc tính đó có thể chứa. Student - studentID = 9 - name n Một lớp có thể không có thuộc tính nào hoặc có số lượng - dateOfBirth = “03/10/1967” thuộc tính bất kỳ. - address - studentID Objects - dateOfBirth Student sv2:Student - name - name = “D. Hatcher” - address Attributes - address = “456 Oak Ln.” - studentID - studentID = 2 - dateOfBirth - dateOfBirth = “12/11/1969” 4
  5. 8/31/17 Nội dung 2.1. Đóng gói (Encapsulation) n Một đối tượng có hai khung nhìn: 1. Trừu trượng hóa dữ liệu n Bên trong: Chi tiết về các thuộc tính và các 2. Đóng gói và xây dựng lớp phương thức của lớp tương ứng với đối tượng 3. Tạo và sử dụng đối tượng n Bên ngoài: Các dịch vụ mà một đối tượng có thể cung cấp và cách đối tượng đó tương tác với phần còn lại của hệ thống Client Methods Data 18 19 2.1. Đóng gói (2) 2.1. Đóng gói (3) n Dữ liệu/thuộc tính và hành vi/phương thức n Một đối tượng là một thực thể được đóng gói, cung được đóng gói trong một lớp à cấp tập các dịch vụ nhất định Encapsulation n Một đối tượng được đóng gói có thể được xem như một hộp đen – các công việc bên trong là ẩn so với client BankAccount Dù thay đổi thiết kế/mã nguồn bên trong nhưng giao diện bên - owner: String ngoài không bị thay đổi theo - balance: double + debit(double): boolean +credit(double) Input Don’t know how Output it works, but it 20 works! 21 5
  6. 8/31/17 2.2. Xây dựng lớp 2.2. Xây dựng lớp (2) n Thông tin cần thiết để định nghĩa một n Lớp đóng gói các thành viên (member) lớp n Các trường/thuộc tính (field/attribute) n Tên (Name) n Tên lớp nên mô tả đối tượng trong n Các hàm/phương thức (function/method): thế giới thật n Tên lớp nên là số ít, ngắn gọn, và xác định rõ ràng cho sự trừu tượng hóa. String owner; Attribute declarations double balance; n Danh sách các phần tử dữ liệu BankAccount n Các phần dữ liệu cần lấy ra khi trừu tượng hóa - owner: String n Danh sách các thông điệp & thực - balance: double thi Method declarations n Các thông điệp mà đối tượng đó + debit(double): boolean có thể nhận được +credit(double) 22 23 2.2. Xây dựng lớp (3) 2.2.1. Khai báo lớp n Các lớp được nhóm lại thành package n Cú pháp khai báo: n Package bao gồm một tập hợp các lớp có quan hệ logic package tenpackage; với nhau, chi_dinh_truy_cap class TenLop { n Package được coi như các thư mục, là nơi tổ chức các // Than lop lớp, giúp xác định vị trí dễ dàng và sử dụng các lớp một } cách phù hợp. n chi_dinh_truy_cap: n Ví dụ: n public: Lớp có thể được truy cập từ bất cứ đâu, kể n Một số package có sẵn của Java: java.lang, javax.swing, cả bên ngoài package chứa lớp đó. java.io n Không có (mặc định): Lớp có thể được truy cập từ bên trong package chứa lớp đó. n Package có thể do ta tự đặt n Cách nhau bằng dấu “.” n Quy ước sử dụng ký tự thường để đặt tên package n Ví dụ: package oop.k52.cnpm; 24 25 6
  7. 8/31/17 Ví dụ - Khai báo lớp 2.2.2. Khai báo thành viên của lớp package oop.k52.cnpm; n Các thành viên của lớp cũng có chỉ định truy cập gần tương tự như lớp. public class Student { public Không có private } Cùng lớp Cùng gói Khác gói 27 28 2.2.2. Khai báo thành viên của lớp (2) Ví dụ: private n Các thành viên của lớp cũng có chỉ định class Student{ truy cập gần tương tự như lớp. private String name; public String getName() { public Không có private return this.name; } Cùng lớp Yes Yes Yes public void setName(String name) Cùng gói Yes Yes No { Khác gói Yes No No this.name = name; } } 29 30 7
  8. 8/31/17 Ví dụ: private (2) a. Thuộc tính class Student{ private String name; n Các thuộc tính phải được khai báo bên trong lớp public String getName() { return this.name; n Mỗi đối tượng có bản sao các thuộc tính của riêng nó } n Giá trị của một thuộc tính thuộc các đối tượng khác nhau là khác public void setName(String name) { nhau. this.name = name; } } class Manager{ Student private Student[] students; public initianize() - name { - address students = new Student[10]; students[0] = new Student(); - studentID //students[0].name = “Hung”; error - dateOfBirth students[0].setName(“Hung”); Nguyễn Thu Hương } } Nguyễn Hoàng Nam Hải Phòng Hà Nội 31 32 a. Thuộc tính (2) b. Phương thức n Thuộc tính có thể được khởi tạo khi khai báo n Xác định cách một đối tượng đáp ứng lại thông n Các giá trị mặc định sẽ được sử dụng nếu không được điệp khởi tạo. n Phương thức xác định các hoạt động của lớp n Bất kỳ phương thức nào cũng phải thuộc về một lớp nào đó BankAccount - owner: String - balance: double + debit(double): boolean +credit(double) boolean 33 34 8
  9. 8/31/17 * Chữ ký phương thức (signature) * Kiểu dữ liệu trả về n Mỗi phương thức phải có một chữ ký riêng n Khi phương thức trả về ít nhất một giá trị gồm: hoặc một đối tượng thì bắt buộc phải có câu n Tên phương thức lệnh return để trả điều khiển cho đối tượng n Số lượng các tham số và kiểu của chúng gọi phương thức. n Nếu phương thức không trả về 1 giá trị nào (void) và có thể không cần câu lệnh return n Có thể có nhiều lệnh return trong một phương thức; câu lệnh đầu tiên mà chương trình gặp sẽ được thực thi. 35 36 Ví dụ c. Thành viên hằng Public boolean checkOdd(int i) n Một thuộc tính/phương thức không thể thay { if (i %2 ==0) đổi giá trị/nội dung trong quá trình sử dụng. return true; n Cú pháp khai báo: else return false; chi_dinh_truy_cap final kieu_du_lieu } TEN_HANG = gia_tri; n Ví dụ: Public boolean checkOdd(int i) final double PI = 3.141592653589793; { public final int VAL_THREE = 39; return true; private final int[] A = { 1, 2, 3, 4, 5, 6 }; return false; //error } 37 9
  10. 8/31/17 package com.megabank.models; BankAccount public class BankAccount { 2.3. Che giấu dữ liệu (Data hiding) - owner: String private String owner; - balance: double private double balance; + debit(double): boolean n Dữ liệu được che giấu ở bên trong lớp và chỉ +credit(double) được truy cập và thay đổi ở các phương thức public boolean debit(double amount){ if (amount > balance) bên ngoài return false; n Tránh thay đổi trái phép hoặc làm sai lệch dữ else { liệu balance -= amount; return true; } } public void credit(double amount){ balance += amount; } 39 } 40 Cơ chế che giấu dữ liệu n Các thành viên dữ liệu n Chỉ có thể truy cập từ các phương thức bên trong lớp n Chỉ định truy cập là private để bảo vệ dữ liệu n Các đối tượng khác muốn truy nhập vào dữ liệu riêng tư này phải thông BankAccount qua các phương thức - owner: String public - balance: double + debit(double): boolean +credit(double) 41 43 10
  11. 8/31/17 Cơ chế che giấu dữ liệu (2) Bài tập: lớp BankAccount package demo; n à Vì dữ liệu là riêng tư Thông thường một public class BankAccount { lớp cung cấp các dịch vụ để truy cập và private String owner; chỉnh sửa các giá trị của dữ liệu private double balance; n Accessor (getter): Trả về giá trị hiện tại của một thuộc public String getOwner() { tính (dữ liệu) return owner; } n Mutator (setter): Thay đổi giá trị của một thuộc tính public void setOwner(String owner1) { n Thường là getX và setX, trong đó x là tên thuộc tính owner = owner1; } public double getBalance() { return balance; } public void setBalance(double balance1) { balance = balance1; } 44 } 45 Bài tập: lớp BankAccount Bài tập 1 NhanVien -tenNhanVien: String package demo; -luongCoBan: double n Viết mã nguồn cho lớp NhanVien public class BankAccount { -heSoLuong: double private String owner; như trong hình bên biết: private double balance; n Lương = Lương cơ bản * Hệ số +LUONG_MAX: double lương +tangLuong(double):boolean public String getOwner() { n Phương thức inTTin() hiển thị +tinhLuong(): double return owner; thông tin của đối tượng NhanVien } +inTTin() public void setOwner(String owner) { tương ứng. this.owner = owner; n Phương thức tangLuong(double) tăng hệ số lương hiện tại lên } một lượng bằng giá trị tham số double truyền vào. Nếu điều public double getBalance() { return balance; này làm cho lương của nhân viên > lương tối đa cho phép thì } không cho phép thay đổi, in ra thông báo và trả về false, public void setBalance(double balance) { ngược lại trả về true. this.balance = balance; n Viết các phương thức get và set cho các thuộc tính của lớp } } 46 NhanVien. 47 11
  12. 8/31/17 Nội dung 3.1. Khởi tạo dữ liệu n Dữ liệu cần được khởi tạo trước khi sử dụng 1. Trừu trượng hóa dữ liệu n Lỗi khởi tạo là một trong các lỗi phổ biến 2. Đóng gói và xây dựng lớp n Với kiểu dữ liệu đơn giản, sử dụng toán tử = n Với đối tượng à Cần dùng phương thức khởi tạo 3. Tạo và sử dụng đối tượng Student - name - address - studentID - dateOfBirth Nguyễn Thu Hương Nguyễn Hoàng Nam Hải Phòng 48 Hà Nội 49 Khởi tạo và hủy bỏ đối tượng 3.2. Phương thức khởi tạo n Mỗi đối tượng khi tồn tại và hoạt động được hệ điều hành n Là phương thức đặc biệt được gọi tự động cấp phát một vùng nhớ để lưu lại các giá trị của dữ liệu thành phần khi tạo ra đối tượng n Khi tạo ra đối tượng HĐH sẽ gán giá trị khởi tạo cho các dữ liệu thành phần n Mục đích chính: Khởi tạo cho các thuộc tính n Phải được thực hiện tự động trước khi người lập trình có của đối tượng thể tác động lên đối tượng Student n Sử dụng hàm/phương thức khởi tạo - name n Ngược lại khi kết thúc cần phải giải phóng hợp lý tất cả các - address bộ nhớ đã cấp phát cho đối tượng. - studentID n Java: JVM - dateOfBirth Nguyễn Thu Hương n C++: Hàm hủy (destructor) Nguyễn Hoàng Nam Hải Phòng Hà Nội 50 51 12
  13. 8/31/17 3.2. Phương thức khởi tạo (2) 3.2. Phương thức khởi tạo (3) n Mỗi lớp phải chứa ít nhất một constructor n Phương thức khởi tạo có thể dùng các chỉ n Có nhiệm vụ tạo ra một thể hiện mới của lớp định truy cập n n Tên của constructor trùng với tên của lớp public n private n Constructor không có kiểu dữ liệu trả về n Không có (mặc định – phạm vi package) n Ví dụ: n Một phương thức khởi tạo không thể dùng public BankAccount(String o, double b){ các từ khóa abstract, static, final, owner = o; native, synchronized. balance = b; } n Các phương thức khởi tạo không được xem như là thành viên của lớp. 52 53 3.2. Phương thức khởi tạo (4) 3.3. Khai báo và khởi tạo đối tượng n Phương khởi tạo mặc định (default n Đối tượng được tạo ra, thể hiện hóa constructor) (instantiate) từ một mẫu chung (lớp). n Là phương thức khởi tạo KHÔNG THAM SỐ n Các đối tượng phải được khai báo kiểu của public BankAccount(){ đối tượng trước khi sử dụng: owner = “noname”; balance = 100000; n Kiểu của đối tượng là lớp các đối tượng } n Ví dụ: n Nếu ta không viết một phương khởi tạo nào trong lớp n String strName; n JVM mới cung cấp phương thức khởi tạo mặc định n BankAccount acc; n Phương thức khởi tạo mặc định do JVM cung cấp có chỉ định truy cập giống như lớp của nó n Một lớp nên có phương thức khởi tạo mặc định 54 55 13
  14. 8/31/17 3.3. Khai báo và khởi tạo đối tượng (2) 3.3. Khai báo và khởi tạo đối tượng (3) n Đối tượng cần được khởi tạo trước khi sử n Có thể kết hợp vừa khai báo vào khởi tạo đối dụng tượng n Sử dụng toán tử = để gán n Sử dụng từ khóa new với constructor để khởi tạo đối n Cú pháp: tượng: Ten_lop ten_doi_tuong = new n Từ khóa new dùng để tạo ra một đối tượng mới n Tự động gọi phương thức khởi tạo tương ứng Pthuc_khoi_tao(ds_tham_so); n Một đối tượng được khởi tạo mặc định là null n Ví dụ: n Đối tượng được thao tác thông qua tham chiếu (~ con trỏ). BankAccount account = new BankAccount(); n Ví dụ: BankAccount acc1; acc1 = new BankAccount(); 56 57 3.3. Khai báo và khởi tạo đối tượng (4) 3.3. Khai báo và khởi tạo đối tượng (5) n Phương thức khởi tạo không có giá trị trả về, n Mảng các đối tượng được khai báo giống như nhưng khi sử dụng với từ khóa new trả về một tham mảng dữ liệu cơ bản chiếu đến đối tượng mới n Mảng các đối tượng được khởi tạo mặc định với giá trị null. n Ví dụ: Employee emp1 = new Employee(123456); Employee emp2; emp2 = emp1; Department dept[] = new Department[100]; Test[] t = {new Test(1),new Test(2)}; 58 59 14
  15. 8/31/17 Ví dụ 1 Ví dụ 2 class BankAccount{ public class BackAccount{ private String owner; private String owner; private double balance; private double balance; public BankAccount(){ } owner = ”noname”; public class Test{ } public static void main(String args[]){ } BankAccount acc1 = new BankAccount(); public class Test{ } public static void main(String args[]){ } BankAccount acc1 = new BankAccount(); } à Phương thức khởi tạo mặc định do Java cung cấp. } à Phương thức khởi tạo mặc định tự viết. 60 61 Ví dụ 3 3.4. Sử dụng đối tượng public class BankAccount { n private String owner; Đối tượng cung cấp các hoạt động phức tạp private double balance; hơn các kiểu dữ liệu nguyên thủy public BankAccount(String name){ setOwner(name); n Đối tượng đáp ứng lại các thông điệp } n Toán tử "." được sử dụng để gửi một thông điệp public void setOwner(String o){ owner = o; đến một đối tượng } } public class Test{ public static void main(String args[]){ BankAccount account1 = new BankAccount(); //Error BankAccount account2 = new BankAccount(“Hoang”); } 62 } 63 15
  16. 8/31/17 3.4. Sử dụng đối tượng (2) public class BankAccount{ private String owner; private double balance; n Để gọi thành viên (dữ liệu hoặc thuộc tính) public BankAccount(String name) { của lớp hoặc đối tượng, sử dụng toán tử “.” setOwner(name); } n Nếu gọi phương thức ngay trong lớp thì toán public void setOwner(String o){ owner = o; } public String getOwner(){ return owner; } tử “.” không cần thiết. } public class Test{ public static void main(String args[]){ BankAccount acc1 = new BankAccount(“”); BankAccount acc2 = new BankAccount(“Hong”); acc1.setOwner(“Hoa”); System.out.println(acc1.getOwner() + “ ”+ acc2.getOwner()); } 64 65 Bài tập Student.java n Viết lớp Student package example; public class Student { n name private int year; n year private String name; n 1 phương thức khởi dựng n Student(String name, int year) public Student(int year, String name) { n Tự tạo phương thức getter, setter cho đủ dùng this.year = year; this.name = name; n Đảm bảo đóng gói, che dấu dữ liệu } n Lớp Test n Nhập số phần tử cho mảng Student (trong 1 lớp học) public int getYear() { return year; n Nhập lần lượt các Student } n In ra danh sách tên Student trong lớp và hiển thị tổng số tuổi của các Student public String getName() { return name; } 66 } 67 16
  17. 8/31/17 Test.java Tự tham chiếu – this package example; import java.util.Scanner; public class Test { n Cho phép truy cập vào đối tượng hiện tại của public static void main(String[] args) { lớp. Scanner scanner = new Scanner(System.in); int N = scanner.nextInt(); n Quan trọng khi hàm/phương thức thành Student[] cls = new Student[N]; for (Student s: cls){ phần thao tác trên hai hay nhiều đối tượng. String name = scanner.next(); int year = scanner.nextInt(); n Xóa đi sự nhập nhằng giữa một biến cục bộ, s = new Student(year, name); } tham số với thành phần dữ liệu của lớp int total = 0; n Không dùng bên trong các khối lệnh static System.out.println("Danh sach lop: "); for (int i=0; i<N; ++i){ total += 2012-cls[i].getYear(); System.out.println(cls[i].getName()); } System.out.println("Tong so tuoi: " + total); } 68 69 } public class BankAccount{ Bài tập 3 NhanVien private String owner; -tenNhanVien: String private double balance; -luongCoBan: double public BankAccount() { } n Viết mã nguồn cho lớp NhanVien -heSoLuong: double public void setOwner(String owner){ (đã làm) this.owner = owner; +LUONG_MAX: double +tangLuong(double):boolean } n Viết phương thức khởi tạo với các public String getOwner(){ return owner; } tham số cần thiết để khởi tạo cho +tinhLuong(): double } các thuộc tính của lớp NhanVien. +inTTin() public class Test{ public static void main(String args[]){ BankAccount acc1 = new BankAccount(); n Viết lớp TestNV trong đó tạo ra 2 đối tượng của lớp BankAccount acc2 = new BankAccount(); NhanVien, thực hiện truyền thông điệp đến các đối tượng vừa acc1.setOwner(“Hoa”); tạo để hiển thị thông tin, hiển thị lương, tăng lương acc2.setOwner(“Hong”); System.out.println(acc1.getOwner() + “ ” + acc2.getOwner()); } 70 71 17