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