Bài giảng Ngôn ngữ lập trình ứng dụng: Phần 2 – ĐH CNTT&TT
lượt xem 23
download
Nối tiếp nội dung phần 1, phần 2 của bài giảng Ngôn ngữ lập trình ứng dụng trình bày các nội dung chính như: Lập trình hướng đối tượng trong C#, Lập trình winform, lập trình cơ sở dữ liệu. Mời các bạn cùng tham khảo.
Bình luận(0) Đăng nhập để gửi bình luận!
Nội dung Text: Bài giảng Ngôn ngữ lập trình ứng dụng: Phần 2 – ĐH CNTT&TT
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Chương 3: Lập trình hướng đối tượng trong C# 3.1 Xây dựng lớp – Đối tượng 3.1.1 Định nghĩa lớp Trong thế giới thực, bạn thường thấy nhiều đối tượng riêng lẻ thuộc cùng một loại. Có thể có hàng nghìn chiếc xe đạp cùng tồn tại, tất cả chúng đều giống nhau về cách sản xuất và mẫu mã. Mỗi chiếc xe đạp đã được tạo ra từ một tập thiết kế chung, vì thế chúng giống nhau về thành phần cấu tạo. Trong thuật ngữ hướng đối tượng, chúng ta nói rằng chiếc xe đạp là một thể hiện của một lớp các đối tượng có tên gọi là xe đạp. Một lớp là một bản thiết kế mà từ đó các đối tượng cụ thể được tạo ra. Trong C#, mọi chuyện đều xảy ra trong một lớp. Như các ví dụ mà chúng ta đã tìm hiểu trước, các hàm đều được đưa vào trong một lớp, kể cả hàm đầu vào của chương trình (hàm Main()): public classTester { public static int Main() { //.... } } Để định nghĩa một kiểu dữ liệu mới hay một lớp đầu tiên phải khai báo rồi sau đó mới định nghĩa các thuộc tính và phương thức của kiểu dữ liệu đó. Khai báo một lớp bằng cách sử dụng từ khoá class. Cú pháp đầy đủ của khai báo một lớp như sau: [Mức độ truy cập] class [: Lớp cơ sở] { [Nội dung lớp có thể bao gồm một hoặc nhiều thuộc tính và phương thức] [Mức độ truy cập] ; [Mức độ truy cập] () { [Nội dung phương thức] } } Trong đó: 46 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Mức độ truy cập: Thông thường, mức độ truy cập (access-modifiers) của một lớp là public. Ngoài ra các thành phần của lớp cũng có mức độ truy cập riêng cho biết loại phương thức nào được phép truy cập đến nó, hay nói cách khác nó mô tả phạm vi mà thành phần đó được nhìn thấy. Thuộc tính Giới hạn truy cập public Không hạn chế. Những thành viên được đánh dấu public có thể được dùng bởi bất kì các phương thức của lớp bao gồm những lớp khác. private Thành viên trong một lớp A được đánh dấu là private thì chỉ được truy cập bởi các phương thức của lớp A. protected Thành viên trong lớp A được đánh dấu là protected thì chỉ được các phương thức bên trong lớp A và những phương thức dẫn xuất từ lớp A truy cập. internal Thành viên trong lớp A được đánh dấu là internal thì được truy cập bởi những phương thức của bất cứ lớp nào trong cùng khối hợp ngữ với A. protected internal Thành viên trong lớp A được đánh dấu là protected internal được truy cập bởi các phương thức của lớp A, các phương thức của lớp dẫn xuất của A, và bất cứ lớp nào trong cùng khối hợp ngữ của A. Định danh: Định danh lớp chính là tên của lớp do người xây dựng chương trình tạo ra. Các định danh cần phải được đặt tên theo đúng quy tắc (Chỉ có thể chứa kí tự số, chữ và “_”, phân biệt chữ hoa, chữ thường và không được bắt đầu bằng số). Lớp cơ sở: Lớp cơ sở là lớp mà đối tượng sẽ kế thừa để phát triển ta sẽ bàn sau. Thuộc tính (trường dữ liệu): là biến dữ liệu của lớp đối tượng. Ví dụ: public class nguoi { public int tuoi;//Khai báo thuộc tính tuổi cho lớp nguoi với kiểu int } Phương thức (Methods): là thành phần xử lý của lớp đối tượng. Khi khai báo và định nghĩa 1 phương thức cần xác định những thành phần sau đây: 47 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện - Kiểu trả về: một phương thức có thể trả về một kiểu dữ liệu có sẵn hoặc do người dùng định nghĩa hoặc không trả về gì cả (void). - Tên phương thức: một định danh tuân thủ nguyên tắc đặt tên. - Danh sách tham số: một phương thức có thể có tham số truyền vào hoặc không o Truyền tham số theo kiểu tham trị (mặc định): giá trị của các biến trước khi được truyền vào phương thức và sau khi ra khỏi phương thức không thay đổi. Ví dụ: //Khai báo phương thức int ttong (int a, int b) { a=a+5; b=b+1; return a+b; } //Gọi hàm truyền tham số int so1=5, so2=10, tong; tong=ttong(so1,so2); Quan sát ví dụ trên ta thấy ban đầu so1 có giá trị là 5, so2 có giá trị là 10 khi được truyền vào trong phương thức ta thấy so1 sẽ được cộng thêm 5 và so2 được cộng thêm 1. Nhưng sau khi gọi hàm xong giá trị của so1 vẫn là 5 và so2 vẫn là 10. o Truyền tham số theo kiểu tham chiếu với từ khóa ref và out : là kiểu truyền tham số vào phương thức mà trong phương thức có thay đổi giá trị của biến thì sau khi ra khỏi phương thức giá trị của biến sẽ thay đổi. Điều nay tỏ ra rất hữu ích khi ta muốn một phương thích trả về nhiều hơn một giá trị. Ví dụ: //Khai báo phương thức int ttong (ref int a, ref int b) { a=a+5; b=b+1; return a+b; } //Gọi hàm truyền tham số int so1=5, so2=10, tong; tong=ttong(so1,so2); 48 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Kết quả sau khi ra khỏi phương thức ttong so1 sẽ có giá trị bằng 10, và so2 có giá trị là 11. Từ khóa ref và out đều có thể được sử dụng trong trường hợp này, sự khác nhau cơ bản là nếu dùng out thì không cần khởi tạo các biến trước khi truyền vào phương thức. o Truyền tham số kiểu mảng với từ khóa params : điều này rất hữu ích khi ta muốn tạo ra một phương thức với số lượng tham số là một dãy số, với số lượng không có định, tùy thuộc vào lúc gọi phương thức. Ví dụ: //Khai báo phương thức public void DisplayVals( params int[] intVals) foreach (int i inintVals) { Console.WriteLine(“DisplayVals: {0}”, i); } //Gọi phương thức DisplayVals(1,2,6,5,4,7); DisplayVals(2,2,1,3,4,3,5,6,6,8,9); int[] mang = new int[5]{2,4,9,7,8}; DisplayVals(mang); - Phần thực thi của phương thức: nội dung phương thức tùy vào mục đích sử dụng của phương thức. Ví dụ. public class nguoi { public void hello()// Phương thức không có tham số, không trả về gì cả { Console.WriteLine(“Xin chao cac ban”); } public int tinhTuoi(int nam_sinh)// Phương thức có tham số và trả về kiểu int { int tuoi=2014-nam_sinh; return tuoi;//Với phương thức có giá trị trả về cần có câu lệnh return để xác định xem phương thức sẽ trả về cái gì. } } 3.1.2 Tạo đối tượng 49 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Các đối tượng là điểm cốt lõi để hiểu về công nghệ hướng đối tượng. Bây giờ hãy nhìn xung quanh và bạn sẽ thấy được rất nhiều ví dụ về đối tượng của thế giới thực: con chó, cái bàn, ti vi, xe đạp. Đối tượng trong thế giới thực có chung hai đặc điểm: Tất cả đều có trạng thái và hành vi. Chó có trạng thái (tên, màu sắc, loại, tình trạng đói hay no) và hành vi (sủa, tha đồ vật đến, vẫy đuôi). Xe đạp cũng có trạng thái (bánh răng, nhịp bàn đạp hiện tại, tốc độ hiện tại) và hành vi (thay đổi bánh răng, thay đổi nhịp bàn đạp, sử dụng phanh). Việc xác định trạng thái và hành vi của các đối tượng trong thế giới thực là một cách tuyệt vời để bắt đầu nghĩ đến các khái niệm của lập trình hướng đối tượng. Bây giờ ta hãy dành ra một vài phút để quan sát các đối tượng của thế giới thực xung quanh bạn. Đối với mỗi đối tượng mà bạn nhìn thấy, hãy tự đặt ra cho mình hai câu hỏi: “Đối tượng này có thể ở trong những trạng thái nào?” và “Đối tượng này có thể thưc hiện những hành vi nào?” Hãy chắc chắn rằng bạn đã ghi lại những quan sát của mình. Khi làm thế, bạn sẽ nhận thấy rằng các đối tượng trong thế giới thực có sự khác nhau về độ phức tạp; chiếc đèn bàn có thể chỉ có 2 trạng thái (đang bật và đang tắt) và hai hành vi (bật và tắt), nhưng chiếc radio có thể có thêm các trạng thái khác (đang bật, đang tắt, âm lượng hiện tại, kênh hiện tại) và hành vi (bật, tắt, tăng âm lượng, giảm âm lượng, tìm kiếm, dò kênh và điều chỉnh). Bạn cũng sẽ nhận thấy rằng một số đối tượng này có thể chứa các đối tượng khác. Những quan sát về thế giới thực này đều được chuyển vào trong thế giới của lập trình hướng đối tượng. Một đối tượng phần mềm. Về mặt khái niệm thì các đối tượng phần mềm cũng tương tự như các đối tượng trong thế giới thực: Nó cũng bao gồm các trạng thái và hành vi liên quan. Một đối tượng lưu trữ trạng thái của nó trong các trường (có thể được gọi là biến trong một số ngôn ngữ lập trình) và thể hiện các hành vi của mình ra bên ngoài thông qua các phương thức (có thể được gọi là hàm ở trong một số ngôn ngữ lập trình). Các phương thức thao tác trên các trạng thái bên trong của một đối tượng và được dùng như là cơ 50 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện chế chính cho sự giao tiếp giữa đối tượng với đối tượng. Việc ẩn đi trạng thái bên trong và bắt buộc tất các các tương tác đều phải được thực hiện thông qua các phương thức của một đối tượng được biết đến như là sự bao gói dữ liệu (data encapsulation) – một nguyên lý cơ bản của lập trình hướng đối tượng. Hãy lấy một chiếc xe đạp làm ví dụ: Chiếc xe đạp được mô hình hóa như là một đối tượng phần mềm. Bằng cách mô tả các trạng thái (tốc độ hiện tại, nhịp đạp hiện tại, bánh răng hiện tại) và cung cấp các phương thức để thay đổi các trạng thái đó, thì một đối tượng vẫn kiểm soát được cách thức mà thế giới bên ngoài được phép sử dụng nó. Ví dụ, nếu chiếc xe đạp chỉ có 6 bánh răng, một phương thức để thay đổi bánh răng có thể từ chối bất cứ giá trị nào nhỏ hơn 1 hoặc lớn hơn 6. Cú pháp tạo đối tượng = new (); Ví dụ: //Khai báo lớp human class human() { int namSinh; string ten; void chao() { Console.WriteLine(“Xin chao cac ban”); } } //Tạo một đối tượng thuộc lớp human human hm1=new human(); //Đối tượng hm1 sẽ có 2 thuộc tính là namSinh và ten cũng như phương Phương thức khởi tạo (Constructor) 51 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Constructor được định nghĩa trong quá trình khai báo class, nếu như không định nghĩa Constructor thì chương trình sẽ tự sinh Constructor mặc định không chứa đối số. Mục đích chính của Constructor là thiết lập các giá trị cho các thuộc tính sau khi khởi tạo các đối tượng. Constructor có thể có một, nhiều đối số hoặc không có đối số nào. Tên phương thức Constructor khi báo phải trùng (chính xác) tên với tên của class. Có thể tạo nhiều Constructor cho class nhưng các constructor phải khác nhau về đối số. Đây cũng là khái niệm overload trong lập trình hướng đối tượng, nghĩa là tạo nhiều hàm / phương thức cùng tên nhưng khác về đối số. Đối số khác nhau ở đây là số lượng đối số và thứ tự các đối số. Constructor không có đối số là constructor mặc định. Hiểu nôm na là phương thức khởi dựng sẽ là phương thức được thực hiện đầu tiên khi vừa tạo đối tượng. Ví dụ //Khai báo lớp class Library { private int ibooktypes; //Constructor public Library() // Hàm tạo không đối số. { ibooktypes = 7; } public Library(int value) // Hàm tạo có một đối số { ibooktypes = value; } } //Tạo đối tượng Library lb1 = new Library(); // Hàm tạo không đối số; Library lb2 = new Library(100); // Hàm tạo được truyền vào với giá trị là 100, và nó sẽ được gán vào ibooktypes = 100; Khởi tạo biến thành viên Các biến thành viên có thể được khởi tạo trực tiếp khi khai báo trong quá trình khởi tạo, thay vì phải thực hiện việc khởi tạo các biến trong bộ khởi dựng. Để thực hiện việc khởi tạo này rất đơn giản là việc sử dụng phép gán giá trị cho một biến: Ví dụ: 52 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện private int Giay = 30; // Khởitạo Việc khởi tạo biến thành viên sẽ rất có ý nghĩa, vì khi xác định giá trị khởi tạo như vậy thì biến sẽ không nhận giá trị mặc định mà trình biên dịch cung cấp. Khi đó nếu các biến này không được gán lại trong các phương thức khởi dựng thì nó sẽ có giá trị mà ta đã khởi tạo. Sử dụng từ khóa this Từ khóa this được dùng để tham chiếu đến thể hiện hiện hành của một đối tượng. Tham chiếu this này được xem là con trỏ ẩn đến tất các phương thức không có thuộc tính tĩnh trong một lớp. Mỗi phương thức có thể tham chiếu đến những phương thức khác và các biến thành viên thông qua tham chiếu this này. Ví dụ: //Khai báo lớp class Library { private int ibooktypes; //Constructor public Library() // Hàm tạo không đối số. { ibooktypes = 7; } public Library(int ibooktypes ) // Hàm tạo có một đối số { this.ibooktypes = ibooktypes; //Sử dụng từ khóa this để tham chiếu tới thành phần của lớp } } 3.1.3 Sử dụng các thành viên static Việc truy cập đến thành viên tĩnh phải thực hiện thông qua tên lớp (không được truy cập thành viên tĩnh thông qua đối tượng) theo cú pháp chung: TênLớp.TênThànhViênTĩnh - Sử dụng phương thức tĩnh Một phương thức static có phạm vi hoạt động giống như một phương thức toàn cục mà không cần tạo ra bất cứ một thể hiện nào của lớp cả. Toàn cục ở đây hiểu theo nghĩa là toàn cục trong lớp. Để truy cập tới các thành viên tĩnh ta có cú pháp như sau: Tenlop.tenhamtinh ([danh sach tham so neu co]: Ví dụ diem.hien() là lời gọi đến phương thúc tĩnh có tên là hien() của lớp diem. - Sử dụng các thuộc tính tĩnh: 53 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Trong C# không hề có một biến nào có phạm vi hoạt động toàn cục như trong một số ngôn ngữ lập trình khác ( pascal, C, C++, Visual Basic …) việc sử dụng một biến với mục đích “toàn cục” trở nên là một điều không thể. Biến toàn cục trong các ngôn ngữ khác được hiểu là toàn cục trong ứng dụng nhưng đối với C# thì toàn cục theo nghĩa hiểu của nó là toàn cục trong một lớp và không có khái niệm toàn cục trong toàn bộ chương trình. Nếu ta khai báo một biến thành viên tĩnh của lớp thì biến thành viên tĩnh này có tầm vực hoạt động theo ý nghĩa toàn cục đó. Các biến thành viên tĩnh có hoạt động tích cực trong vai trò này. Cú pháp sử dụng thuộc tính tĩnh: Tenlop.tenThuocTinh; 3.1.4 Nạp chồng Thông thường khi lập trình thì các phương thức, các biến sẽ không được có tên trùng nhau. Tuy nhiên trong C# lại có cơ chế cho phép chúng ta đặt tên các phương thức trùng nhau nhưng phải khác nhau về thành phần tham số, điều này goi là nạp chồng phương thức. Ví dụ: void myMethod( int p1 ); void myMethod( float p1 ); void myMethod( int p1, int p2 ); void myMethod( int p1, string p2 ); trong ví dụ trên ta thấy có 4 phương thức trùng tên nhau tuy nhiên lại khác nhau về thành phần tham số (số lượng tham số, kiểu dữ liệu của tham số…) 3.2 Kế thừa - Đa hình 3.2.1 Sự kế thừa Là ngôn ngữ lập trình hướng đối tượng, nên C# cũng có đặc điểm về thừa kế (inheritance). Thừa kế là một trong những tính chất của lập trình hướng đối tượng. Nhờ sử dụng khái niệm thừa kế mà ta có thể tạo ra các lớp mới từ lớp cơ sở đã có. Khi sử dụng thừa kế, ta có thể tái sử dụng mã chương trình. Một số khái niệm cơ bản Lớp thừa kế gọi là lớp dẫn xuất (derived class) hay lớp con. Lớp cơ sở (base class) còn gọi là lớp cha. Lớp dẫn xuất thừa kế các thuộc tính (dữ liệu), các phương thức (method) của lớp cơ sở (base class). Cú pháp khai báo kế thừa [mức độ truy cập] class : { } 54 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Khi khai báo như trên tức là lớp con kế thừa lớp cha, lớp con sẽ được kế thừa các thuộc tính và phương thức của lớp cha tùy thuộc vào thuộc mức độ truy cập của các thành phần đó. Ví dụ: public class lopcha { int a=10; public void hello() { Console.WriteLine("Day la phuong thuc cua lop cha"); } } public class lopcon:lopcha//lopcon được khai báo kế thừa lopcha { //lớp con sẽ được sử dụng các thành phần của lớp cha } static void Main(string[] args) { lopcon lc = new lopcon(); lc.hello();//Vì phương thức hello của lớp cha khai báo public nên lớp con được sử dụng //lc.a = 10;//Vì thuộc tính a không khai báo mức độ truy cập (mặc định sẽ là private) nên lớp con không thể sử dụng được. Console.ReadKey(); } Kết quả: Ta thấy lớp con không có phương thức nào nhưng do kế thừa lớp cha nên nó sử dụng phương thức hello của lớp cha. Gọi phương thức khởi dựng của lớp cơ sở Vì lớp dẫn xuất không thể kế thừa phương thức khởi dựng của lớp cơ sở nên một lớp dẫn xuất phải thực thi phương thức khởi dựng riêng của mình. Nếu lớp cơ sở có một phương thức khởi dựng mặc định (tức là không có phương thức khởi dựng hoặc phương thức khởi dựng không có tham số) thì phương thức khởi dựng của lớp dẫn xuất được định nghĩa như cách thông thường. Nếu lớp cơ sở có phương thức khởi dựng có tham số thì lớp dẫn xuất cũng phải định nghĩa phương thức khởi dựng có tham số theo cú pháp sau: TênLớpCon(ThamSốLớpCon): TênLớpCơSở(ThamSốLớpCha) 55 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện { // Khởi tạo giá trị cho các thành phần của lớp dẫn xuất } Ví dụ: //Lop co so class Point2D { public int x,y; //phuong thuc tao lap cua lop co so co tham so public Point2D(int a, int b) { x = a; y = b; } public void Xuat2D() { Console.Write("({0}, {1})", x, y); } } //Lop dan xuat class Point3D:Point2D { public int z; //Vi phuong thuc tao lap cua lop co so co tham so nen phuong thuc tao lap cua lop dan xuat cung phai co tham so public Point3D(int a, int b, int c):base (a,b) { z = c; } public void Xuat3D() { Console.Write("({0}, {1}, {2})", x, y, z); } 56 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện } class PointApp { public static void Main() { Point2D p2 = new Point2D(1, 2); Console.Write("Toa do cua diem 2 D :"); p2.Xuat2D(); Console.WriteLine(); Point3D p3 = new Point3D(4,5,6); Console.Write("Toa do cua diem 3 D :"); p3.Xuat3D(); Console.ReadLine(); } } Trong ví dụ trên, vì phương thức khởi dựng của lớp Point2D có tham số: public Point2D(int a, int b ) nên khi lớp Point3D dẫn xuất từ lớp Point2D, phương thức khởi dựng của nó cần có ba tham số. Hai tham số đầu tiên dùng để khởi gán cho các biến x, y kế thừa từ lớp Point2D, tham số còn lại dùng để khởi gán cho biến thành viên z của lớp Point3D. Phương thức khởi dựng có nguyên mẫu như sau: public Point3D(int a, int b, int c):base (a, b) Phương thức khởi dựng này gọi phương thức khởi dựng của lớp cơ sở Point2D bằng cách đặt dấu “:” sau danh sách tham số và từ khoá base với các đối số tương ứng với phương thức khởi dựng của lớp cơ sở. Truy xuất tới các thành phần lớp cơ sở Trong lớp dẫn xuất để truy xuất tới các thành phần thuộc lớp cơ sở ta sử dụng từ khóa base. base.tenThanhPhan; Trong ví dụ trên lớp Point3 kế thừa lớp Point2 vậy trong lớp Point3 ta có thể gọi tới phương thức Xuat2D() trong lớp Point2 bằng câu lệnh: base.Xuat2D(); nếu muốn gọi tới các thuộc tính của lớp cơ sở ta cũng làm tương tự. Định nghĩa phiên bản mới trong lớp dẫn xuất Lớp dẫn xuất sẽ kế thừa tất cả các thành viên của lớp cơ sở, bao gồm tất cả các phương thức và biến thành viên của lớp cơ sở. Lớp dẫn xuất được tự do thực thi các 57 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện phiên bản của một phương thức của lớp cơ sở. Tuy nhiên trong một số trường hợp lớp dẫn xuất muốn tạo ra các phiên bản mới cho một số phương thức của lớp cơ sở cho phù hợp với mình. Lớp dẫn xuất có thể làm việc đó thông qua từ khóa new. Ví dụ: class XeHoi { protected int TocDo; protected string BienSo; protected string HangSX; public XeHoi(int td, string BS, string HSX) { TocDo = td; BienSo = BS; HangSX = HSX; } public void Xuat() { Console.Write("Xe: {0}, Bien so: {1}, Toc do: {2} kmh",HangSX, BienSo, TocDo); } } class XeCar: XeHoi { int SoHanhKhach; public XeCar(int td, string BS, string HSX, int SHK): base(td, BS, HSX) { SoHanhKhach = SHK; } public new void Xuat()//Lớp XeCar kế thừa lớp XeHoi và tiến hành định nghĩa một phiên bản mới cho phương thức Xuat() với từ khóa new { // Goi phuong thuc xuat cua lop co so thong qua tu khoa base base.Xuat(); Console.WriteLine(", {0} cho ngoi", SoHanhKhach); } } 3.2.2 Đa hình 58 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Hai đặc điểm mạnh nhất của kế thừa đó là khả năng sử dụng lại mã chương trình và đa hình (polymorphism). Đa hình là ý tưởng “sử dụng một giao diện chung cho nhiều phương thức khác nhau”, dựa trên phương thức ảo (virtual method) và cơ chế liên kết muộn (late binding). Nói cách khác, đây là cơ chế cho phép gởi một loại thông điệp tới nhiều đối tượng khác nhau mà mỗi đối tượng lại có cách xử lý riêng theo ngữ cảnh tương ứng của chúng. Tính đa hình (polymorphism) được hiểu như là khả năng sử dụng nhiều hình thức của một kiểu mà không cần phải quan tâm đến từng chi tiết. Ví dụ khi một tổng đài điện thoại gửi cho máy điện thoại của chúng ta một tín hiệu có cuộc gọi. Tổng đài không quan tâm đến điện thoại của ta là loại nào. Có thể ta đang dùng một điện thoại cũ dùng motor để rung chuông, hay là một điện thoại điện tử phát ra tiếng nhạc số. Hoàn toàn các thông tin về điện thoại của ta không có ý nghĩa gì với tổng đài, tổng đài chỉ biết một kiểu cơ bản là điện thoại mà thôi và diện thoại này sẽ biết cách báo chuông. Còn việc báo chuông như thế nào thì tổng đài không quan tâm. Tóm lại, tổng đài chỉ cần bảo điện thoại hãy làm điều gì đó để reng. Còn phần còn lại tức là cách thức reng là tùy thuộc vào từng loại điện thoại. Đây chính là tính đa hình. Để thực hiện được đa hình ta phải thực hiện các bước sau: 1. Lớp cơ sở đánh dấu phương thức ảo bằng từ khóa virtual hoặc abstract. 2. Các lớp dẫn xuất định nghĩa lại phương thức ảo này (đánh dấu bằng từ khóa override). 3. Vì tham chiếu thuộc lớp cơ sở có thể trỏ đến một đối tượng thuộc lớp dẫn xuất và có thể truy cập hàm ảo đã định nghĩa lại trong lớp dẫn xuất nên khi thực thi chương trình, tùy đối tượng được tham chiếu này trỏ tới mà phương thức tương ứng được gọi thực hiện. Nếu tham chiếu này trỏ tới đối tượng thuộc lớp cơ sở thì phương thức ảo của lớp cơ sở được thực hiện. Nếu tham chiếu này trỏ tới đối tượng thuộc lớp dẫn xuất thì phương thức ảo đã được lớp dẫn xuất định nghĩa lại được thực hiện. Ví dụ: using System; public class MyWindow { protected int top, left; //Toa do goc tren ben trai public MyWindow(int t, int l) { top = t; left = l; } // Phuong thuc ao 59 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện public virtual void DrawWindow( ) { Console.WriteLine("...dang ve Window tai toa do {0}, {1}", top, left); } } public class MyListBox : MyWindow { string listBoxContents; public MyListBox(int top,int left,string contents):base(top, left) { listBoxContents = contents; } public override void DrawWindow( ) { Console.WriteLine("...dang ve listbox {0} tai toa do: {1},{2}", listBoxContents, top, left); } } public class MyButton : MyWindow { public MyButton(int top,int left):base(top, left) {} public override voidDrawWindow( ) { Console.WriteLine ("...dang ve button tai toa do:{0},{1}", top, left); } } public class Tester { static void Main( ) { Random R = new Random(); int t; string s = ""; MyWindow[] winArray = new MyWindow[4]; for(int i = 0;i < 4; i++) { 60 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện t = R.Next() % 3; switch(t) { case 0: winArray[i] =new MyWindow( i * 2, i * 4); break; case 1: s = "thu " + (i+1).ToString(); winArray[i] = new MyListBox(i*3, i * 5, s); break; case 2: winArray[i] =new MyButton(i * 10, i * 20); break; } } for(int i = 0; i < 4; i++) { winArray[i].DrawWindow( ); } Console.ReadLine(); } } Trong ví dụ này ta xây dựng một lớp MyWindow có một phương thức ảo: public virtual void DrawWindow( ) Các lớp MyListBox, MyButton kế thừa từ lớp MyWindow và định nghĩa lại (override) phương thức DrawWindow() theo cú pháp: public override void DrawWindow( ) Sau đó trong hàm Main() ta khai báo và tạo một mảng các đối tượng MyWindow. Vì mỗi phần tử thuộc mảng này là một tham chiếu thuộc lớp MyWindow nên nó có thể trỏ tới bất kỳ một đối tượng nào thuộc các lớp kế thừa lớp MyWindow, chẳng hạn lớp MyListBox hay lớp MyButton. Vòng lặp for đầu tiên tạo ngẫu nhiên các đối tượng thuộc một trong các lớp MyWindow, MyListBox, MyButton, vì vậy, tại thời điểm biên dịch chương trình, trình biên dịch không biết đối tượng thứ i thuộc lớp nào và do đó chưa thể xác định được đoạn mã của phương thức DrawWindow() cần gọi. Tuy nhiên, tại thời điểm chạy chương trình, sau vòng lặp for đầu tiên, mỗi winArray[i] tham chiếu tới một loại đối tượng cụ thể nên trình thực thi sẽ tự động xác định được phương thức DrawWindow() cần gọi. (Như vậy ta đã sử dụng một giao diện chung là DrawWindow() cho nhiều phương thức khác nhau). 61 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Chú ý rằng nếu phương thức DrawWindow() trong các lớp MyListBox, MyButton,.. không có từ khóa override như cú pháp: public override void DrawWindow( ) thì trình biên dịch sẽ báo lỗi. 3.2.3 Lớp trừu tượng, lớp cô lập, giao diện a. Lớp trừu tượng Lớp trừu tượng (Abstract Class) là lớp dùng để định nghĩa những thuộc tính và hành vi chung của những lớp khác… Hay nói cách khác lớp trừu tượng là lớp dùng để khai báo thuộc tính và phương thức cho các lớp khác sử dụng. Lớp trừu tượng được dùng như một lớp cha (base class) của các lớp có cùng bản chất. Bản chất ở đây được hiểu là kiểu, loại, nhiệm vụ của class. Mỗi lớp dẫn xuất (derived class - lớp con) có thể thừa kế từ một lớp trừu tượng. Từ khóa abstract được dùng để định nghĩa một lớp trừu tượng. Những lớp được định nghĩa bằng cách dùng từ khóa abstract thì không cho phép khởi tạo đối tượng (instance) của lớp ấy. Lớp trừu tượng (abstract class) có thể coi như một quy tắc chung cho các lớp con (sub class) kế thừa từ nó. Khi các lớp kế thừa từ nó thì bắt buộc phải định nghĩa lại (override) tất cả các phương thức đã được khai báo abstract trong lớp trừu tượng. Cú pháp khai báo phương thức trừu tượng: abstract public void TênPhươngThức( ); Phương thức trừu tượng phải được đặt trong lớp trừu tượng. Lớp trừu tượng có từ khóa abstract đứng trước. Cú pháp khai báo lớp trừu tượng: abstract [thuộc tính truy cập] class {tên lớp} Ví dụ:Xây dựng lớp HinhHocvới phương thức tính chu vi, diện tích là phương thức trừu tượng hoặc phương thức ảo. Sau đó định nghĩa các lớp HinhChuNhat (hình chữ nhật), HinhTron (hình tròn) kế thừa từ lớp HinhHoc với các thành phần dữ liệu và phương thức tính chu vi, diện tích cụ thể của từng loại đối tượng. // lop hinh hoc (truu tuong) abstract public class HinhHoc { abstract public doubleDienTich(); virtual public doubleChuVi() { return 0;} } // lop hinh tron ke thua tu lop hinh hoc public classHinhTron : HinhHoc { double _bankinh; 62 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện public double BanKinh { get{ return_bankinh;} set{ _bankinh = value;} } public override doubleDienTich() { return _bankinh*_bankinh*3.1416; } public override doubleChuVi() { return _bankinh*2*3.1416; } } // lop hinh chu nhat ke thua tu lop hinh hoc public classHinhChuNhat : HinhHoc { double_dai, _rong; public doubleChieuDai { get{ return_dai;} set{ _dai = value;} } public doubleChieuRong { get{ return_rong;} set{ _rong = value;} } public override doubleDienTich(){ return _dai*_rong;} public override doubleChuVi(){return( _dai+_rong )*2;} } classTester { static voidMain(string[] args) { HinhHoc h; 63 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện HinhTron t = newHinhTron(); t.BanKinh = 5; Console.WriteLine("Thong tin ve hinh tron"); h = t; Console.WriteLine("Chu vi hinh tron: {0} ", h.ChuVi()); Console.WriteLine("Dien tich hinh tron:{0} ", h.DienTich()); HinhChuNhat n = newHinhChuNhat(); n.ChieuDai = 4; n.ChieuRong = 3; h = n; Console.WriteLine("Thong tin ve hinh chu nhat "); Console.WriteLine("Chu vi hinh chu nhat:{0}", h.ChuVi()); Console.WriteLine("Dien tich hinh chu nhat:{0}", h.DienTich()); Console.ReadLine(); } } Trong lớp HinhHoc ở ví dụ trên, ta khai báo phương thức tính diện tích là một phương thức trừu tượng (không có phần cài đặt mã của phương thức vì chưa biết đối tượng hình thuộc dạng nào nên không thểtính diện tích của nó). Như vậy, lớp HinhHoc là một lớp trừu tượng. abstract public double DienTich(); Trong lớp trên, ta cũng khai báo một phương thức tính chu vi là phương thức ảo với mục đích minh họa rằng trong lớp trừu tượng có thể có phương thức ảo (hoặc bất cứ một thành phần nào khác của một lớp). Vì đây là một phương thức không trừu tượng nên phải có phần cài đặt mã bên trong thân phương thức. Các lớp HinhChuNhat, HinhTron kế thừa từ lớp HinhHoc nên chúng buộc phải cài đặt lại phương thức tính diện tích. Trong hàm Main(), ta tạo ra đối tượng nthuộc lớp HinhChuNhat và đối tượng thuộc lớp HinhTron. Khi tham chiếu h thuộc lớp HinhHoc trỏ tới đối tượng (tương tự với đối tượng t), nó có thể gọi được phương thức tính diện tích của lớp HinhChuNhat (tương tự lớp HinhTron), điều này chứng tỏ phương thức trừu tượng cũng có thể dùng với mục đích đa hình. Chú ý: Phân biệt giữa từ khóa new và override • Từ khóa override dùng để định nghĩa lại (ghi đè) phương thức ảo (virtual) hoặc phương thức trừu tượng (abstract) của lớp cơ sở, nó được dùng với mục đích đa hình. 64 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
- Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện • Từ khóa new để che dấu thành viên của lớp cơ sở trùng tên với thành viên của lớp dẫn xuất. b. Lớp cô lập Ngược với các lớp trừu tượng là các lớp cô lập. Một lớp trừu tượng được thiết kế cho các lớp dẫn xuất và cung cấp các khuôn mẫu cho các lớp con theo sau. Trong khi một lớp cô lập thì không cho phép các lớp dẫn xuất từ nó. Để khai báo một lớp cô lập ta dùng từ khóa sealed đặt trước khai báo của lớp không cho phép dẫn xuất. Hầu hết các lớp thường được đánh dấu sealed nhằm ngăn chặn các tai nạn do sự kế thừa gây ra. Nếu khai báo của lớp Window trong ví dụ 5.3 được thay đổi từ khóa abstract bằng từ khóa sealed (cũng có thể loại bỏ từ khóa trong khai báo của phương thức rawWindow()). Chương trình sẽ bị lỗi khi biên dịch. Nếu chúng ta cố thử biên dịch chương trình thì sẽ nhận được lỗi từ trình biên dịch: ‘ListBox’ cannot inherit from sealed class ‘Window’ Đây chỉ là một lỗi trong số những lỗi như ta không thể tạo một phương thức thành viên protected trong một lớp khai báo là sealed. c. Giao diện Các subclass trong C# không thể kế thừa nhiều hơn một class. Chính bởi điều này C# không hỗ trợ đa kế thừa. Từ hạn chế này interface được giới thiệu. Một class trong C# thực thi được nhiều interface. Giao diện là một dạng của lớp trừu tượng được sử dụng với mục đích hỗ trợ tính đa hình. Trong giao diện không có bất cứ một cài đặt nào, chỉ có nguyên mẫu của các phương thức, chỉmục, thuộc tính mà một lớp khác khi kếthừa nó thì phải có cài đặt cụ thể cho các thành phần này (tức là lớp kế thừa giao diện tuyên bố rằng nó hỗ trợ các phương thức, thuộc tính, chỉ mục được khai báo trong giao diện). Khi một lớp kế thừa một giao diện ta nói rằng lớp đó thực thi (implement) giao diện. Ta dùng từ khóa interface để khai báo một giao diện với cú pháp sau: [MứcĐộTruyCập] interface TênGiaoDiện [:CácGiaoDiệnCơSở] { //Nội dung } MứcĐộTruyCập: public hoặc internal. CácGiaoDiệnCơSở: danh sách các interface khác mà nó kế thừa. Về mặt cú pháp, một giao diện giống như một lớp chỉ có phương thức trừu trượng. Nó có thể chứa khai báo của phương thức, thuộc tính, chỉ mục, sự kiện (events) nhưng không được chứa biến dữ liệu. Khi kế thừa một giao diện ta phải thực thi mọi phương thức, thuộc tính,… của giao diện. 65 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
CÓ THỂ BẠN MUỐN DOWNLOAD
-
Bài giảng Ngôn ngữ lập trình Java căn bản
115 p | 351 | 104
-
Bài giảng Ngôn ngữ lập trình C++: Chương 1 - Trần Minh Châu
17 p | 250 | 54
-
Bài giảng Ngôn ngữ lập trình C# - Nguyễn Hồng Phương
409 p | 214 | 41
-
Bài giảng Ngôn ngữ lập trình ứng dụng: Phần 1 – ĐH CNTT&TT
45 p | 112 | 13
-
Bài giảng Ngôn ngữ lập trình C và C++ (Phần 1: Ngôn ngữ lập trình C) - Chương 1: Ôn tập một số nội dung chính của NNLT C
31 p | 157 | 13
-
Bài giảng Ngôn ngữ lập trình bậc cao - Th.S Đoàn Thị Thu Huyền
44 p | 150 | 10
-
Bài giảng Ngôn ngữ lập trình C: Chương 1 - TS. Nguyễn Thị Hiền
12 p | 62 | 9
-
Bài giảng Ngôn ngữ lập trình - Nguyễn Văn Linh
109 p | 118 | 8
-
Bài giảng Ngôn ngữ lập trình C - Chương 1: Giới thiệu ngôn ngữ C
4 p | 104 | 8
-
Bài giảng Ngôn ngữ lập trình C và C++: Bài 1 - TS. Đỗ Đăng Khoa
53 p | 112 | 7
-
Bài giảng Ngôn ngữ lập trình C và C++ (Phần 2: Ngôn ngữ lập trình C++) - Chương 5: Các lớp nhập/xuất trong C++
19 p | 132 | 7
-
Bài giảng Ngôn ngữ lập trình C và C++ (Phần 2: Ngôn ngữ C++) - Chương 2: Giới thiệu về ngôn ngữ lập trình C++
49 p | 137 | 7
-
Bài giảng Ngôn ngữ lập trình C: Chương 1 - PhD. Nguyễn Thị Huyền
12 p | 55 | 7
-
Bài giảng Ngôn ngữ lập trình C và C++ (Phần 2: Ngôn ngữ lập trình C++) - Chương 3: Lớp và đối tượng
52 p | 112 | 5
-
Bài giảng Ngôn ngữ lập trình C và C++: Bài 4 - TS. Đỗ Đăng Khoa
40 p | 95 | 5
-
Bài giảng Ngôn ngữ lập trình C/C++ (Bài giảng tuần 1) – Nguyễn Hải Châu
7 p | 142 | 5
-
Bài giảng Ngôn ngữ lập trình C và C++ (Phần 2: Ngôn ngữ lập trình C++) - Chương 6: Mẫu (template)
27 p | 85 | 4
-
Bài giảng Ngôn ngữ lập trình: Bài 1 - Lý Anh Tuấn
30 p | 82 | 4
Chịu trách nhiệm nội dung:
Nguyễn Công Hà - Giám đốc Công ty TNHH TÀI LIỆU TRỰC TUYẾN VI NA
LIÊN HỆ
Địa chỉ: P402, 54A Nơ Trang Long, Phường 14, Q.Bình Thạnh, TP.HCM
Hotline: 093 303 0098
Email: support@tailieu.vn