Kiểu liệt kê

Một phần của tài liệu Giáo trình Lập trình trực quan (Nghề: Quản trị mạng máy tính - Cao đẳng) - Trường Cao đẳng Cộng đồng Đồng Tháp (Trang 50)

CHƢƠNG 1– TỔNG QUAN VỀ FRAMEWORK .NET

2.4 Các kiểu dữ liệu có cấu trúc

2.4.3 Kiểu liệt kê

Kiểu liệt kê đơn giản là tập hợp các tên hằng có giá trị khơng thay đổi (thƣờng đƣợc gọi là danh sách liệt kê).

Chƣơng 2 – Ngơn ngữ lập trình c#

51 [thuộc tính] [bổ sung] enum <tên liệt kê> [:kiểu cơ sở]

{danh sách các thành phần liệt kê};

Chú ý:

- Mỗi kiểu liệt kê có một kiểu dữ liệu cơ sở, kiểu dữ liệu có thể là bất cứ kiểu dữ liệu nguyên nào nhƣ int, short, long... tuy nhiên kiểu dữ lịêu của liệt kê không chấp nhận kiểu ký tự

- Thành phần kiểu cơ sở chính là kiểu khai báo cho các mục trong kiểu liệt kê. Nếu bỏ qua thành phần này thì trình biên dịch sẽ gán giá trị mặc định là kiểu nguyên int, tuy nhiên chúng ta có thể sử dụng bất cứ kiểu nguyên nào nhƣ ushort hay long ,.. ngoại trừ kiểu ký tự

- Khai báo một kiểu liệt kê phải kết thúc bằng một danh sách liệt kê, danh sách liệt kê này phải có các hằng đƣợc gán, và mỗi thành phần phải phân cách nhau dấu phẩy.

