Bài giảng Kĩ thuật lập trình - Chương 7: Quan hệ lớp

pdf 33 trang huongle 3740
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Kĩ thuật lập trình - Chương 7: Quan hệ lớp", để 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_ki_thuat_lap_trinh_chuong_7_quan_he_lop.pdf

Nội dung text: Bài giảng Kĩ thuật lập trình - Chương 7: Quan hệ lớp

  1. Kỹ thuật lập trình ng 1 0101010101010101100001 ươ 01010101010101011000010101010101010101100001 Chương 7: StateControllerQuan010101010010101010010101010101001010101001010101010100101010100101hệ lớp start() 101001100011001001001010100110001100100100101010011000110010010010 Ch stop() 110010110010001000001011001011001000100000101100101100100010000010 010101010101010110000101010101010101011000010101010101010101100001 N Ơ 010101010010101010010101010101001010101001010101010100101010100101 101001100011001001001010100110001100100100101010011000110010010010y = A*x + B*u; 110010110010001000001011001011001000100000101100101100100010000010x = C*x + d*u; LQGController010101010101010110000101010101010101011000010101010101010101100001 start() 010101010010101010010101010101001010101001010101010100101010100101 stop() 101001100011001001001010100110001100100100101010011000110010010010 110010110010001000001011001011001000100000101100101100100010000010 12/3/2007 2004, HOÀNG MINH S 2004, HOÀNG MINH ©
  2. Nộidung chương 7 7.1 Quan hệ lớp 7.2 Dẫnxuấtvàthừakế 7.3 Hàm ảo và nguyên lý ₫ahình/₫axạ 7.4 Ví dụ thư việnkhốichứcnăng N Ơ Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 2 © ©
  3. 7.1 Phân loạiquanhệ lớp ƒ Ví dụ minh họa: Các lớp biểu diễn các hình vẽ trong một chương trình ₫ồ họa —Rectangle Textbox — Square — Ellipse — Circle —Line — Polygon — Polyline —Textbox N Ơ —Group Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 3 © ©
  4. Biểu ₫ồ lớp (Unified Modeling Language) Quan hệ dẫnxuất N Ơ Quan hệ chứa Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 4 © ©
  5. Các dạng quan hệ lớp (meta model) Class relationship Generalization Association Dependency Aggregation N Ơ Composition Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 5 © ©
  6. 7.2 Dẫnxuấtvàthừakế ƒ Ví dụ xây dựng các lớp: Rectangle, Square và Textbox (sử dụng lớp Point) Lớpcơ sở Lớpdẫnxuất N Ơ Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 6 © ©
  7. Thựchiện trong C++: LớpPoint class Point { int X,Y; public: Point() : X(0), Y(0) {} Point(int x, int y): X(x), Y(y) {} int x() const { return X; } int y() const { return Y; } void move(int dx, int dy) { X += dx; Y += dy; } void operator*=(int r) { X *= r; Y *= r; N Ơ } }; Point operator-(const Point& P1, const Point& P2) { return Point(P2.x()-P1.x(),P2.y()-P1.y()); } Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 7 © ©
  8. Thựchiện trong C++: LớpRectangle #include #include #include "Point.h" typedef int Color; class Rectangle { Point TL, BR; Color LineColor, FillColor; int LineSize; public: Point getTL() const { return TL; } Point getBR() const { return BR; } void setTL(const Point& tl) { TL = tl; } N Ơ void setBR(const Point& br) { BR = br; } Color getLineColor() const { return LineColor; } void setLineColor(Color c) { LineColor = c; } int getLineSize() const { return LineSize; } void setLineSize(int s) { LineSize = s; } Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 8 © ©
  9. Rectangle(int x1=0, int y1=0, int x2=10, int y2=10) : TL(x1,y1), BR(x2,y2), LineColor(256),FillColor(0) {} Rectangle(const Point& tl, const Point& br, Color lc, Color fc) : TL(tl), BR(br), LineColor(lc), FillColor(fc) {} void draw() { std::cout 0 ? a : - a; } }; Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 9 © ©
  10. Thựchiện trong C++: LớpSquare #include "Rectangle.h" class Square : public Rectangle { public: Square(int x1=1, int y1=0, int a=10) : Rectangle(x1,y1,x1+a,y1+a) {} void resize(int r) { Rectangle::resize(r,r); } }; N Ơ Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 10 © ©
  11. Thựchiện trong C++: LớpTextbox #include "Rectangle.h" enum AlignType { Left, Right, Center}; class TextBox : public Rectangle { std::string Text; AlignType Align; public: TextBox(const string& text = "Text") : Text(text), Align (Left) {} TextBox(const Point& tl, const Point& br, Color lc, Color fc, const string& text): Rectangle(tl,br,lc,fc), Text(text), Align(Left) {} void draw() { N Ơ Rectangle::draw(); std::cout << Text << '\n'; } }; Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 11 © ©
  12. Chương trình minh họa #include "Rectangle.h" #include "Square.h" #include "TextBox.h" #include void main() { Rectangle rect(0,50,0,100); Square square(0,0,50); TextBox text("Hello"); rect.draw(); std::cout << "\t Rect area: " << rect.area(); square.draw(); N Ơ std::cout << "\t Square area: " << square.area(); text.draw(); std::cout << "\t Textbox area: " << text.area(); Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 12 © ©
  13. getch(); std::cout << "\n\nNow they are moved "; rect.move(10,20); square.move(10,20); text.move(10,20); getch(); std::cout << "\n\nNow they are resized "; rect.resize(2,2); square.resize(2); text.resize(2,2); getch(); } N Ơ Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 13 © ©
  14. Truy nhập thành viên ƒ Cáchàmthànhviêncủalớpdẫnxuấtcóthể truy nhậpthành viên "protected" ₫ịnh nghĩa ở lớpcơ sở, nhưng cũng không thể truy nhập các thành viên "private" ₫ịnh nghĩa ở lớpcơ sở Phảnvídụ: Rectangle rect(0,0,50,100); Square square(0,0,50); square.TL = 10; ƒ Lớpdẫnxuất ₫ược"thừakế" cấutrúcdữ liệu và các phép toán ₫ã ₫ược ₫ịnh nghĩatronglớpcơ sở, nhưng không nhấtthiếtcó quyềnsử dụng trựctiếp, mà phải qua các phép toán (các hàm công cộng hoặc hàm public) N ƒƠ Quyềntruynhậpcủa các thành viên "public" và "protected" ở lớpdẫnxuất ₫ượcgiữ nguyên trong lớpcơ sở Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 14 © ©
  15. Thuộc tính truy nhập kế thừa Thuộc tính kế thừa của lớp dẫn xuất Y Thuộc tính truy nhập của các thành viên lớp cơ sở X class Y: private X class Y: public X private Được kế thừa nhưng các thành viên của X không thể truy nhập trong Y Các thành viên của X Các thành viên của X protected sẽ trở thành các sẽ trở thành các thành thành viên private viên protected của Y của Y và có thể ₫ược và có thể truy nhập truy nhập trong Y trong Y N Thành viên của X sẽ Thành viên của X sẽ Ơ public trở thành thành viên trở thành thành viên private của Y và có public của Y và có thể thể truy nhập trong Y truy nhập trong Y Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 15 © ©
  16. Ví dụ void func2(int a, int b) { } int xy; class X { private: int x1; protected: int x2; public: int x3; int xy; X(int a, int b, int c) { x1 = a; x2 = b; x3 = xy = c; } N Ơ void func1(int, int); void func2(int, int); }; void X::func1(int i, int j) { } void X::func2(int k, int l) { } Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 16 © ©
  17. class Y:public X { private: int y1; public: int y2; int xy; Y(int d, int e, int f, int g, int h):X(d, e, f) { y1 = g; y2 = xy = h; } void func2(int, int); }; void Y::func2(int m, int n) { int a, b; x1 = m; //Error, x1 is private in the basic class X x2 = m; N Ơ x3 = m; xy = m; X::xy = m; ::xy = m; y1 = n; y2 = n; Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 17 © ©
  18. func1(a,b); OK, X::func1( ) X::func2(a,b); OK, X::func2( ) ::func2(a,b) } void f() { const int a = 12; Y objY(3, 4, 5, 6, 7); objY.x1 = a; //Error, x1 is private objY.x2 = a; //Error, x2 is protected objY.x3 = a; objY.xy = a; objY.y1 = a; //Error, y1 is private objY.y2 = a; objY.X::xy = a; objY.func1(a, a); objY.func2(a, a); N }Ơ Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 18 © ©
  19. Chuyển ₫ổikiểu ₫ốitượng ƒ Một ₫ối tượng hay con trỏ, hoặc tham chiếu ₫ối tượng kiểu lớp dẫn xuất sẽ có thể ₫ược chuyển ₫ổi kiểu tự ₫ộng về kiểu lớp cơ sở (nếu ₫ược kế thừa public) nhưng không ₫ảm bảo theo chiều ngược. Ví dụ: class X { X( ){ } }; class Y:public X { Y( ):X( ){ } }; X objX( ); Y objY( ); X* xp = &objX; //OK X* xp = &objY; //OK Y* yp = &objX; //Error Y* yp = (Y*)&objX; //OK, but not guaranteed! N ƒƠ Chuyển ₫ổi kiểu tự ₫ộng cho ₫ối tượng có kiểu lớp cơ sở sang kiểu lớp dẫn xuất sẽ không thể thực hiện vì không ₫ảm bảo ₫ược quyền truy nhập của các thành viên của lớp cơ sở, chắc chắn không ₫ược nếu kế thừa private. Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 19 © ©
  20. Chuyển ₫ổikiểu ₫ốitượng Ví dụ: class X { public: int x; }; class Y:private X { }; void f() { Y objY; X *xp; N Ơ xp = &objY; //Error xp = (X*) &objY; xp->x = 5; } Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 20 © ©
  21. 7.3 Hàm ảovàcơ chế₫a hình/₫axạ ƒ Trong quá trình liên kết, lời gọi các hàm và hàm thành viên thông thường ₫ược chuyển thành các lệnh nhảy tới ₫ịa chỉ cụ thể của mã thực hiện hàm => "liên kết tĩnh" ƒ Vấn ₫ề thực tế: —Các ₫ối tượng ₫a dạng, mặc dù giao diện giống nhau (phép toán giống nhau), nhưng cách thực hiện khác nhau => thực thi như thế nào? —Một chương trình ứng dụng chứa nhiều kiểu ₫ối tượng (₫ối tượng thuộc các lớp khác nhau, có thể có cùng kiểu cơ sở) => quản lý các ₫ối tượng như thế nào, trong một danh sách hay nhiều danh sách khác nhau? N Ơ Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 21 © ©
  22. Vấn ₫ề củacơ chế "liên kếttĩnh" ƒ Xem lạichương trình trước, hàm Rectangle::draw ₫ềuin ratên "Rectangle" => chưahợplýnêncần ₫ược ₫ịnh nghĩalại ở các lớp dẫnxuất void Square::draw() { std::cout << "\nSquare:\t[" << getTL() << getBR() << ']'; } void TextBox::draw() { std::cout << "\nTextbox:\t[" << getTL() << getBR() << ' ' << Text << ']'; } N Ơ Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 22 © ©
  23. Chương trình minh họa1 void main() { Rectangle rect(0,0,50,100); Square square(0,0,50); TextBox text("Hello"); rect.draw(); square.draw(); text.draw(); getch(); std::cout << "\n\nNow they are moved "; rect.move(10,20); square.move(10,20); text.move(10,20); getch(); std::cout << "\n\nNow they are resized "; N Ơ rect.resize(2,2); square.resize(2); text.resize(2,2); getch(); } Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 23 © ©
  24. Kếtquả: Như ý muốn? Rectangle: [(0,0)(50,100)] Square: [(0,0)(50,50)] Textbox: [(0,0)(10,10) Hello] Now they are moved Rectangle: [(10,20)(60,120)] Rectangle: [(10,20)(60,70)] Rectangle: [(10,20)(20,30)] Now they are resized Rectangle: [(20,40)(120,240)] Rectangle: [(20,40)(120,140)] Rectangle: [(20,40)(40,60)] N Ơ Gọi hàm draw() của Rectangle! Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 24 © ©
  25. Chương trình minh họa2 void main() { Quảnlýcác₫ốitượng const N =3; chung trong một danh sách Rectangle rect(0,0,50,100); nhờ cơ chế dẫnxuất! Square square(0,0,50); TextBox text("Hello"); Rectangle* shapes[N] = {&rect, &square, &text}; for (int i = 0; i draw(); getch(); } Kếtquả: các hàm thành viên củalớpdẫnxuất N Ơ cũng không ₫ượcgọi Rectangle: [(0,0)(50,100)] Rectangle: [(0,0)(50,50)] Rectangle: [(0,0)(10,10)] Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 25 © ©
  26. Giảipháp: Hàmảo class Rectangle { public: virtual void draw(); } N Ơ Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 26 © ©
  27. Kếtquả: Như mong muốn! Rectangle: [(0,0)(50,100)] Square: [(0,0)(50,50)] Textbox: [(0,0)(10,10) Hello] Chương trình 1 Now they are moved Rectangle: [(10,20)(60,120)] Square: [(10,20)(60,70)] Textbox: [(10,20)(20,30) Hello] Now they are resized Rectangle: [(20,40)(120,240)] Square: [(20,40)(120,140)] Textbox: [(20,40)(40,60) Hello] N Ơ Rectangle: [(0,0)(50,100)] Chương trình 2 Square: [(0,0)(50,50)] Textbox: [(0,0)(10,10) Hello] Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 27 © ©
  28. Hàm ảo class X { class Y:public X { public: public: virtual void f1() { } void f1() { } virtual void f2() { } void f2(int a) { } virtual void f3() { } char f3() { } void f4() { } void f4() { } }; }; void function() { Y y; N X* px = &y; //Typ-Convert Y* to X* Ơ px->f1(); //virtual function Y::f1() px->f2(); //virtual function X::f2() px->f3(); //virtual function X::f3() px->f4(); //function X::f4() } Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 28 © ©
  29. Ví dụ hàm ảo class X { protected: int x; public: X(int x_init) { x = x_init;} virtual void print(); }; class Y:public X { protected: int y; public: Y(int x_init, int y_init):X(x_init) {y = y_init;} void print(); }; class Z:public Y { protected: N Ơ int z; public: Z(int x_init, int y_init, int z_init):Y(x_init, y_init) {z = z_init;} void print(); }; Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 29 © ©
  30. class U:public Y { protected: int u; public: Z(int x_init, int y_init, int u_init):Y(x_init, y_init) {u = u_init;} void print(); }; void X::print() { cout << “Data of Class X: “ << x << endl; } void Y::print() { cout << “Data of Class X+Y: “ << x + y << endl; } void Z::print() {N Ơ cout << “Data of Class X+Y+Z: “ << x + y + z << endl; } void U::print() { cout << “Data of Class X+Y+U: “ << x + y + u << endl; } Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 30 © ©
  31. void print_data(X* px) { px->print(); } main() main() { { X* pobjX = new X(1); int x; Y* pobjY = new Y(10, 20); X *pobj[4]; Z* pobjZ = new Z(100, 200, 300); pobj[0] = new X(1); U* pobjU = new U(1000, 2000, 3000); pobj[1] = new Y(10, 20); print_data(pobjX); pobj[2] = new Z(100, 200, 300); print_data(pobjY); pobj[3] = new U(1000, 2000, print_data(pobjZ); 3000); print_data(pobjU); for(x = 0; x < 4; x++) delete pobjX; print_data(pobj[x]); delete pobjY; delete[4] pobj; delete pobjZ; } N delete pobjU; } Ơ Kết quả: Data of Class X: 1 Data of Class X+Y: 30 Data of Class X+Y+Z: 600 Data of Class X+Y+U: 6000 Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 31 © ©
  32. 7.4 Ví dụ thư viện khốichứcnăng ƒ Bài toán: —Xâydựng mộtthư việncáckhốichứcnăng phụcvụ tính toán và mô phỏng tương tự trong SIMULINK —Viếtchương trình minh họasử dụng ₫ơngiản ƒ Ví dụ mộtsơ₫ồkhối 0 Sum StaticGain Limiter Integrator N Ơ Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 32 © ©
  33. Biểu ₫ồ lớp N Ơ Ch2004, HOÀNG MINH S ương 7: Quan hệ lớp 2007 AC - HUT 33 © ©