Bài giảng Lập trình hướng đối tượng - Bài 6: Một số kỹ thuật trong kế thừa
Bạn đang xem tài liệu "Bài giảng Lập trình hướng đối tượng - Bài 6: Một số kỹ thuật trong kế thừa", để 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:
- bai_giang_lap_trinh_huong_doi_tuong_bai_6_mot_so_ky_thuat_tr.pdf
Nội dung text: Bài giảng Lập trình hướng đối tượng - Bài 6: Một số kỹ thuật trong kế thừa
- 9/18/17 Mục tiêu của bài học Bộ môn Công nghệ Phần mềm n Trình bày nguyên lý định nghĩa lại trong kế Viện CNTT & TT thừa Trường Đại học Bách Khoa Hà Nội n Đơn kế thừa và đa kế thừa n Giao diện và lớp trừu tượng n Sử dụng các vấn đề trên với ngôn ngữ lập LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG trình Java. Bài 06. Một số kỹ thuật trong kế thừa 2 Nội dung Nội dung 1. Định nghĩa lại (Redefine/Overriding) 1. Định nghĩa lại 2. Lớp trừu tượng (Abstract class) (Redefine/Override) 3. Đơn kế thừa và đa kế thừa 2. Lớp trừu tượng (Abstract class) 4. Giao diện (Interface) 3. Đơn kế thừa và đa kế thừa 4. Giao diện (Interface) 3 4 1
- 9/18/17 1. Định nghĩa lại hay ghi đè 1. Định nghĩa lại hay ghi đè (2) n Lớp con có thể định nghĩa phương thức trùng n Phương thức ghi đè sẽ thay thế hoặc làm rõ tên với phương thức trong lớp cha: hơn cho phương thức cùng tên trong lớp cha n Nếu phương thức mới chỉ trùng tên và khác chữ n Đối tượng của lớp con sẽ hoạt động với ký (số lượng hay kiểu dữ liệu của đối số) phương thức mới phù hợp với nó à Chồng phương thức (Method Overloading) n Nếu phương thức mới hoàn toàn giống về giao diện (chữ ký) à Định nghĩa lại hoặc ghi đè (Method Redefine/Override) 5 6 class Shape { protected String name; class Square extends Shape { Shape(String n) { name = n; } private int side; public String getName() { return name; } public float calculateArea() { return 0.0f; } Square(String n, int s) { } super(n); class Circle extends Shape { side = s; private int radius; } Circle(String n, int r){ public float calculateArea() { super(n); radius = r; float area = (float) side * side; } return area; } public float calculateArea() { } float area = (float) (3.14 * radius * radius); return area; } } 7 8 2
- 9/18/17 Thêm lớp Triangle this và super class Triangle extends Shape { n this và super có thể sử dụng cho các phương private int base, height; thức/thuộc tính non-static và phương thức Triangle(String n, int b, int h) { khởi tạo super(n); n this: tìm kiếm phương thức/thuộc tính trong lớp hiện tại base = b; height = h; n super: tìm kiếm phương thức/thuộc tính trong lớp cha } trực tiếp public float calculateArea() { float area = 0.5f * base * height; n Từ khóa super cho phép tái sử dụng các return area; đoạn mã của lớp cha trong lớp con } } 9 10 package abc; Bài tập: Sửa lại cho kết quả là true public class Person { protected String name; class Value { protected int age; int i; public String getDetail() { } String s = name + "," + age; public class EqualsMethod2 { return s; public static void main(String[] args) { } Value v1 = new Value(); } Value v2 = new Value(); v1.i = v2.i = 100; import abc.Person; System.out.println(v1.equals(v2)); public class Employee extends Person { } double salary; } public String getDetail() { String s = super.getDetail() + "," + salary; return s; } } 11 12 3
- 9/18/17 Solution 1. Định nghĩa lại hay ghi đè (3) class Value { n Một số quy định int i; n Phương thức ghi đè trong lớp con phải public boolean equals(Object obj){ n Có danh sách tham số giống hệt phương thức kế thừa if (obj instanceof Value) trong lớp cha. return ((Value)obj).i == this.i; n Có cùng kiểu trả về với phương thức kế thừa trong lớp return false; cha } n Không được phép ghi đè: } n Các phương thức hằng (final) trong lớp cha n Các phương thức static trong lớp cha n (Các phương thức private trong lớp cha, lớp con không kế thừa được) 13 14 1. Định nghĩa lại hay ghi đè (3) Ví dụ class Parent { n Một số quy định (tiếp) public void doSomething() {} n Các chỉ định truy cập không giới hạn chặt hơn protected int doSomething2() { phương thức trong lớp cha return 0; cannot override: attempting to use } n Ví dụ, nếu ghi đè một phương thức protected, thì incompatible return type phương thức mới có thể là protected hoặc public, mà } không được là private. class Child extends Parent { protected void doSomething() {} protected void doSomething2() {} } cannot override: attempting to assign weaker access privileges; was public 15 16 4
- 9/18/17 Ví dụ Bài tập NhanVien #tenNhanVien:String class Parent { #heSoLuong:double #luongCoBan: double public void doSomething() {} +LUONG_MAX:double=20.000.000 n Sửa lại lớp NhanVien: private int doSomething2() { +tangLuong(double):boolean n 3 thuộc tính không hằng của return 0; NhanVien kế thừa lại cho lớp +tinhLuong():double } TruongPhong +inTTin() } n Viết mã nguồn của lớp TruongPhong như hình vẽ class Child extends Parent { n Viết các phương thức khởi tạo TruongPhong public void doSomething() {} cần thiết để khởi tạo các thuộc -phuCap:double private void doSomething2() {} tính của lớp TruongPhong -soNamDuongChuc:double } n Lương của trưởng phòng = +tinhLuong():double Lương Cơ bản * hệ số lương + +inTTin() 17 phụ cấp 18 Nội dung 2. Lớp trừu tượng (Abstract Class) 1. Định nghĩa lại (Redefine/Overiding) n Không thể thể hiện hóa (instantiate – tạo đối tượng của lớp) trực tiếp 2. Lớp trừu tượng (Abstract class) n Chưa đầy đủ, thường được sử dụng làm lớp 3. Đơn kế thừa và đa kế thừa cha. Lớp con kế thừa nó sẽ hoàn thiện nốt. 4. Giao diện (Interface) 19 20 5
- 9/18/17 abstract class Shape { 2. Lớp trừu tượng (2) protected String name; Shape(String n) { name = n; } public String getName() { return name; } n Để trở thành một lớp trừu tượng, cần: public abstract float calculateArea(); } n Khai báo với từ khóa abstract class Circle extends Shape { n Có thể chứa các phương thức trừu tượng (abstract private int radius; method - chỉ có chữ ký mà không có cài đặt cụ thể) Circle(String n, int r){ super(n); n public abstract float calculateArea(); radius = r; n Lớp con khi kế thừa phải cài đặt cụ thể cho các } phương thức trừu tượng của lớp cha à Phương thức trừu tượng không thể khai báo là final hoặc static. public float calculateArea() { float area = (float) (3.14 * radius * radius); n Nếu một lớp có một hay nhiều phương thức return area; trừu tượng thì nó phải là lớp trừu tượng } } Lớp con bắt buộc phải override tất cả các phương thức 21 abstract của lớp chả 22 Ví dụ lớp trừu tượng Ví dụ lớp trừu tượng (2) class Circle extends Action { import java.awt.Graphics; int radius; abstract class Action { public Circle(int x, int y, int r) { protected int x, y; super(x, y); radius = r; public void moveTo(Graphics g, } int x1, int y1) { public void draw(Graphics g) { erase(g); x = x1; y = y1; System out println("Draw circle at (" draw(g); + x + "," + y + ")"); } g.drawOval(x-radius, y-radius, 2*radius, 2*radius); } abstract public void erase(Graphics g); public void erase(Graphics g) { abstract public void draw(Graphics g); System.out.println("Erase circle at (" } + x + "," + y + ")"); // paint the circle with background color } 23 24 } 6
- 9/18/17 Nội dung Đa kế thừa và đơn kế thừa 1. Định nghĩa lại (Redefine/Overiding) n Đa kế thừa (Multiple Inheritance) n Một lớp có thể kế thừa nhiều lớp khác 2. Lớp trừu tượng (Abstract class) n C++ hỗ trợ đa kế thừa A B C 3. Đơn kế thừa và đa kế thừa n Đơn kế thừa (Single Inheritance) 4. Giao diện (Interface) n Một lớp chỉ được kế thừa từ một lớp khác D n Java chỉ hỗ trợ đơn kế thừa n à Đưa thêm khái niệm Giao diện (Interface) A E F 25 D 26 Vấn đề gặp phải trong Đa kế thừa Nội dung Name clashes on attributes or operations Repeated inheritance 1. Định nghĩa lại (Redefine/Overiding) 2. Lớp trừu tượng (Abstract class) SomeClass 3. Đơn kế thừa và đa kế thừa Animal FlyingThing + color + color 4. Giao diện (Interface) + getColor () + getColor () Animal FlyingThing + color + color + getColor () + getColor () Bird Bird Resolution of these problems is implementation-dependent. 28 7
- 9/18/17 Shape Action #x: int #name: String #y: int +getName():String 4. Giao diện-Interface +draw(Graphics) +calculateArea():float +moveTo(Graphics,int, int) +erase(Graphics) n Interface: đặc tả cho các bản cài đặt Circle -radius: float (implementation) khác nhau. +calculateArea():float +draw(Graphics) n Interface định nghĩa một "kiểu" chỉ chứa +erase(Graphics) > định nghĩa hằng và phương thức trừu tượng Shape Actable #name: String #x:int #y:int n Interface không cài đặt bất cứ một phương +getName():String +draw(Graphics) +moveTo(Graphics,int, int) +calculateArea():float +erase(Graphics) thức nào nhưng để lại cấu trúc thiết kế trên bất cứ lớp nào sử dụng nó. Circle -radius:float +calculateArea():float +draw(Graphics) +moveTo(Graphics,int,int) 29 30 +erase(Graphics) 4. Giao diện 4. Giao diện (2) • Cho phép một lớp có thể kế thừa (thực thi - n Để trở thành giao diện, cần implement) nhiều giao diện một lúc. n Sử dụng từ khóa interface để định nghĩa • Không thể thể hiện hóa (instantiate) trực tiếp n Chỉ được bao gồm: n Chữ ký các phương thức (method signature) n Các thuộc tính khai báo hằng (static & final) n Lớp thực thi giao diện n Hoặc là lớp trừu tượng (abstract class) n Hoặc là bắt buộc phải cài đặt chi tiết toàn bộ các phương thức trong giao diện nếu là lớp instance. 31 32 8
- 9/18/17 4. Giao diện (3) Ví dụ n Cú pháp thực thi trên Java: n [extends ] implements > Shape Actable #name: String #x:int #y:int n extends +getName():String +draw(Graphics) +moveTo(Graphics,int, int) +calculateArea():float n Ví dụ: +erase(Graphics) public interface DoiXung { } public interface DiChuyen { } Circle public class HinhVuong extends TuGiac -radius:float +calculateArea():float implements DoiXung, DiChuyen { +draw(Graphics) +moveTo(Graphics,int,int) +erase(Graphics) } 33 34 class Circle extends Shape implements Actable { import java.awt.Graphics; private int radius; abstract class Shape { public Circle(String n, int x, int y, int r){ protected String name; super(n, x, y); radius = r; } protected int x, y; public float calculateArea() { Shape(String n, int x, int y) { float area = (float) (3.14 * radius * radius); name = n; this.x = x; this.y = y; return area; } } public void draw(Graphics g) { public String getName() { System out println("Draw circle at (" return name; + x + “," + y + ")"); g.drawOval(x-radius,y-radius,2*radius,2*radius); } } public abstract float calculateArea(); public void moveTo(Graphics g, int x1, int y1){ } erase(g); x = x1; y = y1; draw(g); } interface Actable { public void erase(Graphics g) { public void draw(Graphics g); System out println(“Erase circle at (" public void moveTo(Graphics g, int x1, int y1); + x + “," + y + ")"); // paint the region with background color public void erase(Graphics g); } } } 35 36 9
- 9/18/17 Nhược điểm của Giao diện để giải quyết Lớp trừu trượng vs. Giao diện vấn đề Đa kế thừa n Không cung cấp một Lớp trừu trượng Giao diện cách tự nhiên cho các n Có thể có các phương n Chỉ có thể chứa chữ ký thức abstract, có thể phương thức (danh sách tình huống không có chứa các phương thức các phương thức) sự đụng độ về kế instance n Chỉ có thể chứa các thừa xảy ra n Có thể chứa các phương thức protected và static phương thức public mà không có mã nguồn n Có thể chứa các thuộc n Kế thừa là để Tái sử tính final và non-final n Chỉ có thể chứa các thuộc tính hằng dụng mã nguồn n Một lớp chỉ có thể kế thừa một lớp trừu tượng n Một lớp có thể thực thi nhưng Giao diện (kế thừa) nhiều giao diện không làm được điều này 37 38 10