Bài giảng Xây dựng lớp và giao diện - Nguyễn Duy Hải
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Xây dựng lớp và giao diện - Nguyễn Duy Hải", để 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:
- bai_giang_xay_dung_lop_va_giao_dien_nguyen_duy_hai.pdf
Nội dung text: Bài giảng Xây dựng lớp và giao diện - Nguyễn Duy Hải
- ThS. Nguyễn Duy Hải
- Nội dung Khai báo lớp Constructor & destructor Hàm thành viên Thuộc tính Đa hình trong C# Down cast – up cast Abstract class Sealed class, nested class Interface 2
- Tạo lớp trong C# Khai báo lớp [access modifier] class [: base class] { // class body } Access modifier: public, protected, internal, protected internal, private Nếu ko khai báo lớp cơ sở thì C# mặc định xem lớp cơ sở là object Lớp luôn là kiểu dữ liệu tham chiếu trong C# 3
- Khóa truy xuất cho class Một class chứa trong namespace chỉ có 2 khóa truy xuất Public: cho phép bên ngoài assembly truy xuất Internal: chỉ cho phép sử dụng bên trong assembly Assembly là tập mã đã được biên dịch sang .NET Một assembly chứa nội dung thực thi chương trình hay thư viện động Assembly có thể chứa trong nhiều file 4
- Các Lớp cóthành thể chứa cácphần phần sau của class Constructor và destructor Field và constant Method Property Indexer Event Chứa các kiểu khác (nested): class, struct, enumeration, interface và delegate 5
- Tạo đối tượng Tên lớp Tên đối tượng Khai báo HocSinh hs ; Trong thân lớp Giống như thuộc tính hs Trong thân phương thức Tương tự như biến Khởi tạo Tạo đối tượng Bằng lệnh new hs = new HocSinh(); hs 6
- Constructor Được gọi tự động khi tạo đối tượng Cùng tên với lớp Constructor ko tham số sẽ được tạo mặc định khi không có bất cứ constructor nào Cho phép overload constructor để tạo ra nhiều cách khởi tạo đối tượng Static constructor: ko tham số, ko access modifier, 7
- Constructor Constructor mặc định Không có tham số Khởi tạo thể hiện (đối tượng) khi chưa biết thông tin gì về nó Constructor sao chép Tham số vào là đối tượng cùng lớp Tạo ra obj như bản sao của obj đầu vào Constructor khác Có một hay nhiều tham số vào Tạo obj khi biết một số thông tin nào về nó 8
- class HocSinh Constructor{ // public HocSinh() { hoTen = “unknown"; Constructor mặc định namSinh = 1990; diemVan = diemToan = 0; } public HocSinh(HocSinh hs) { hoTen = hs.hoTen; namSinh = hs.namSinh; Constructor sao chép diemVan = hs.diemVan; diemToan = hs.diemToan; } public HocSinh(string ht) { Constructor khác hoTen = ht; } (tạo học sinh khi biết họ tên) } 9
- Khai báo private cho constructor sẽ ko cho phép tạo đối Constructortượng Ko thể tạo thể hiện/obj 10
- Destructor Thực hiện nhiệm vụ “clean” khi đối tượng bị hủy Trùng tên lớp và có dấu “~” phía trước Không có tham số và access modifier Mỗi lớp chỉ có 1 destructor class HocSinh { // ~HocSinh() { siSo ; } } 11
- Hàm, thủ tục khai báo trong class Method Hành vi giao tiếp với bên ngoài Static và non static public class CSharp { public CSharp ( ) { . . .} public static void StaticMethod( ) { . . .} public void NonStaticMethod( ) { . . .} } public class Tester() { CSharp cs = new CSharp( ); cs.NonStaticMethod( ); CSharp.StaticMethod( ); Truy cập qua thể hiện: cs } Truy cập qua tên lớp: CSharp 12
- Methodnamespace QuanLyHocSinh { class HocSinh Kiểu trả về Tên Đối số { // Phần khai báo static public bool KiemTraDiem( double diem ) { Phần định nghĩa bool kq = (0<= diem && diem <= diemToiDa); return kq; } } } Câu lệnh trả kết quả ra ngoài Các câu lệnh 13
- Methodnamespace QuanLyHocSinh { Không có class HocSinh đối số { Kiểu trả về // public void Xuat( ) { Console.WriteLine("Ho ten : "+hoTen); Console.WriteLine("Nam sinh : "+namSinh); Console.WriteLine("Diem van : "+diemVan); Console.WriteLine("Diem toan: "+diemToan); } } Các câu lệnh } 14
- Methodstatic void ThongBao( - overload double d ) { Console.WriteLine("Day la ThongBao(double)"); } static void ThongBao( int i ) { Console.WriteLine("Day la ThongBao(int)"); } static void ThongBao( int i1, int i2 ) { Console.WriteLine("Day la ThongBao(int, int)"); } static void ThongBao( HocSinh hs ) { Console.WriteLine("Day la ThongBao(HocSinh)"); } Các phương thức cùng có tên là ThongBao Các phương có tham số đầu vào khác nhau 15
- Method - overload ThongBao(40); Day la ThongBao(int) ThongBao(6.8); Day la ThongBao(double) ThongBao(new HocSinh()); Day la ThongBao(HocSinh) ThongBao(9,5); Day la ThongBao(int, int) 16
- Method – virtual method Tên lớp con Tên lớp cha class LopCon:LopCha class HocSinhVan: HocSinh { { // } } LopCha HocSinh LopCon HocSinhVan Tạo ra lớp HocSinhVan (học sinh chuyên văn) kế thừa từ lớp HocSinh 17
- Method – virtual method Phương thức ảo: Khai báo từ khoá virtual Cho phép lớp con có thể thay thế (override) Đây chính là thực thi tính đa hình Một phương thức của lớp cơ sở (lớp cha) có thể được thực thi khác nhau ở lớp dẫn xuất (lớp con) 18
- Method – virtual method Phương thức tính điểm trung bình của lớp HocSinh class HocSinh { // public virtual float TinhDiemTrungBinh() { float kq = (diemVan + diemToan) / 2; return kq; } } 19
- Method – virtual method Lớp HocSinhVan phủ quyết lại cách tính điểm trung bình của lớp HocSinh class HocSinhVan:HocSinh { // public override double TinhDiemTrungBinh() { double kq = (diemVan * 2 + diemToan) / 3; return kq; } } 20
- Method – virtual method HocSinh hs1 = new HocSinh(6,7); float d1 = hs1.TinhDiemTrungBinh(); HocSinhVan hs2 = new HocSinhVan(8,9); float d2 = hs2.TinhDiemTrungBinh(); hs1 = hs2; float d3 = hs1.TinhDiemTrungBinh(); 21
- VD Polymorphism Phủ quyết hàm Draw của Shape Hàm mới cùng tên Draw với hàm Draw của lớp cơ sở 22
- Polymorphism Shape s1 = new Shape(); Shape draw! s1.Draw(); Shape s2 = new Line(); Line draw! s2.Draw(); Shape s3 = new Circle(); Shape draw! s3.Draw(); Circle c = (Circle)s3; Circle draw! c.Draw(); 23
- Property Getter/Setter là các phương thức: Getter: Cho phép đối tượng cung cấp giá trị của thuộc tính ra bên ngoài Setter: Cho phép bên ngoài thay đổi giá trị của thuộc tính của đối tượng một cách có kiểm soát Property: Được bổ sung vào C# để thay thế cách dùng getter/setter truyền thống 24
- Property Đặt vấn đề Lớp HocSinh có thuộc tính diemVan (điểm văn) Giá trị của diemVan phải từ 0 tới 10 Bên ngoài có thể thấy và đổi giá trị của diemVan Chỉ cho phép đưa giá trị mới (diemMoi) vào diemVan nếu giá trị mới là hợp lệ (từ 0 tới 10) 25
- PropertyDùng getter/setter class HocSinh { protected double diemVan=0; // public double GetDiemVan() { return diemVan; } public void SetDiemVan( double diemMoi) { if (0<=diemMoi&&diemMoi<=10) diemVan=diemMoi; } } 26
- PropertyCài đặt bằng property class HocSinh { protected double diemVan=0; // public double DiemVan { get { return diemVan; } set { if (0 <= value && value <= 10) diemVan = value; } } } 27
- Property Sử dụng property class Tester { HocSinh hs1 = new HocSinh(“Nguyen Ha My Tien”); hs1.DiemVan = 5; HocSinh hs2 = new HocSinh(“Nguyen Ha Thanh Tung”); hs2.DiemVan = hs1.DiemVan; } set get 28
- Up-cast và down-cast Up-cast Ép kiểu từ handle con lên handle cha Luôn thành công Thực hiện tự động (implicit) Down-cast Ép kiểu từ handle cha xuống handle con Tùy trường hợp Phải chỉ định rõ (explicit) 29
- Ví dụ up-cast HocSinh HocSinh hs = new HocSinhVan(); HocSinhVan là lớp con của HocSinh HocSinhVan HocSinhVan hsv = new HocSinhVan(); Object o = hsv; HocSinhVan là lớp con (gián tiếp) của Object HinhHoc HinhHoc hh = new HinhVuong(); HinhVuong là lớp con của HinhChuNhat HinhChuNhat là lớp con của HinhHoc HinhChuNhat HinhVuong 30
- Ví dụ down-cast ((HinhVuong)hh).Width = 8; Được vì handle hh đang giữ một đối tượng HinhVuong ((HinhChuNhat)hh).Width = 8; Được vì handle hh đang giữ một đối tượng HinhVuong, mà lớp HinhChuNhat là cha của lớp HinhVuong ((HinhChuNhat)o).Width = 8; Không được vì handle o đang giữ một đối tượng HocSinhVan, mà lớp HocSinhVan và lớp HinhChuNhat không có quan hệ cha-con cần có user-defined cast 31
- Kiểm tra trước khi down-cast Để đảm bảo down-cast thành công, cần kiểm tra xem handle có phải đang giữ đối tượng phù hợp hay không Từ khóa: is if (o is HinhChuNhat) ((HinhChuNhat)o).Width = 8; else Console.WriteLine("o khong la HinhChuNhat"); 32
- Abstract class Lớp trừu tượng ko cho phép tạo thể hiện của lớp đó Sử dụng polymorphism đòi hỏi khai báo các phương thức là virtual hay abstract trong lớp cơ sở trừu tượng Override chúng trong lớp dẫn xuất (lớp con) Bất cứ lớp nào có một phương thức trừu tượng thì phải khai báo lớp là lớp trừu tượng 33
- Abstract class Abstract Method Virtual Method từ khoá: abstract từ khoá: virtual Chỉ có phần khai báo Có phần thực thi cho method và kết thúc là phương thức virtual ở lớp dấu “;”, Không cần có cơ sở phần thực thi cho phương thức abstract ở lớp abstract Bắt buộc lớp dẫn xuất Không bắt buộc lớp dẫn phải override lại xuất phải override từ khoá override trước từ khoá override trước phương thức ở lớp con phương thức ở lớp con 34
- Abstract class: Abstract class - example public abstract class AbstractClass { public AbstractClass() { } public abstract int AbstractMethod() ; public virtual int VirtualMethod() { return 0; } } 35
- Derived class: Abstract class - example public class DerivedClass : AbstractClass Bắt buộc phải có { public DerivedClass() { } public override int AbstractMethod() { return 0; } public override int VirtualMethod() { return base.VirtualMethod (); } } 36
- Sealed Còn gọi là Classlớp niêm phong, không cho phép lớp khác kế thừa nó, ngược với lớp abstract. using System; sealed class MyClass { public int x; public int y; } class MainClass { public static void Main() { MyClass mC = new MyClass(); mC.x = 110; mC.y = 150; Console.WriteLine("x = {0}, y = {1}", mC.x, mC.y); } } 37
- using System; Sử dụng sealed trước Sealedclass MyClass1 method { phương thức để ngăn ko public int x; public int y; cho lớp dẫn xuất override public virtual void Method() { Console.WriteLine("virtual method"); } } class MyClass : MyClass1 { public override sealed void Method() { Console.WriteLine("sealed method"); } } class MainClass { public static void Main() { MyClass1 mC = new MyClass(); mC.x = 110; mC.y = 150; Console.WriteLine("x = {0}, y = {1}", mC.x, mC.y); mC.Method(); } } 38
- Nested class Lớp đựơc khai báo bên trong thân của lớp khác gọi là: inner class hay nested class, lớp kia gọi là outer class Lớp nội có thể truy cập tất cả thành viên của lớp ngoài, kể cả private Lớp nội nằm trong lớp ngoài nên nó có thể là private với lớp ngoài Khi lớp nội khai báo là public thì có thể truy xuất thông qua tên của lớp ngoài: outer_class.inner_class 39
- public class Fraction Truy xuất được thành phần Nested{ class Private của lớp outer private int numerator; private int denominator; public Fraction(int numerator, int denominator) { this.numerator = numerator; this.denominator = denominator; } Lớp nested class public override string ToString() { string str = numerator.ToString() + "/" + denominator.ToString(); return s; } public class FractionArtist { public void Draw(Fraction f) { Console.WriteLine("Drawing the numerator {0}", f.numerator); Console.WriteLine("Drawing the denominator {0}", f.denominator); } } } 40
- Nested class class Tester { static void Main() { Fraction f1 = new Fraction(3, 4); Console.WriteLine("f1: {0}", f1.ToString()); Fraction.FractionArtist fa = new Fraction.FractionArtist(); fa.Draw(f1); } } Truy xuất lớp inner qua lớp outer, lớp outer tương tự như manespace 41
- Interface Interface quy định các chức năng nhưng không mô tả cụ thể chúng Phương thức trong interface Chỉ khai báo, không định nghĩa Không có từ khóa phạm vi, luôn là public Interface không thể chứa thuộc tính Từ khóa: interface Có thể xem interface như một bản hợp đồng, nếu lớp nào sử dụng (kế thừa) nó thì phải thực thi đầy đủ các mô tả (phương thức) trong hợp đồng (interface) 42
- Interface[access modifier] interface [: base interface list] Một interface có thể kế thừa từ nhiều interface khác Một lớp có thể kế thừa từ nhiều interface Phải định nghĩa tất cả phương thức mà các interface "cha" quy định Sự kế thừa interface phải đặt sau sự kế thừa lớp Các interface thường được đặt tên với tiền tố là “I” IFile, IComparable, IDisposable, IStorable, ICloneable 43
- Khai báo property Interfacepublic interface - IStudent example StudentID gồm hàm get ,set { int StudentID { get; Khai báo phương thức set; AddSubject } void AddSubject(string subjectName); } Phải định nghĩa {get,set} của StudentID và AddSubject ở lớp thực thi interface 44
- Interfacepublic class Student - : exampleIStudent Bắt buộc lớp student { phải định nghĩa property private int studentID = 0; Student và hàm AddSubject private ArrayList subjects = null; public Student() {} public int StudentID { get { return studentID; } set { studentID = value; } } public void AddSubject(string subjectName) { subjects.Add(subjectName); } } 45
- Xin cảm ơn! 47