Bai 1
Bai 1
Mục tiêu:
Nhắc lại về đối tượng và lớp, kế thừa, lớp trừu tượng, giao diện và đa hình trong
C#.NET.
1.1 Lớp và đối tượng
1.2 Kế thừa
1.3 Lớp trừu tượng và giao diện
1.4 Đa hình
1.1 Lớp và đối tượng
a. So sánh lớp và đối tượng
- Lớp: Một lớp bao gồm có các thuộc tính và phương thức. Để khai báo một lớp ta sử dụng từ khóa class với
cấu trúc sau đây:
[Thuộc tính truy cập] class <tên lớp>
{
Khai báo các thuộc tính của lớp
Khai báo các phương thức của lớp
}
Các thuộc tính truy cập gồm có các từ khóa sau đây: public, private, internal, protected,
internal protected.
+ internal: Các phương thức, các biến thành viên có thể được truy cập bởi tất cả những
phương thức của bất cứ lớp nào trong cùng một khối hợp ngữ assembly với lớp đó.
+ protected internal: Các biến thành viên được khai báo bằng từ khóa này trong một
lớp A bất kì có thể được truy xuất bởi các phương thức thuộc lớp A và các phương thức
của lớp dẫn xuất từ lớp A và bất cứ lớp nào trong cùng một khối hợp ngữ với lớp A.
- Khối hợp ngữ Assembly được hiểu là một khối chia xẻ và dùng lại trong CLR. Khối
hợp ngữ là tập hợp các tập tin vật lý được lưu trữ trong một thư mục bao gồm các tập tin
tài nguyên.
Các thuộc tính truy cập được áp dụng cho thuộc tính, phương thức của lớp và bản thân
lớp. Khi định nghĩa thuộc tính truy cập của lớp là internal, protected chỉ được định nghĩa
trong lớp lồng nhau mà thôi.
1.1 Lớp và đối tượng
- Lớp có thể lồng nhau:
class class1
{
// khai báo thuộc tính
// khai báo các phương thức
public class class2
{
// khai báo các thành phần dữ liệu
// khai báo các phương thức
}
}
}
1.1 Lớp và đối tượng
- Sử dụng các đối tượng của lớp:
+ Các thành phần của một lớp chỉ đuợc sử dụng khi có thể hiện của lớp, trừ trường hợp trong lớp có một hàm
khởi dựng là static.
+ Để khai báo một đối tượng của lớp ta dùng từ khóa new và khai báo nó theo cấu trúc sau:
<tên lớp> <tên đối tượng> = new <tên lớp> ([các giá trị khởi tạo nếu có])
+ Truy cập:
<tên đối tượng>. <tên phương thức> ([danh sách các đối số nếu có])
1.1 Lớp và đối tượng
Đối với các lớp lồng nhau, để truy cập đến những thuộc tính và phương thức của class lồng thì khi khai báo cần
chỉ ra lớp chứa đựng nó. Muốn sử dụng biến của lớp chứa thì các biến của lớp dùng để chứa phải khai báo là
static và phải khai báo đối tượng chứa nó.
class Pheptoan
{
int x, y;
static int x1, x2;
public void hien() {
Console.WriteLine("x={0},y={1}", x, y);
}
class tinhhieu {
int a, b;
public int hieu() {
return x - y;//loi ko truy cập được
return x1 - x2;//chỉ truy cập được đến thành phần static
}
}
static void Main(string[] args)
{
Pheptoan ob1=new Pheptoan();
Pheptoan.tinhhieu ob = new Pheptoan.tinhhieu();
tinhhieu ob2 = new tinhhieu();
ob1.hieu();// lỗi ko truy cập được vì ko hiểu rõ lớp bên trong
ob.hieu();//ok
ob2.hien();//lỗi ko truy cập được thanh phan của lớp chứa mình
}
}
b. Đóng gói dữ liệu thông qua các thuộc tính
- Đóng gói dữ liệu với thuộc tính thực chất là một quá trình ta lấy giá trị cho biến thành viên
và thiết lập giá trị đó cho biến để nó được truy cập thông qua phương thức của lớp mà
không qua đối tượng.
- Trong C# cung cấp khả năng khai báo hàm chung gọi là thuộc tính cho hàm get và set
(Code: Baitap1.cs)
1.2 Kế thừa
- Cú pháp:
<acess-specifier> class <base_class> { ... }
class <derived_class> : <base_class> { ... }
- Ví dụ:
public static void Main(string[] args) {
class Shape { //lớp base class HinhChuNhat :
//tao doi tuong HinhChuNhat
protected int chieu_rong; Shape {
HinhChuNhat hcn = new
protected int chieu_cao; public int
HinhChuNhat(); hcn.setChieuRong(5);
public void tinhDienTich() {
setChieuRong(int w) { hcn.setChieuCao(7);
return (chieu_cao *
chieu_rong = w; } // in dien tich cua doi tuong.
chieu_rong);
public void Console.WriteLine("Dien tich hinh chu
}
setChieuCao(int h) { nhat: {0}", hcn.tinhDienTich());
}
chieu_cao = h; } Console.ReadKey();
} }
- Gọi phương thức của lớp cha: class ChiPhiXayDung : HinhChuNhat
class HinhChuNhat { { private double cost;
//cac bien thanh vien public ChiPhiXayDung(double l, double
protected double chieu_dai; w) : base(l, w) { }
protected double chieu_rong; public double tinhChiPhi() {
// constructor public HinhChuNhat(double l, double chi_phi;
double w) { chieu_dai = l; chieu_rong = w; } chi_phi = tinhDienTich() * 70;
//phuong thuc return chi_phi;
public double tinhDienTich() { }
return chieu_dai * chieu_rong; } public void hienThiThongTin()
public void Display() { { base.Display();
Console.WriteLine("Chieu dai: {0}", Console.WriteLine("Chi phi: {0}",
chieu_dai); Console.WriteLine("Chieu rong: tinhChiPhi()); }
{0}", chieu_rong); Console.WriteLine("Dien }
tich: {0}", tinhDienTich());
- Đa kế thừa:
C# không hỗ trợ đa kế thừa. Tuy nhiên, bạn có thể sử dụng Interface để triển khai
đa kế thừa. public interface ChiPhiSon {
Ví dụ: int tinhChiPhi(int dien_tich);
class Shape {
}
protected int chieu_rong;
protected int chieu_cao; class HinhChuNhat : Shape, ChiPhiSon {
public void setChieuRong(int w) public int tinhDienTich() {
{ chieu_rong = w; } return (chieu_rong * chieu_cao);
public void setChieuCao(int h) { chieu_cao = }
h; } public int tinhChiPhi(int dien_tich) {
} return dien_tich * 70; }
}
- Đa kế thừa: Đa kế thừa là mỗi Class được phép kế thừa nhiều lớp cơ sở.
C# không hỗ trợ đa kế thừa. Tuy nhiên, bạn có thể sử dụng Interface để triển khai
đa kế thừa. public interface ChiPhiSon {
Ví dụ: int tinhChiPhi(int dien_tich);
class Shape {
}
protected int chieu_rong;
protected int chieu_cao; class HinhChuNhat : Shape, ChiPhiSon {
public void setChieuRong(int w) public int tinhDienTich() {
{ chieu_rong = w; } return (chieu_rong * chieu_cao);
public void setChieuCao(int h) { chieu_cao = }
h; } public int tinhChiPhi(int dien_tich) {
} return dien_tich * 70; }
}
1.3 Lớp trừu tượng và giao diện
a. Lớp trừu tượng
- Là lớp có ít nhất một phương thức trừu tượng. Khi xây dựng lớp trừu tượng thì mọi thành
viên được định nghĩa trong lớp trừu tượng đều sử dụng từ khoá abstract.
- Phương thức trừu tượng không có sự thực thi. Phương thức này chỉ đơn giản tạo ra một tên
phương thức và kí hiệu phương thức. Nó không định nghĩa phần thân, thay vào đó chúng được
cài đặt trong phương thức ghi đè của lớp dẫn xuất.
- Để khai báo lớp trừu tượng bạn sử dụng từ khoá abstract trước từ khoá class như cú pháp
sau:
abstract class baseclass
{
// Code of members
}
b. Giao diện
+ Giao diện là tập các hàm khai báo sẵn mà không cài đặt. Các lớp thực thi giao diện có nhiệm
vụ cài đặt các hàm này.
+ Mục đích của việc cài đặt giao diện: Cho phép một lớp dẫn xuất có thể kế thừa thực thi nhiều
giao diện. Điều này đã khắc phục được hạn chế của lớp trừu tượng là một lớp dẫn xuất chỉ có
thể thực thi một lớp trừu tượng.
Cú pháp để định nghĩa một giao diện như sau:
[thuộc tính] [bổ sung truy cập] interface <tên giao diện> [: danh sách cơ sở]
{
<phần thân giao diện>
}
Ví dụ:
public interface GiaoDich { class GiaoDichHangHoa : GiaoDich {