Trường dữ liệu tĩnh public class TaiKhoan { public static int soLuongTK = 0; public static double laiSuat = 0.07; public double TienGui; public TaiKhoandouble sotien { TienGui = sotie
Trang 1Lập trình hướng đối tượng trong C#
(Object Oriented Programming in C#)
Trang 2Lớp và đối tượng
Class & Object
Trang 3 Lớp là 1 kiểu dữ liệu chung của một nhóm đối tượng nào đó Ví dụ: loài mèo, loài chó
Trang 4Tạo class
Ví dụ:
public class Cat
{ // Trường (field)
public string _name;
public double _weight;
Tương tự như struct, định
nghĩa class trong C#
cũng hoàn toàn tương tự
Trang 5Cat cat1, cat2;
Khi chưa gán giá trị cho đối tượng, nó sẽ mang giá trị null Để tạo mới 1 đối tượng, ta dùng từ khóa new:
cat1 = new Cat();
Có thể gán đối tượng này bằng đối tượng khác Bản chất phép gán này là gán tham chiếu của đối tượng này bằng tham chiếu của đối tượng kia, khi 1 đối tượng thay đổi (không thay đổi tham chiếu), đối tượng kia cũng thay đổi theo
cat1 = cat2;
Trang 6 Trong ví dụ trên, lớp Cat được cung cấp sẵn hàm khởi tạo Cat(), nếu ta khai báo 1 hàm khởi tạo thì hàm Cat()
Trang 7Cat cat2 = new Cat();
Ta có thể ghi đè lên hàm khởi tạo mặc định, mục đích
để đưa các dữ liệu về mặc định
public Cat(){
_name = “Mew”; _weight = 1;
}
Trang 8Từ khóa this
Từ khóa this dùng để truy cập thể hiện hiện tại của class, thường dùng để phân biệt tên thành viên và tên tham số khi có sự trùng nhau
public class Person
{ public string name;
public Person(string name) {
this.name = name;
}}
Trang 9public Cat( double weight) : this ( “Mew” , weight)
{ } }
Chúng ta có thể tạo ra 1
hàm khởi tạo tổng quát
rồi gọi nó trong các hàm
khởi tạo khác
Trang 10// Khi tạo đối tượng Cat cat1 = new Cat (); // name = “Mew”, weight = 1 Cat cat2 = new Cat ( “Tom” ); // name = “Tom”, weight = 1 Cat cat3 = new Cat (weight: 2); // name = “Mew”, weight
= 2
Tương tự như hàm, hàm
khởi tạo cũng có các chức
năng: giá trị tham số mặc
định, truyền giá trị theo
tên tham số
Trang 11Từ khóa
static
Trong class, ta có thể định nghĩa các thành viên tĩnh
Để gọi 1 thành viên tĩnh, ta phải gọi thông qua tên lớp chứ không gọi qua thể hiện của lớp đó
Trang 12Trường dữ
liệu tĩnh
public class TaiKhoan
{ public static int soLuongTK = 0;
public static double laiSuat = 0.07; public double TienGui;
public TaiKhoan(double sotien) {
TienGui = sotien;
soLuongTK++;
}}
Khi tất cả các thể hiện
của 1 lớp đều dùng chung
1 trường dữ liệu giống
Trang 13dữ liệu tĩnh
public class TaiKhoan {
public static int soLuongTK;
public static TaiKhoan() {
soLuongTK = 0;
} }
Chú ý : Trong các hàm tĩnh, ta chỉ có thể gọi các thành viên tĩnh
Ta cũng có thể định nghĩa 1 lớp là tĩnh, lớp này chỉ được phép
có các thành viên tĩnh
Trang 15Tính đóng gói
Encapsulation
Trang 16Các bổ từ
truy xuất
trong C#
Bổ từ truy xuất Giới hạn truy cập
public Phạm vi không giới hạn private Chỉ được sử dụng trong class khai báo nó protected Chỉ được sử dụng trong class khai báo nó
và các class dẫn xuất internal Chỉ được sử dụng trong các class cùng
khối assembly với class khai báo nó protected internal Chỉ được sử dụng trong class khai báo nó
và các class dẫn xuất thuộc cùng khối assembly
C# hỗ trợ 5 loại bổ từ truy xuất
Mặc định với class là internal Mặc định với các thành viên bên trong class là private
Trang 17private string name;
public void setName(string s)
{ name = s;
} public string getName() {
return name;
} }
Giống như C++ và Java,
name = s;
} string Humans::getName(void){
return name;
}
Trang 18public class Humans {
private string name;
// Thuộc tính (property) public string Name
{ get { return name; } set { name = value ; } }
}
Trang 19a.Name = “Linh” ; Console WriteLine( “His name is {0}” , a.Name); Sau khi khai báo thuộc tính, ta có thể sử dụng trực tiếp thuộc tính thay vì các hàm get và set
Trang 20Thuộc tính
Thuộc tính chỉ đọc và chỉ ghi
Nếu ta chỉ viết phương thức get (hoặc set) cho thuộc tính thì thuộc tính đó sẽ là thuộc tính chỉ đọc (hoặc chỉ ghi)
Ngoài ra, C# còn cho phép sử dụng các bổ từ trước các phương thức get, set để giới hạn truy cập đến thuộc tính
Thuộc tính tĩnh
Cách sử dụng giống như trường tĩnh
Các hàm get, set cũng chỉ được gọi các thành viên tĩnh trong class
Trang 21public string name;
public string Name {
get { return name; } set
{
if ( value Length > 15) Console WriteLine( “Name must be less than 16 characters!” );
else name = value ; }
} }
Trang 22Thuộc tính
tự động
Nếu 2 hàm get, set của thuộc tính có dạng đơn giản là đọc và ghi giá trị của 1 trường, ta có thể viết gọn lại thành
public class Pokemon
{ public string Name { get; set; } public int ID { get; set; }
public int Level { get; set; }}
C# sẽ tự tạo 1 trường private giống như trường name bên trên
Trang 24Trường
hằng
Trường là hằng số: phải gán giá trị tại câu lệnh khai báo public const double PI = 3.14;
Trường chỉ đọc (read-only): chỉ được thay đổi giá trị 1 lần ở hàm khởi tạo
Trường tĩnh chỉ đọc: chỉ được thay đổi duy nhất 1 lần ở hàm khởi tạo tĩnh
// class number
public readonly int max;
public static readonly int min;
public Number() {
max = 100;
} public static Number() {
min = 0;
}
Trang 25}
Trang 26Tính kế thừa
Inheritance
Trang 27Cơ bản về
kế thừa
Kế thừa từ 1 lớp: dùng dấu hai chấm:
public class Student : Humans
{ public string School { get; set; }}
// hàm Main
Student a = new Student(){
Name = “Linh”, Age = 20,
School = “HUST”,};
Trang 28Cơ bản về
kế thừa
Từ khóa sealed sẽ đánh dấu 1 lớp không thể được dẫn xuất
Một vài lớp sealed có sẵn như: Math, String…
Kế thừa từ 1 sealed class sẽ dẫn đến lỗi
// Errorclass MyString : String
{}
Trang 29public class Humans {
public string Name { get ; set ; } public int Age { get ; set ; }
Trang 30public Student() {}
public Student(string name, int age, string
school, int grade) : base(name, age) {
School = school; Grade = grade;
}}
Trang 31sử dụng giao diện (Interface)
Từ khóa protected dùng để chia sẻ dữ liệu của lớp cha cho lớp con nhưng không chia sẻ cho các lớp bên
ngoài
protected int a;
Để ngắt chuỗi kế thừa, ta có thể dùng từ khóa sealed
public sealed class Child : Humans
{ }
Trang 32Tính đa hình
Polymorphism
Trang 33 Chỉ có các phương thức được đánh dấu là ảo (virtual) thì lớp con mới được phép ghi đè (override) lên
Ví dụ 1 class động vật
public class Animal
{ public virtual void Sound() {
Console.WriteLine(“Animal”);
}}
Trang 34Từ khóa
virtual và
override
Ta tạo thêm 2 class Cat và Dog dẫn xuất từ lớp Animal
public class Dog : Animal
{ public override void Sound() {
Console.WriteLine(“Woof woof”);
}}
public class Cat : Animal
{ public override void Sound() {
Console.WriteLine(“Meow meow”);
}}
Trang 35Animal[] a = new Animal[3];
a[0] = new Animal(); a[0].Sound(); a[1] = new Dog(); a[1].Sound();
a[2] = new Cat(); a[2].Sound();
}
Kết quảAnimalWoof woofMeow meow
Trang 36Console.WriteLine(“Woof woof”);
}}
Trang 37abstract public class Animal
Ta không thể tạo 1 thể hiện của lớp trừu tượng mà chỉ
kế thừa từ lớp đó
Trong lớp trừu tượng ta có thể tạo các phương thức trừu tượng, mọi lớp dẫn xuất từ lớp này sẽ phải
override tất cả các phương thức trừu tượng của nó
abstract public void Sound()
Trang 38public new void Sound(){};
public new string name;
Khi sử dụng đa hình, phương thức override thấp nhất trong chuỗi kế thừa sẽ được gọi thay vì phương thức new trong class
Trang 39Animal a = new Cat();
Đối tượng của lớp cơ sở muốn chuyển sang đối tượng của lớp dẫn xuất thì phải chuyển đổi tường minh, có thể có ngoại lệ nếu chuyển kiểu không phù hợp
Animal a = new Cat();
Cat b = (Cat)a;
Trang 40Toán tử as
và is
Toán tử as dùng để chuyển 1 đối tượng sang 1 kiểu dữ liệu khác, nếu chuyển không thành công thì sẽ trả lại giá trị null
Animal a = new Cat(), b = new Dog();
Cat cat1 = a as Cat; // cat1 = a
Cat cat2 = b as Cat; // cat2 = null
Toán tử is dùng để kiểm tra 1 đối tượng có chuyển được sang kiểu dữ liệu khác không, trả về true hoặc false tương ứng
Animal a = new Cat(), b = new Dog();
bool c1 = a is Dog; // c1 = falsebool c2 = b is Dog; // c2 = true