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

