Lập trình hướng đối tượng - Chương 5: Kế thừa - Huỳnh Quyết Thắng
Ngoài việc nhóm các đối tượng có cùng tập thuộc
tính/hành vi lại với nhau, con người thường nhóm các
đối tượng có cùng một số (chứ không phải tất cả) thuộc
tính/hành vi
Ví dụ, ta nhóm tất cả xe chạy bằng động cơ thành một
nhóm, rồi phân thành các nhóm nhỏ hơn tuỳ theo loại xe
(xe ca, xe tải,.)
Mỗi nhóm con là một lớp các đối tượng tương tự, nhưng
giữa tất cả các nhóm con có chung một số đặc điểm
Quan hệ giữa các nhóm con với nhóm lớn được gọi là
quan hệ “là”
– một cái xe ca “là” xe chạy bằng động cơ
– một cái xe tải “là” xe chạy bằng động cơ
– một cái xe máy “là” xe chạy bằng động cơ
M 66
Person, Student và Faculty
34
TS H.Q. Thắng - TS C.T. Dũng CNPM 67
Lớp Faculty
package university;
public class Faculty extends Person {
private int hireYear;
public Faculty( ) { super( ); hireYear = -1; }
public Faculty( String n, String id, int yr ) {
super(n, id);
hireYear = yr;
}
public Faculty( Faculty f ) {
this( f.getName( ), f.getIdNum( ), f.hireYear );
}
int getHireYear( ) { return hireYear; }
void setHireYear( int yr ) { hireYear = yr; }
public String toString( ) {
return super.toString( ) + " " + hireYear;
}
public boolean equals( Faculty f ) {
return super.equals( f ) && hireYear == f.hireYear;
}
}
TS H.Q. Thắng - TS C.T. Dũng CNPM 68
Định nghĩa lại phương thức
(overriding)
Xảy ra khi lớp kế thừa muốn thay đổi chức năng
của môt phương thức kế thừa từ lớp cha (super).
public class Person {
public String toString( ) { }
}
public class Student extends Person {
public String toString( ) { }
}
Student bob = new Student("Bob Goodstudent","123-45-
6789",2004,4.0 );
System.out.println( "Bob's info: " + bob.toString( ) );
Định nghĩa lại phương
thức của lớp cha
Lời gọi đến phương thức của lớp con
35
TS H.Q. Thắng - TS C.T. Dũng CNPM 69
Cấm định nghĩa lại với final
Đôi lúc ta muốn hạn chế việc định nghĩa lại vì
các lý do sau:
– Tính đúng đắn: Định nghĩa lại một phương thức trong
lớp dẫn xuất có thể làm sai lạc ý nghĩa của nó
– Tính hiệu quả: Cơ chế kết nối động không hiệu quả
về mặt thời gian bằng kết nối tĩnh. Nếu biết trước sẽ
không định nghĩa lại phương thức của lớp cơ sở thì
nên dùng từ khóa final đi với phương thức
public final String baseName () {
return “Person”;}
}
TS H.Q. Thắng - TS C.T. Dũng CNPM 70
Lớp cơ sở ship
public class Ship {
public double x=0.0, y=0.0, speed=1.0,
direction=0.0;
public String name;
public Ship(double x, double y, double speed, double
direction, String name) {
this.x = x;
this.y = y;
this.speed = speed;
this.direction = direction;
this.name = name;
}
public Ship(String name) {
this.name = name;
}
private double degreesToRadians(double degrees) {
return(degrees * Math.PI / 180.0);
}
...
36
TS H.Q. Thắng - TS C.T. Dũng CNPM 71
Lớp cơ sở ship
public void move() {
move(1);
}
public void move(int steps) {
double angle = degreesToRadians(direction);
x = x + (double)steps * speed * Math.cos(angle);
y = y + (double)steps * speed * Math.sin(angle);
}
public void printLocation() {
System.out.println(name + " is at ("+ x + "," + y
+ ").");
}
}
...
TS H.Q. Thắng - TS C.T. Dũng CNPM 72
Lớp dẫn xuất Speedboat
public class Speedboat extends Ship {
private String color = "red";
public Speedboat(String name) {
super(name);
setSpeed(20);
}
public Speedboat(double x, double y, double speed,
double direction, String name, String color) {
super(x, y, speed, direction, name);
setColor(color);
}
public void printLocation() {
System.out.print(getColor().toUpperCase() + " ");
super.printLocation();
}
...
37
TS H.Q. Thắng - TS C.T. Dũng CNPM 73
Lớp trừu tượng Point, ColorPoint
abstract class Point {
private int x, y;
public Point(int x, int y) { this.x = x; this.y = y; }
public void move(int dx, int dy) {
x += dx; y += dy;
plot();
}
public abstract void plot(); // abstract method has no implemention
}
abstract class ColoredPoint extends Point {
int color;
public ColoredPoint(int x, int y, int color) { super(x, y); this.color = color; }
}
class SimpleColoredPoint extends ColoredPoint {
public SimpleColoredPoint(int x, int y, int color) { super(x,y,color); }
public void plot() { ... } // code to plot a SimplePoint
}
TS H.Q. Thắng - TS C.T. Dũng CNPM 74
Ví dụ: Point, Circle, Cylinder
38
TS H.Q. Thắng - TS C.T. Dũng CNPM 75
Ví dụ: Point, Circle, Cylinder
TS H.Q. Thắng - TS C.T. Dũng CNPM 76
Định nghĩa lại: Cylinder
Cylinder phải định
nghĩa lại getArea()
thừa kế từ Circle
Dùng getArea() và
getCircumference()
của lớp cha
39
TS H.Q. Thắng - TS C.T. Dũng CNPM 77
TS H.Q. Thắng - TS C.T. Dũng CNPM 78
Upcasting – Tương tự C++
import java.util.*;
class Instrument {
public void play() {}
static void tune(Instrument i) {
// ...
i.play();
}
}
// Wind objects are instruments
// because they have the same
interface:
class Wind extends Instrument {
public static void main(String[] args)
{
Wind flute = new Wind();
Instrument.tune(flute); // Upcasting
}
}
Wind
Instrument
40
TS H.Q. Thắng - TS C.T. Dũng CNPM 79
Abstract Class
abstract class Point {
private int x, y;
public Point(int x, int y) { this.x = x; this.y = y; }
public void move(int dx, int dy) {
x += dx; y += dy;
plot();
}
public abstract void plot(); // phương thức trừu tượng
không có code thực hiện
}
TS H.Q. Thắng - TS C.T. Dũng CNPM 80
Abstract Class
abstract class ColoredPoint extends Point {
int color;
public ColoredPoint(int x, int y, int color) { super(x, y);
this.color = color; }
}
class SimpleColoredPoint extends ColoredPoint {
public SimpleColoredPoint(int x, int y, int color) {
super(x,y,color);
}
public void plot() { ... } // code to plot a SimplePoint
}
41
TS H.Q. Thắng - TS C.T. Dũng CNPM 81
Abstract Class
Lớp ColoredPoint không cài đặt mã cho
phương thức plot() do đó phải khai báo:
abstract
Chỉ có thể tạo ra đối tượng của lớp
SimpleColoredPoint.
Tuy nhiên có thể:
Point p = new SimpleColoredPoint(a, b, red);
p.plot();
TS H.Q. Thắng - TS C.T. Dũng CNPM 82
Thừa kế pha trộn
mix-in inheritance
Trong dạng thừa kế này, một "lớp" sẽ cung cấp
một số chức năng nhằm hòa trộn vào những lớp
khác.
Một lớp pha trộn thường sử dụng lại một số
chức năng định nghĩa từ lớp cung cấp nhưng lại
thừa kế từ một lớp khác.
Một số phần mềm dựa trên một số dịch vụ
(service) công dụng chung được cung cấp bởi
nhiều lớp. Thừa kế pha trộn là cách thức để tập
trung việc phát triển các dịch vụ này.
Trong Java thừa kế pha trộn được thể hiện qua
khái niệm Interface
42
TS H.Q. Thắng - TS C.T. Dũng CNPM 83
Giao diện (Interface)
Interface: đặc tả cho các bản cài đặt
(implementation) khác nhau.
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 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ó.
Một lớp cài đặt interface phải hoặc cài đặt
tất cả các phương thức hoặc khai báo là
lớp trừu tượng
TS H.Q. Thắng - TS C.T. Dũng CNPM 84
Interface
2DShape
Circle Rectangle
Square
3DShape
Sphere Cube
Drawable
43
TS H.Q. Thắng - TS C.T. Dũng CNPM 85
Interface
Kế thừa giao diện: Một interface có thể kế thừa
một (thậm chí nhiều) interface khác.
public interface Displayable extends Printable,
Drawable {
// Định nghĩa hằng và phương thức trừu tượng riêng
...
}
Cài đặt giao diện: Một lớp có thể cài đặt cùng lúc
nhiều giao diện khác nhau.
public class Circle extends 2DShape implements
Printable, Drawable {
...
}
TS H.Q. Thắng - TS C.T. Dũng CNPM 86
Interface
Tất cả các phương thức khai báo trong
Interface là ngầm định trừu tượng
Các thành phần dữ liệu là ngầm định:
static final (hằng)
Các thành phần (dữ liệu và phương thức)
là public
44
TS H.Q. Thắng - TS C.T. Dũng CNPM 87
Ví dụ
interface Shape2D {
double getArea();
}
interface Shape3D {
double getVolume();
}
class Point3D {
double x, y, z;
Point3D(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
}
Shape
Circle Sphere
Shape2D Shape3D
88
class Sphere extends Shape
implements Shape3D {
Point3D center;
double radius;
Sphere(Point3D center, double radius) {
this.center = center;
this.radius = radius;
}
public void display() {
System.out.println("Sphere");
}
public double getVolume() {
return 4 * Math.PI * radius * radius * radius / 3;
}
}
class Shapes {
public static void main(String args[]) {
Circle c = new Circle(new Point3D(0, 0, 0), new
Point3D(1, 0, 0));
c.display();
System.out.println(c.getArea());
Sphere s = new Sphere(new Point3D(0, 0, 0), 1);
s.display();
System.out.println(s.getVolume());
} }
abstract class Shape {
abstract void display();
}
class Circle extends Shape
implements Shape2D {
Point3D center, p; // p is an point on
circle
Circle(Point3D center, Point3D p) {
this.center = center;
this.p = p;
}
public void display() {
System.out.println("Circle");
}
public double getArea() {
double dx = center.x - p.x;
double dy = center.y - p.y;
double d = dx * dx + dy * dy;
double radius = Math.sqrt(d);
return Math.PI * radius * radius;
}
}
Result :
Circle
3.141592653589793
Sphere
4.1887902047863905
45
TS H.Q. Thắng - TS C.T. Dũng CNPM 89
Lớp trừu tượng vs Giao diện
Lớp trừu tượng bên cạnh các phương thức
trừu tượng vẫn có các thành phần thông
thường (dữ liệu, phương thức). Chỉ có thể
thừa kế từ duy nhất một lớp trừu tượng.
Giao diện định nghĩa ra một tập các chữ
ký (dịch vụ, chức năng) trừu tượng mà
các lớp cài đặt phải thực hiện. Nó cho
phép định nghĩa lớp với nhiều hành vi
khác nhau tương ứng với các tình huống
khác nhau
TS H.Q. Thắng - TS C.T. Dũng CNPM 90
Câu hỏi
Nêu bản chất của nguyên lý kết tập
Nêu bản chất của nguyên lý kế thừa
Các đặc điểm của kế thừa
Những hàm nào không được phép kế thừa và tại
sao
Phân biệt sự giống nhau và khác nhau giữa kế
thừa và kết tập
Nêu nguyên lý và thứ tự thực hiện của hàm khởi
tạo trong kế thừa và kết tập
Khi nào sử dung kế thừa và kết tập
46
TS H.Q. Thắng - TS C.T. Dũng CNPM 91
Bài tập
Xây dựng chương trình quản lý điểm học sinh:
Các lớp cần có: các lớp Person, Student, Teacher,
Subject, BKClass
Xây dựng mô hình kiến trúc của bài toán thoả mãn các
yêu cầu sau:
Nhập được các thông số của học sinh, giáo viên dạy các
môn học và điểm cho các môn
Nhập danh sách một lớp BKclass theo quy đinh có 40
sinh viên
Thực hiện chương trình và vẽ sơ đồ mô tả kiến trúc của
lớp: quan hệ kết tập, quan hệ kế thừa, v.v
File đính kèm:
lap_trinh_huong_doi_tuong_chuong_5_ke_thua_huynh_quyet_thang.pdf