Ví dụ: enum Thu:int { ChuNhat=0, ThuHai=1, ThuBa=2, ThuTu=3, ThuNam=4,

Chƣơng 2 – Ngơn ngữ lập trình c# 52 ThuSau=5, ThuBay=6, } Ví dụ: enum Thu { ChuNhat, ThuHai, ThuBa, ThuTu, ThuNam, ThuSau, ThuBay, }

ChuNhat=0, ThuHai=1, ThuBa=2, ThuTu=3, ThuNam=4, ThuSau=5, ThuBay=6

Chƣơng 2 – Ngơn ngữ lập trình c# 53 enum Thu { ChuNhat=0, ThuHai=10, ThuBa, ThuTu, ThuNam=20, ThuSau, ThuBay, }

ChuNhat=0, ThuHai=10, ThuBa=11, ThuTu=12, ThuNam=20,

ThuSau=21, ThuBay=22

Kiểu liệt kê là một kiểu hình thức do đó bắt buộc phải thực hiện phép chuyển đổi tƣờng minh với các kiểu giá trị nguyên:

Chƣơng 2 – Ngơn ngữ lập trình c#

54 2.4.4 Khơng gian tên

Nhƣ chúng ta đã biết .NET cung cấp một thƣ viện các lớp đồ sộ và thƣ viện này có tên là FCL (Framework Class Library). Trong đó Console chỉ là một lớp nhỏ trong hàng ngàn lớp trong thƣ viện. Mỗi lớp có một tên riêng, vì vậy FCL có hàng ngàn tên nhƣ ArrayList, Dictionary, FileSelector,… Điều này làm nảy sinh vấn đề, ngƣời lập trình khơng thể nào nhớ hết đƣợc tên của các lớp trong .NET Framework. Tệ hơn nữa là sau này có thể ta tạo lại một lớp trùng với lớp đã có chẳng hạn. Ví dụ trong q trình phát triển một ứng dụng ta cần xây dựng một lớp từ điển và lấy tên là Dictionary, và điều này dẫn đến sự tranh chấp khi biên dịch vì C# chỉ cho phép một tên duy nhất.

Chắc chắn rằng khi đó chúng ta phải đổi tên của lớp từ điển mà ta vừa tạo thành một cái tên khác chẳng hạn nhƣ myDictionary. Khi đó sẽ làm cho việc phát triển các ứng dụng trở nên phức tạp, cồng kềnh. Đến một sự phát triển nhất định nào đó thì chính là cơn ác mộng cho nhà phát triển.

Giải pháp để giải quyết vấn đề này là việc tạo ra một namespace, namsespace sẽ hạn chế phạm vi của một tên, làm cho tên này chỉ có ý nghĩa trong vùng đã định nghĩa.

Tƣơng tự nhƣ vậy ta cứ tạo các namespace để phân thành các vùng cho các lớp trùng tên không tranh chấp với nhau.

Tƣơng tự nhƣ vậy, .NET Framework có xây dựng một lớp Dictionary bên trong namespace System.Collections, và tƣơng ứng ta có thể tạo một lớp Dictionary khác nằm trong namespace ProgramCSharp.DataStructures, điều này hoàn tồn khơng dẫn đến sự tranh chấp với nhau.

Chƣơng 2 – Ngơn ngữ lập trình c#

55 Để làm cho chƣơng trình gọn hơn, và khơng cần phải viết từng namespace cho từng đối tƣợng, C# cung cấp từ khóa là using, sau từ khóa này là một namespace hay

subnamespace với mô tả đầy đủ trong cấu trúc phân cấp của nó.

Ta có thể dùng dịng lệnh: using System; ở đầu chƣơng trình và khi đó trong

chƣơng trình nếu chúng ta có dùng đối tƣợng Console thì khơng cần phải viết đầy đủ: System.Console. mà chỉ cần viết Console. thôi.

using < Tên namespace >

Để tạo một namespace dùng cú pháp sau:

namespace <Tên namespace>

{ < Định nghĩa lớp A> < Định nghĩa lớp B > ..... } 2.5 Hàm

Khi thực thi một đoạn code nào nó nhiều lần, thay vì phải copy đi copy lại đoạn code đó nhiều lần, dẫn đến chƣơng trình chúng ta bị trùng lặp code rất nhiều, trong

Chƣơng 2 – Ngơn ngữ lập trình c#

56 c# có function cho phép chúng ta thực thi đoạn code nào đó nhiều lần mà khơng cần phải copy lại code, mà chỉ cần gọi tên hàm.

2.5.1 Khai báo hàm

Cú pháp

<Quyền truy cập> <Kiểu trả về> Tên hàm (<Tham số>) {

// Thân hàm // Giá trị trả về; }

Trong đó:

 Tên hàm: là một tên duy nhất đƣợc sử dụng để gọi hàm.

 Kiểu trả về: đƣợc sử dụng để chỉ rõ kiểu dữ liệu của hàm đƣợc trả về.

 Thân hàm: là khối lệnh sẽ đƣợc thực thi khi hàm đƣợc gọi.

 Quyền truy cập: đƣợc sử dụng để xác định khả năng truy cập hàm trong ứng dụng.

 Tham số: là một danh sách các tham số mà chúng ta truyền vào khi gọi hàm

Ví dụ:

Chƣơng 2 – Ngơn ngữ lập trình c#

57 Khai báo hàm tham số kiểu tham trị: kiểm tra số nguyên tố

public static bool SoNT(int so) {

int u = 2;

for (; u < so; u++)

if (so % u == 0)

return false;

return true;

}

Khai báo hàm tham số kiểu tham biến ref: hàm đổi chỗ 2 số public static void Swap(ref int a, ref int b) {

a = a + b; b = a - b; a = a - b;

}

Khai báo hàm tham số kiểu tham chiếu out: hàm giải phƣơng trình bậc 2 public static bool GiaiPTB2(int a, int b, int c, out Double X1, out Double X2)

Chƣơng 2 – Ngơn ngữ lập trình c# 58 int Delta = b * b - 4 * a * c; X1 = X2 = 0; if (Delta >= 0) { X1 = (-b - Math.Sqrt(Delta)) / (2 * a); X2 = (-b + Math.Sqrt(Delta)) / (2 * a); return true; } else return false; } 2.5.2 Cách gọi hàm

Trong c# có 3 cách gọi hàm đó là gọi bằng giá trị (call by value), gọi bằng tham chiếu (call by Reference) và dùng tham số out.

Gọi bằng giá trị (call by value)

Trong C#, gọi bằng giá trị tức là tham số truyền vào là bản sao của giá trị gốc, vì vậy dù cho bên trong thân hàm có thay đổi giá trị của tham số truyền vào thì sau khi kết thúc gọi hàm thì giá trị gốc vẫn khơng thay đổi.

Chƣơng 2 – Ngơn ngữ lập trình c#

59 Trong ví dụ sau, chúng ta truyền tham số giá trị khi gọi hàm:

Gọi bằng tham chiếu (call by Reference)

C # cung cấp một từ khóa ref để truyền đối số dƣới dạng tham chiếu. Tức là tham số truyền vào bằng địa chỉ ô nhớ của biến gốc vì vậy bên trong thân hàm thay đổi giá trị tham số truyền vào thì giá trị gốc cũng thay đổi theo..

2.5.3 Truyền tham số

C # cung cấp một từ khóa ref để truyền đối số dƣới dạng tham chiếu. Tức là tham số truyền vào bằng địa chỉ ơ nhớ của biến gốc vì vậy bên trong thân hàm thay đổi giá trị tham số truyền vào thì giá trị gốc cũng thay đổi theo..

Tham số out

Tham số out giống nhƣ kiểu tham chiếu, ngoại trừ việc nó khơng u cầu biến khởi tạo trƣớc khi truyền.

Nhƣ vậy mình chỉ cần phân biệt ref và out nhƣ sau:

ref

 Giá trị phải đƣợc khởi tạo trƣớc

 Bên trong thân hàm có thể đọc vào thay đổi giá trị nó

out

 Giá trị khơng đƣợc khởi tạo trƣớc và bên trong thân hàm khơng đọc đƣợc nó cho đến khi nó đƣợc gán giá trị

Chƣơng 2 – Ngơn ngữ lập trình c#

60

2.6 Exception và cấu trúc try..catch

2.6.1 Exception

Ngôn ngữ C# cũng giống nhƣ bất cứ ngôn ngữ hƣớng đối tƣợng khác, cho phép xử lý những lỗi và các điều kiện khơng bình thƣờng với những ngoại lệ. Ngoại lệ là một đối tƣợng đóng gói những thơng tin về sự cố của một chƣơng trình khơng bình thƣờng.

Một điều quan trọng để phân chia giữa bug, lỗi, và ngoại lệ. Một bug là một lỗi lập trình có thể đƣợc sửa chữa trƣớc khi mã nguồn đƣợc chuyển giao. Những ngoại lệ thì khơng đƣợc bảo vệ và tƣơng phản với những bug. Mặc dù một bug có thể là nguyên nhân sinh ra ngoại lệ, chúng ta cũng không dựa vào những ngoại lệ để xử lý những bug trong chƣơng trình, tốt hơn là chúng ta nên sửa chữa những bug này. Một lỗi có ngun nhân là do phía hành động của ngƣời sử dụng. Ví dụ, ngƣời sử dụng nhập vào một số nhƣng họ lại nhập vào ký tự chữ cái. Một lần nữa, lỗi có thể làm xuất hiện ngoại lệ, nhƣng chúng ta có thể ngăn ngừa điều này bằng cách bắt giữ lỗi với mã hợp lệ.

Những lỗi có thể đƣợc đốn trƣớc và đƣợc ngăn ngừa. Thậm chí nếu chúng ta xóa tất cả những bug và dự đoán tất cả các lỗi của ngƣời dùng, chúng ta cũng có thể gặp phải những vấn đề không mong đợi, nhƣ là xuất hiện trạng thái thiếu bộ nhớ (out of memory), thiếu tài nguyên hệ thống,... những nguyên nhân này có thể do các chƣơng trành khác cùng hoạt động ảnh hƣởng đến. Chúng ta không thể ngăn ngừa các ngoại lệ này, nhƣng chúng ta có thể xử lý chúng để chúng khơng thể làm tổn hại đến chƣơng trình.

Chƣơng 2 – Ngơn ngữ lập trình c#

61 Khi một chƣơng trình gặp một tình huống ngoại lệ, nhƣ là thiếu bộ nhớ thì nó sẽ tạo một ngoại lệ. Khi một ngoại lệ đƣợc tạo ra, việc thực thi của các chức năng hiện hành sẽ bị treo cho đến khi nào việc xử lý ngoại lệ tƣơng ứng đƣợc tìm thấy.

Các lớp ngoại lệ

Tên ngoại lệ Mô tả

MethodAccessException Lỗi truy cập, do truy cập đến thành viên hay phƣơng thức không đƣợc truy cập ArgumentException Lỗi tham số đối mục

ArgumentNullException Đối số Null, phƣơng thức đƣợc truyền đối số null không đƣợc chấp nhận

ArithmeticException Lỗi liên quan đến các phép toán ArrayTypeMismatchException Kiểu mảng không hợp, khi cố lƣu trữ

kiểu khơng thích hợp vào mảng DivideByZeroException Lỗi chia zero

FormatException Định dạng khơng chính xác một đối mục nào đó

IndexOutOfRangeException Chỉ số truy cập mảng không hợp lệ, dùng nhỏ hơn chỉ số nhỏ nhất hay lớn hơn chỉ số lớn nhất của mảng

Chƣơng 2 – Ngơn ngữ lập trình c#

62 MulticastNotSupportedException Multicast không đƣợc hỗ trợ, do việc kết

hợp hai delegate không đúng

NotFiniteNumberException Không phải số hữu hạn, số không hợp lệ NotSupportedException Phƣơng thức không hỗ trợ, khi gọi một phƣơng thức không tồn tại bên trong lớp.

NullReferenceException Tham chiếu null không hợp lệ. OutOfMemoryException Out of memory

OverflowException Lỗi tràn phép toán StackOverflowException Tràn stack

TypeInitializationException Kiểu khởi tạo sai, khi bộ khởi dựng tĩnh có lỗi

2.6.2 Cấu trúc try…catch Cú pháp cấu trúc try…catch

try

{

Chƣơng 2 – Ngơn ngữ lập trình c#

63 }

catch (TypeException1 ex)

{

//Mã đựơc thực thi khi một ngoại lệ TypeException1 đựơc phát sinh trong khối try

}

catch (TypeException2 ex)

{

//Mã đựơc thực thi khi một ngoại lệ TypeException2 đựơc phát sinh trong khối try

}

catch (TypeExceptionN ex)

{

//Mã đựơc thực thi khi một ngoại lệ TypeExceptionN đựơc phát sinh trong khối try

}

[finally

{

Chƣơng 2 – Ngôn ngữ lập trình c#

64 có xảy ra trong khối try hay khơng.

}]

Nếu khơng có một ngoại lệ nào phát sinh trong khối try thì các mệnh đề catch sẽ bị bỏ qua, trong trƣờng hợp một trong các câu lệnh bên trong khối try gây ra một

ngoại lệ thì, thì C# sẽ bỏ qua các câu lệnh cịn lại trong khối try để đi tìm mã xử lý ngoại lệ, nếu kiểu ngoại lệ so khớp với kiểu ngoại lệ trong mệnh đề catch, thì mã lệnh trong khối catch đó sẽ đƣợc thực thi, nếu khơng tìm thấy một kiểu ngoại lệ

nào đƣợc so khớp C# sẽ kết thúc phƣơng thức đó và chuyển biệt lệ đó ra phƣơng thức đã gọi phƣơng thức này quá trình này đƣợc tiếp tục cho đến khi tìm thấy mã xử lý biệt lệ, nếu khơng tìm thấy mã xử lý biệt lệ trong chuỗi các phƣơng thức gọi nhau, chƣơng trình có thể chấm dứt và in thơng báo lỗi…

Khối finally là tuỳ chọn, khơng bắt buộc phải có. Khối này đƣợc đặt sau khối catch cuối cùng. Chƣơng trình sẽ thực thi câu lệnh đầu tiên của khối finally ngay sau khi gặp câu lệnh return hay lệnh break trong khối try.

Khối finally bảo đảm lúc nào cũng đƣợc thực thi, bất chấp có ngoại lệ xảy ra hay khơng Ví dụ 1: int[] m = { 1, 4, 6, 7 }; try { int a, b; a = 1;

Chƣơng 2 – Ngơn ngữ lập trình c#

65 b = 0;

int c = a / b;//Co khả năng sinh ra lỗi nếu mẫu số =0

Console.WriteLine("c={0}", c);

Console.WriteLine("m{0}={1}", c, m[7]);

//m[c] có khả năng sinh ra lỗi nếu vượt ra ngồi chỉ sơ của mảng

}

catch (DivideByZeroException ex)

{

Console.WriteLine(ex.Message);

}

catch (IndexOutOfRangeException ex)

{

Console.WriteLine(ex.Message);

}

catch (Exception ex)

Chƣơng 2 – Ngôn ngữ lập trình c#

66 Console.WriteLine(ex.Message);

}

Kết quả

attempted to divide by zero

Ví dụ 2: int[] m = { 1, 4, 6, 7 }; try { int a, b; a = 1; b = 2;

int c = a / b;//Co khả năng sinh ra lỗi nếu mẫu số =0

Console.WriteLine("c={0}", c);

Console.WriteLine("m{0}={1}", c, m[7]);

//m[c] có khả năng sinh ra lỗi nếu vượt ra ngồi chỉ sơ của mảng

Chƣơng 2 – Ngơn ngữ lập trình c#

67 catch (DivideByZeroException ex)

{

Console.WriteLine(ex.Message);

}

catch (IndexOutOfRangeException ex)

{

Console.WriteLine(ex.Message);

}

catch (Exception ex)

{

Console.WriteLine(ex.Message);

}

Kết quả

Index was outside the bounds of the array

Ví dụ 3:

int[] m = { 1, 4, 6, 7 };

Chƣơng 2 – Ngơn ngữ lập trình c# 68 { int a, b; a = 1; b = 2;

int c = a / b;//Co khả năng sinh ra lỗi nếu mẫu số =0

Console.WriteLine("c={0}", c);

Console.WriteLine("m{0}={1}", c, m[7]);

//m[c] có khả năng sinh ra lỗi nếu vượt ra ngồi chỉ sơ của mảng

}

catch (DivideByZeroException ex)

{

Console.WriteLine(ex.Message);

}

catch (IndexOutOfRangeException ex)

{

Chƣơng 2 – Ngơn ngữ lập trình c#

69 }

catch (Exception ex)

{

Console.WriteLine(ex.Message);

}

finally

{

Console.WriteLine("Vi du ve cau truc try...catch...finally");

}

Kết quả

Index was outside the bounds of the array

Chƣơng 3 – Lập trình hƣớng đối tƣợng

70

CHƢƠNG 3 – LẬP TRÌNH HƢỚNG ĐỐI TƢỢNG Mục tiêu

- Trình bày đƣợc các tính chất của lập trình hƣớng đối tƣợng. - Trình bày đƣợc các thành phần trong mơ hình hƣớng đối tƣợng.

- Sử dụng thành thạo các lớp đối tƣợng và các thành phần của lớp đối tƣợng. - Rèn luyện tính tích cực, chủ động, thích học hỏi, tƣ duy trong lập lập. - Thao tác cẩn thận an tồn trên máy tính.

3.1 Giới thiệu

Lập trình hƣớng đối tƣợng là kiểu lập trình nhằm vào sự tƣơng tác giữa các đối tƣợng. Mỗi đối tƣợng có những thuộc tính xác định các đặc điểm, những phƣơng thức xác định các chức năng của đối tƣợng. các đối tƣợng cũng có khả năng phát sinh các sự kiện khi thay đổi thuộc tính, thực hiện một phƣợng thức hay bị đối tƣợng khác tác động vào.

3.2 Các tính chất của lập trình hƣớng đối tƣợng

3.2.1 Tính trừu tƣợng

Tính trừu tƣợng là một tiến trình ẩn các chi tiết trình triển khai và chỉ hiển thị tính năng tới ngƣời dùng. Tính trừu tƣợng cho phép bạn loại bỏ tính chất phức tạp của đối tƣợng bằng cách chỉ đƣa ra các thuộc tính và phƣơng thức cần thiết của đối tƣợng trong lập trình.

Chƣơng 3 – Lập trình hƣớng đối tƣợng

71 Tính trừu tƣợng giúp bạn tập trung vào những cốt lõi cần thiết của đối tƣợng thay vì quan tâm đến cách nó thực hiện.

3.2.2 Tính đóng gói

Tức là trạng thái của đối tƣợng đƣợc bảo vệ không cho các truy cập từ code bên ngoài nhƣ thay đổi trong thái hay nhìn trực tiếp. Việc cho phép môi trƣờng bên ngoài tác động lên các dữ liệu nội tại của một đối tƣợng theo cách nào là hoàn toàn tùy thuộc vào ngƣời viết mã. Đây là tính chất đảm bảo sự tồn vẹn, bảo mật của đối tƣợng Trong Java, tính đóng gói đƣợc thể hiện thơng qua phạm vi truy cập (access modifier). Ngoài ra, các lớp liên quan đến nhau có thể đƣợc gom chung lại thành package.

3.2.3 Tính thừa kế

Tính kế thừa là khả năng cho phép ta xây dựng một lớp mới dựa trên các định nghĩa của một lớp đã có. Lớp đã có gọi là lớp Cha, lớp mới phát sinh gọi là lớp Con

Một phần của tài liệu Giáo trình Lập trình trực quan (Nghề: Quản trị mạng máy tính - Cao đẳng) - Trường Cao đẳng Cộng đồng Đồng Tháp (Trang 50)

Tải bản đầy đủ (PDF)

(105 trang)