Thứ Ba, 17 tháng 3, 2009

Update window server 2003

- Start > Run > regedit
- Tìm đến nhánh sau :
Code:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WPAEvents

- Thay đổi bất kì giá trị nào ở key OOBETimer (Cái này làm cho windows trở về trạng thái chưa active)
- Close registry. Sau đó vào Start > Run > gõ :
Code:

%systemroot%\system32\oobe\msoobe.exe /a

- Tại cửa sổ active windows, chọn : Yes, i want to telephone ...
- Chọn tiếp Change Product Key > Điền key mới của bạn. Chọn Update.
- Khi chọn Update, nó sẽ quay trở lại màn hình ở bước 6. Khi đó ta chọn Remind Me Later
- Restart PC, sau đó gõ
Code:

systemroot%\system32\oobe\msoobe.exe /a

Nếu thấy cửa sổ active windows báo "Windows is already activated" thì bạn đã thành công


key

V893X-4RHCY-6PPH8-8VMT6-W97QT
HMWM9-2883J-HGGGC-FDBRX-XHHQT
TVF69-YXHGB-C9X2RJR9-Q6RX6
PFGC3-XWY6C-9MPYD-XKK2M-8DP7G
QVHVK-H6G69-3CXT9-Q43HC-Y8P7G
FGMF6-QCRXR-Y9CW7-YKFM3-Y97QT
DG9KD-G7VGM-3TPBW-QTGPV-7RFX6
D9MYT-QMTYX-MTVC7-BTP4T-9JD3T
R3RXP-6X97Q-D72YC-784FX-MFKHG
MWP23-VWB3X-PTTYT-8D297-DMXHG
WB2CJ-JWGJ4-HVFJ3-8Y9HM-V8VQT
RBRBP-WXWDF-WXP7H-M4B49-9QP7G
DBKDW-4M6XH-6R279-3HFC7-W3JK6
VPTQX-8X8RX-38Q6H-98P26-V4Q3T
J76HW-X4KKC-QRHW7-HV62R-M2TVG
TQ863-76XMQ-BK8DP-R3X8B-MHTVG
MF9FM-KQQPH-26R2J-9YHC2-8KFX6
H36TY-XQVW9-8KWFM-H8JCX-BYRX6
RFGHD-3MMGK-TPPD9-49PJT-MVTVG
D3TJG-9K7DW-TJFDX-YF6T6-F8VQT
KD4QJ-CBC3Q-P38M7-GVJWB-PD6VG
HJH9D-344BV-83DMJ-X67FB-RGRX6
R8FJP-C8YMC-W7MMG-HMJWW-6TRX6
KRTJB-K9H9P-8DPYD-F7JYV-X3Y96


Có hai (pháp lý) các phương pháp mà bạn có thể sử dụng để thay đổi các sản phẩm trọng điểm với khối lượng cấp giấy phép phương tiện truyền thông sau khi cài đặt. You can use either the Windows Activation Wizard graphical user interface (GUI) or a Windows Management Instrumentation (WMI) script. Bạn có thể sử dụng, hoặc Windows Activation Wizard giao diện người dùng đồ họa (GUI), hoặc Windows Management Instrumentation (WMI) script.

The easier method to use is the Use the Activation Wizard method. Các phương pháp dễ dàng hơn để sử dụng là sử dụng các phương pháp kích hoạt Wizard. Use this method when you only have a few computers on which to change the product key. Sử dụng phương pháp này khi bạn chỉ có một vài máy vi tính mà trên đó để thay đổi các sản phẩm chủ chốt. The Use a Script me


http://64.233.189.132/translate_c?hl=vi&langpair=en%7cvi&u=http://www.petri.co.il/change_the_serial_in_windows_xp.htm&prev=/translate_s%3Fhl%3Dvi%26q%3Dthay%2Bdoi%2Bcd%2Bkey%2Btrong%2Bwindows%2Bserver%2B2003%26tq%3Dchange%2Bcd%2Bkey%2Bin%2BWindows%2BServer 2B2003%26sl%3Dvi%26tl%3Den&usg=ALkJrhgiG7acDELkXGVGzfZprJ8vfynQoQ

Thứ Hai, 9 tháng 3, 2009

Mảng và các toán tử trong C#

Trong bài nảy chúng ta sẽ tìm hiểu các khái niệm về dữ liệu mảng và toán tử trong C#.

Mảng (Arrays)

Array là một cấu trúc dữ liệu cấu tạo bởi một số biến được gọi là những phần tử mảng. Tất cả các phần tử này đều thuộc một kiểu dữ liệu. Bạn có thể truy xuất phần tử thông qua chỉ số (index). Trong C# chỉ số này bắt đầu bằng 0.

Có nhiều loại mảng (array): mảng một chiều, mảng nhiều chiều.

Cú pháp :

type[ ] array-name;

thí dụ:

int[] myIntegers; // mảng kiểu số nguyên

string[] myString ; // mảng kiểu chuổi chữ

Bạn khai báo mảng có chiều dài xác định với từ khoá new như sau:

// Tạo mảng có 32 phần tử kiểu int

int[] myIntegers = new int[32];

integers[0] = 35;// phần tử đầu tiên có giá trị 35

integers[31] = 432;// phần tử 32 có giá trị 432

Bạn cũng có thể khai báo như sau:

int[] integers;

integers = new int[32];

string[] myArray = {"first element", "second element", "third element"};

Làm việc với mảng

Ta có thể tìm được chiều dài của mảng sau nhờ vào thuộc tính Length thí dụ sau :

int arrayLength = integers.Length

Nếu các thành phần của mảng là kiểu định nghĩa trước (predefined types), ta có thể sắp xếp tăng dần vào phương thức gọi là static Array.Sort() method:

Array.Sort(myArray);

Cuối cùng chúng ta có thể đảo ngược mảng đã có nhờ vào the static Reverse() method:

Array.Reverse(myArray);

string[] artists = {"Leonardo", "Monet", "Van Gogh", "Klee"};

Array.Sort(artists);

Array.Reverse(artists);

foreach (string name in artists)

{

Console.WriteLine(name);

}

Mảng nhiều chiều

Cú pháp :

type[,] array-name;

Thí dụ muốn khai báo một mảng hai chiều gồm hai hàng ba cột với phần tử kiểu nguyên :

int[,] myRectArray = new int[2,3];

Bạn có thể khởi gán mảng xem các ví dụ sau về mảng nhiều chiều:

int[,] myRectArray = new int[,]{ {1,2},{3,4},{5,6},{7,8}}; mảng 4 hàng 2 cột

string[,] beatleName = { {"Lennon","John"},

{"McCartney","Paul"},

{"Harrison","George"},

{"Starkey","Richard"} };

chúng ta có thể sử dụng :

string[,,] my3DArray;

double [, ] matrix = new double[10, 10];

for (int i = 0; i < 10; i++)

{

for (int j=0; j < 10; j++)

matrix[i, j] = 4;

}

Mảng jagged

Một loại thứ 2 của mảng nhiều chiều trong C# là Jagged array. Jagged là một mảng mà mỗi phần tử là một mảng với kích thước khác nhau. Những mảng con này phải đuợc khai báo từng mảng con một.

Thí dụ sau đây khai báo một mảng jagged hai chiều nghĩa là hai cặp [], gồm 3 hàng mỗi hàng là một mảng một chiều:

int[][] a = new int[3][];
a[0] = new int[4];
a[1] = new int[3];
a[2] = new int[1];

Khi dùng mảng jagged ta nên sử dụng phương thức GetLength() để xác định số lượng cột của mảng. Thí dụ sau nói lên điều này:

using System;

namespace Wrox.ProCSharp.Basics

{

class MainEntryPoint

{

static void Main()

{

// Declare a two-dimension jagged array of authors' names

string[][] novelists = new string[3][];

novelists[0] = new string[] {

"Fyodor", "Mikhailovich", "Dostoyevsky"};

novelists[1] = new string[] {

"James", "Augustine", "Aloysius", "Joyce"};

novelists[2] = new string[] {

"Miguel", "de Cervantes", "Saavedra"};

// Loop through each novelist in the array

int i;

for (i = 0; i < novelists.GetLength(0); i++)

{

// Loop through each name for the novelist

int j;

for (j = 0; j < novelists[i].GetLength(0); j++)

{

// Display current part of name

Console.Write(novelists[i][j] + " ");

}

// Start a new line for the next novelist

Console.Write("\n");

}

}

}

}

Toán tử trong C#

Phép tính


+ - * / %

Logic


& | ^ ~ && || !

Cộng chuỗi


+

Tăng và giảm


++ --

Dịch bit


<< >>

So sánh


== != < > <= >=

Gán


= += -= *= /= %= &= |= ^= <<= >>=

Truy cập member


.

Dùng để chỉ index


[]

Cast


()

Conditional (the Ternary Operator)


?:

Tạo đối tượng


new

Thông tin về kiểu


sizeof ,is, typeof, as



Câu sau đây có nghĩa là x bằng với 3 (gán 3 vào biến x):

x = 3;

Nếu chúng ta muốn so sánh x với một giá trị chúng ta sử dụng kí hiệu sau ==:

if (x == 3)

Toán tử “Shortcuts”

Bảng dưới đây trình bày một danh sách đầy đủ của shortcut operators có giá trị trong C#:

Shortcut Operator


Tương đương

x++, ++x


x = x + 1

x--, --x


x = x - 1

x += y


x = x + y

x -= y


x = x – y

x *= y


x = x * y

x /= y


x = x / y

x %= y


x = x % y

x >>= y


x = x >> y

x <<= y


x = x << y

x &= y


x = x & y

x |= y


x = x | y

x ^= y


x = x ^ y

Thí dụ :

int x = 5;
if (++x == 6)
{
Console.WriteLine("This will execute");
}
if (x++ == 7)
{
Console.WriteLine("This won't");
}

x += 5;

x = x + 5;

is

int i = 10;

if (i is object)

{

Console.WriteLine("i is an object");

}

sizeof

string s = "A string";

unsafe

{

Console.WriteLine(sizeof(int));

}

C# căn bản _ phần III

Câu lệnh điều kiện if :

Cú pháp như sau:

if (condition)

statement(s)

[else if

statement(s)]

[else

statement(s)]

Nếu có nhiều hơn một câu lệnh để thi hành trong câu lệnh điều kiện chúng ta sẽ đưa
tất cả các câu lệnh này vào trong dấu ngoặc móc ({ ... }) giống như ví dụ sau :

bool isZero;
if (i == 0)
{
isZero = true;
Console.WriteLine("i is Zero");
}
else
{
isZero = false;
Console.WriteLine("i is Non-zero");
}

Đoạn code trên kiểm tra isZero có bằng 0 hay không. Lệnh If có thể sử dụng lồng nhau không hạn chế.

Câu lệnh switch

Các câu lệnh if nằm lồng rất khó đọc, khó gỡ rối. Khi bạn có một loạt lựa chọn phức tạp thì nên sử dụng câu lệnh switch.

Cú pháp như sau:

switch (biểu thức)

{ casce biểu thức ràng buộc:

câu lệnh

câu lệnh nhảy

[default: câu lệnh mặc định]

}



Thí dụ sau: Thí dụ sẽ kiểm tra integerA thoả đúng trong các trường hợp 1, 2, 3 không nếu không đúng sẽ thực thi trường hợp default




switch (integerA)

{

case 1:

Console.WriteLine("integerA =1");

break;

case 2:

Console.WriteLine("integerA =2");

break;

case 3:

Console.WriteLine("integerA =3");

break;

default:

Console.WriteLine("integerA is not 1,2, or 3");

break;

}


Xem các ví dụ sau để hiểu rõ thêm về switch:



switch(country) {
case "America":
CallAmericanOnlyMethod();
goto case "Britain";
case "France":
language = "French";
break;
case "Britain":
language = "English";
break;
}
switch(country)
{
case "au":
case "uk":
case "us":
language = "English";
break;
case "at":
case "de":
language = "German";
break;
}

Vòng lặp (Loops):

C# cung cấp cho chúng ta 4 vòng lặp khác nhau (for, while, do...while, và foreach)

cho phép chúng ta thực hiện một đoạn mã lặp lại đến khi đúng điều kiện lặp.



Vòng lặp for:



cú pháp:

for (initializer; condition; iterator)

statement(s)

Thí dụ:

Đoạn mã sau sẽ xúât ra tất cả số nguyên từ 0 đến 99:

for (int i = 0; i < 100; i = i+1)
{
Console.WriteLine(i);
}

Xét ví dụ sau:

using System;

namespace itop.vn
{
class Coltech
{
static void Main(string[] args)
{
for (int i = 0; i < 100; i+=10)
{
for (int j = i; j < i + 10; j++)
{
Console.Write(" " + j);
}
Console.WriteLine();
}
}
}
}

Kết quả được in ra khi chạy chương trình như sau:

0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59
60 61 62 63 64 65 66 67 68 69
70 71 72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87 88 89
90 91 92 93 94 95 96 97 98 99

Vòng lặp while (The while Loop)

Cú pháp như sau :

while (condition)
statement(s);

Thí dụ :

int i = 0;
while (i > 5)
{
Console.Writeln(“www.itop.vn ” + i.ToString();
i ++;
}

Câu lệnh in trong vòng lặp sẽ thực hiện cho đến khi i = 6. Đoạn lện trên sẽ cho kết quả :


www.itop.vn 1
www.itop.vn 2
www.itop.vn 3
www.itop.vn 4
www.itop.vn 5
www.itop.vn 6

Vòng lặp do . . . while (The do…while Loop)

bool condition;
do
{
// Vòng lặp này sẽ thực hiện ít nhất một lần thậm chí nếu // câu điều kiện sai
[Statements]
} while (condition);

Vòng lặp foreach (The foreach Loop)

Cho phép bạn rảo qua tất cả các phần tử bản dãy hoặc các tập hợp khác, và tuần tự xem xét từng phần tử một.Cú pháp như sau:
foreach (type identifier in expression) statement

Ví dụ:

foreach (int temp in ArrayInt)
{
Console.WriteLine(temp);
}

Câu lệnh break

Ta dùng câu lệnh break khi muốn chấm dứt thi hành và thoát khỏi vòng lặp.

Câu lệnh continue

Câu lệnh continue được dùng trong vòng lặp khi bạn muốn khởi động lại một vòng lặp nhưng lại không muốn thi hành phần lệnh còn lại trong thân vòng lặp.

C# căn bản _ phần II

Trong bài này chúng ta tiếp tục tìm hiểu các vấn đề căn bản của ngôn ngữ C# :

* · Khai báo biến hệ thống kiểu dữ liệu trong C#.
* · Cú pháp lệnh và các khái niệm trong C#.



Khái niệm interface :

Interface cung cấp giải pháp thuận tiện cho việc phát triển các thành phần cơ sở. Interface cung cấp những thỏa thuận chung cho phép các thành phần làm việc với nhau.

Interface chứa các khai báo của các members hay methods, sử dụng từ khóa public. Các method trong interface chỉ là các khai báo, có thể nói đơn giản đó như là chỉ thị buộc những class hay struct cài đặt interface phải cài đặt các method này. Các class hay struct có thể cài đặt nhiều interface, khi đã cài đặt interface bắt buộc phải cài đặt đầy đủ các member và method được khai báo trong interface.

Cấu trúc : interface [tên interface]

{

//code

}

Ví dụ :

//Khai bao interface

public interface IPlayerManager

{

public void PlayMusic();

public void PauseMusic();

public void Stop();

}

//Class cài đặt interface

public class Player : IPlayerManager

{

public void PlayMusic()

{

//code

}

public void PauseMusic()

{

//code

}

public void Stop()

{

//code

}

}

Trên đây là ví dụ về cài đặt 1 interface cho class, nếu bạn sử dụng nhiều interface thì cách làm không có gì khác biệt, khi ấy mỗi interface được cài đặt sẽ được viết cạnh nhau và chác nhau bằng dấu “ , ”. Tuy nhiên, vấn đề đạt ra là nếu trong các interface được cài đặt vào class lại có những method trùng tên nhau thì sao !? Vấn đề này được giải quyết như sau :

Cũng đoạn code trên nhưng ta sẽ viết tường minh cả tên Interface chưa method như sau :

public class Player : IplayerManager1 , IplayerManager2

{

// cài đặt method PlayMusic() trong interface IplayerManager1

public void IplayerManager1.PlayMusic()

{

//code

}

// cài đặt method PlayMusic() trong interface IplayerManager2

public void IplayerManager2.PlayMusic()

{

//code

}

public void PauseMusic()

{

//code

}

public void Stop()

{

//code

}

}

Kế thừa trong C# :

Kế thừa là khái niệm then chốt trong lập trình hướng đối tượng, Kế thừa cho phép các method, thuộc tính được dùng chung trong các lớp cơ sở (base class) và các lớp chỉ định được sử dụng chúng cũng như mở rộng các chức năng ấy tùy thuộc từng yêu cầu trong từng lớp xẫn xuất.

Ví dụ : hình chữ nhật, hình tam giác … đều là những hình khối cơ bản và có đặc điểm chung như chiều dài, rộng, có diện tích, chu vi …. Điều này trong lập trình cho phép ta khái quát hóa chúng thành một lớp cơ sở. hcn, tam giác … sẽ là những lớp kế thừa từ lớp cơ sở này và có đầy đủ tính chất của lớp co sở, nhưng bản thân chúng cũng có những sự khác biệt, và chúng ta hoàn toàn có thể mở rộng.

// lớp cơ sở

class Shape

{

public int ChieuDai;

public int ChieuRong;

public void DienTich(int Dai,int Rong)

{

}

}

class HinhChuNhat : Shape

{

//Contructor

public HinhChuNhat()

{

ChieuDai = 0;

ChieuRong = 0;

}

public new void DienTich(int Dai,int Rong)

{

Console.WriteLine(“Diện tích là : {0}”,Dai*Rong);

}

}

class HinhVuong : Shape

{

//Contructor

public HinhVuong()

{

}

public new void DienTich(int Canh1,int Canh2)

{

int iDienTich = Canh1*Canh2;

Console.WriteLine(“Diện tích là : {0}” , iDienTich);

}

}



Tính đa hình

Như trên ta đã nói, lớp dẫn xuất có khả năng ghi đè phương thức của lớp cớ sở (hay nói cách khác là cài đặt lại) và cung cấp thể hiện khác ở lớp dẫn xuất, đây chính là hình thức cơ bản của khái niệm đa hình.

C# cung cấp từ khóa virtual để chỉ rõ phương thức có thể bị lớp dẫn xuất ghi đè (overridden). Lớp dẫn xuất có thể ghi đè phương thức virtual bằng cách sử dụng từ khóa override.

Code demo :

class TongDai()

{

public virtual void ChuongGoiDien() { … }

}

class DienThoaiCoDinh() : TongDai

{

public override void ChuongGoiDien() { … }

}

class DienThoaiDiDong() : TongDai

{

public override void ChuongGoiDien() { … }

}

C# căn bản _ phần I

Trong bài này chúng ta sẽ tìm hiểu các vấn đề căn bản của ngôn ngữ C# sau :

* · Khai báo biến hệ thống kiểu dữ liệu trong C#.
* · Cú pháp lệnh và các khái niệm trong C#.



1. Khai báo biến và hệ thống kiểu dữ liệu trong C#.

C# định nghĩa 7 kiểu biến, bao gồm: static variables, instance variables, array elements, value parameters, reference parameters, output parameters, và local variables.

Ví dụ sau sẽ miêu tả 7 kiểu biến đó :

class A
{
public static int x;
int y;
void F(int[] v, int a, ref int b, out int c) {
int i = 1;
c = a + b++;
}
}

x là một static variable, y là một instance variable, v[0] là một array element,
a là một tham số truyền theo giá trị(value parameter), b là một tham chiếu (reference parameter), c là một tham số output, và i là một biến cục bộ.

Trong C#, biến (variable), phương thức (method) chúng ta gọi chung là member.

Cấu trúc : [access modifier] [DataType] [VariableName]

Access modifier (bổ từ truy cập) : định nghĩa mức độ (hay phạm vi) truy cấp của member.

DataType : Kiểu dữ liệu trong C#.

Ví dụ :

public int iCount ;

private string sFullName ;

Access modifier


Mô tả

Public


Member có thể được gọi hay truy cập từ bất kỳ chỗ nào trong ứng dụng

Protected


Member chỉ được truy cập trong phạm vi lớp (class) hiện tại và lớp kế thừa.

Private


Member chỉ được truy cập trong phạm vi lớp (class) hiện tại.

Internal


Memner chỉ được truy cập trong gói (assembly) hiện tại.

Protected internal


Member chỉ được truy cập ở gói hiện tại và của kiểu dẫn xuất từ lớp.

Kiểu dữ liệu


Mô tả


Ví dụ

object


Lớp cơ sở của tất cả các kiểu dữ liệu trong C#.


object o = null ;

string


Dãy các ký tự ở dạng Unicode


string sName = “Le Ha” ;

int


Số nguyên có dấu 32 bit


int iCout = 1;

long


Số nguyên có dấu 64 bit


float


Số chấm động


float fHeight = 1.25 ;

char


Kiểu ký tự Unicode


char c = ‘a’ ;

bool


Kiểu logic (true hoặc false)


bool bFlag = true ;

double


Số chấm động


· Bảng trên là một số kiểu dữ liệu phổ biến mà C# định nghĩa sẵn cho người lập trình, nhưng đôi khi chúng ta cũng cần tự định nghĩa một cấu trúc dữ liệu theo ý mình và C# cung cấp cho ta một vài khái niệm để thực hiện điều này, đó là Struct và Enumerators.



Struct :

Cú pháp : Struct [name]

{

[Access-modifier] member;

}

Ví dụ :

Struct phanso

{

public int tuso ;

public int mauso ;

public void Print()

{

Console.Write (“phân số là : {0} / {1}”, tuso, mauso);

}

}

Public static void Main()

{

phanso p1;

p1.tuso = 1;

p1.tuso = 2;

p1.Print();

}

Kết quả trên màn hình console là 1/2.

Nếu bạn đã từng biết C++ thì có thấy một khác biệt đó là Struct trong C# cho phép viết cả phương thức trong nó. Kiểu struct hữu ích khi ta muốn tạo ra các object giống class nhưng cần truy xuất nhanh mà không cần khởi tạo object.

Enumerator :

Cú pháp : enum [name]

{

Value_1,

Value_2,

………,

Value_n

}

Ví dụ :

public class Holiday

{

Public enum Weekdays

{

Monday,

Tuesday,

Friday

}

}

Public static void Main()

{

Holiday h = new Holiday();

Console.Writeline(“My holiday is :” + h.Friday );

}

Hữu ích khi bạn dùng để liệt kê một loạt các giá trị, kiểu enum thuận lợi cho việc tạo danh sách có giá trị xác định.

· Các đối tượng thuộc 1 kiểu dữ liệu có thể được chuyển đổi sang một kiểu dữ liệu khác qua cơ chế chuyển đổi tường minh hoặc chuyển đổi ngầm định. việc chuyển đổi ngầm định được thực hiện tự động và phải đảm bảo không mất thông tin. Nghĩa là kiểu được chuyển đổi phải có kích thước lơn hơn.

Ví dụ : ta có thể gán ngầm định một số kiểu short vào một số kiểu int nhưng không thể ngược lại vì kích thước của kiểu int lớn hơn kích thước của kiểu short.

Cách ép kiểu đúng :

short x = 1 ;

int y = x ;

Cách ép kiểu sai :

short x ;

int y = 1 ;

x = y;

Phải ép kiểu tường minh như sau

short x ;

int y = 1 ;

x = (short)y;

2. Cú pháp lệnh và các khái niệm trong C#.

Ø Lớp (class) và đối tượng (objects) trong C#

Class là một khái niệm mô tả cho những thực thể có chung tính chất và hành vi. Class định nghĩa những thuộc tính và hành vi được dùng cho những đối tượng của lớp đó. Có thể nói Class là một khuôn mẫu cho các đối tượng.

Công thức để tạo một class

AccessModifier class [className]

{

// code

}

Đối tượng (Objects) là một đại diện, hay có thể nói là một sản phẩm của một class. Tất cả các đối tượng đều có chung những thuộc tính và hành vi mà class định nghĩa. Cách tạo đối tượng giống như cách tạo một biến có kiểu dữ liệu là Class.

Ví dụ : theo văn nói ta có thể mô tả như sau, một chiếc ô tô có những bộ phận như khung xe, màu xe, động cơ …, tất cả thông tin ấy được mô tả trong 1 class. Dựa trên mô tả đó, nhà sản xuất đưa ra được các mẫu xe khác nhau như có chiếc khung xe bằng thép, màu đỏ, động cơ BH-240 …, có chiếc khung lại bằng hợp kim nhôm, màu đen ….; tóm lại dựa trên class xe, sẽ có nhiều object xe khác nhau …

Hàm tạo (Constructors) và hàm hủy (Destructors) trong C#

Constructors là những hàm đặc biệt cho phép thực thi, điều khiển chương trình ngay khi khởi tạo đôi tượng. Trong C#, Constructors có tên giống như tên của Class và không trả lại giá trị. Một class có thể có nhiều contructor.

Ví dụ

class Oto

{

private string Color;

//Constructor

public Library()

{

Color = “White”;

}

public Oto(string value)

{

I Color = value;

}

}

Khi khởi tạo một object từ class này, nếu bạn không truyền tham số thì oto (object) này sẽ có color = “white” ngay khi nó được khởi tạo :

Oto oto_1 = new Oto(); // color là White

Do class cung cấp contructor cho phép gán giá trị color cho object khi được khởi tạo, nên bạn có thể tạo color cho object này ngay trong lệnh khởi tạo :

Oto oto_1 = new Oto(“Red”); // color lúc này là Red

Decontructor



Là một hàm đặc biệt được sử dụng để làm sạch bộ nhớ. Cách khai báo giống như Constructor nhưng không có tham số và được bắt đầu bằng dấu “~”. Bên trong thân Destructors, ta có thể dùng các lệnh giúp giải phóng bộ nhớ như hủy các kết nối đến database, đóng các luồng dữ liệu …

Ø Khái niệm namespace (không gian tên)

Nếu đã học Java bạn có thể hiểu namespace có ý nghĩa tương tự như package. Namespace giúp đóng việc đóng gói các class, các interface và các struct có liên quan thành một unit (đơn vị).

Cú pháp :

namespace namespace-name

{
// classes, interfaces, structs,...
}

Để khai báo sử dụng namespce ta dungf từ khóa using;

Ví dụ : using System ;

using System.Data ;

Hãy xem xét một ví dụ về cách sử dụng namespace trong lập trình. Chúng ta sẽ thấy có hai lớp Money đồng nhất trong khai báo và cài đặt, tuy nhiên C# xét chúng là hai lớp rõ rệt phân biệt bởi namespace khác nhau.

· Tác giả: Richard L. Week

· Mục đích: Làm rõ hơn về namespace (không gian tên)

CODE
using System;

namespace Foo

{
public class Money

{
private double m_Amount;
public Money()

{
Init(0.0);
}
public Money(double Amount)

{
Init(Amount);
}
public void Print()

{
Console.WriteLine("Foo.Money.Print{0}", m_Amount);
}
public void Init(double Amount)

{
m_Amount = Amount;
}
}
}

namespace Bar

{
public class Money

{
private double m_Amount;
public Money()

{
Init(0.0);
}
public Money(double Amount)

{
Init(Amount);
}
public void Print()

{
Console.WriteLine("Bar.Money.Print{0}", m_Amount);
}


public void Init(double Amount)

{
m_Amount = Amount;
}
}
}

public class NamespaceTest

{
public static void Main()

{
Foo.Money fm=new Foo.Money(5.00);
Bar.Money bm=new Bar.Money(5.00);
fm.Print();
bm.Print();
}
}

Có hai namespace đã được tạo ra là Foo và Bar. Một lớp Money tồn tại trong mỗi namespace. Để sử dụng mỗi lớp Money, trong phương thức Main của lớp NamespaceTest tạo một thể hiện của mỗi lớp bằng tên đầy đủ. Nếu có nhiều đối tượng có cùng tên thuộc về những namespace khác nhau, sử dụng tên đầy đủ thì hay hơn là dùng chỉ thị using.

(Còn tiếp ...)

Tu Khoa ----- Cơ bản lập trình hướng đối tượng C#

Kế thừa:
Một lớp A1 kế thừa lớp A nghĩa là lớp A1 chứa tất cả thuộc tính, phương thức là protected hoặc public của A.
Vd:
CODE

public class A {
public int a;
protected int b;
private int c;
/**
* constructor – Hàm khởi tạo - của lớp A.
*/
public A() {
a = 0;
b = 1;
c = 2;
}
public int getNextA() {
return a+1;
}
public int getNextB() {
return b+1;
}
public int getNextC() {
return c+1;
}
}
public class A1: A {
public void setA (int a) {
this.a = a;
}
public void setB (int b) {
this.b = b;
}
/**
* Hàm setC này sai (bị báo lỗi) vì không thể truy cập tới biến c.
*/
public void setC (int c) {
this.c = c;
}
/**
* hàm main sau sẽ in ra kết quả: a = 1; b = 2; c = 3;
*/
static void main() {
A1 a1 = new A1();
Console.WriteLine("a = " + a1.getNextA()
+ "; b = " + a1.getNextB()
+ "; c = " + a1.getNextC() + ";");
}
}
------------------------------------------------------------------------------
Từ khóa abstract:
Nếu lớp A là abstract thì lớp A không thể tự khởi tạo mà nó chỉ được dùng cho việc kế thừa.
vd:
CODE

public abstract class A {
private int a;
public A() {
a = 100;
}
public int getA() {
return a;
}
}
public class A1: A {
public A1() {
}
static void Main() {
A a = new A(); //--> sai
A1 a1 = new A1();
Console.WriteLine("a = " + a1.getA());//kết quả là: a = 100
}
}


Nếu phương setA của lớp A là abstract thì nó không được có phần thân hàm mà phần thân hàm sẽ được viết trong lớp kế thừa A. Lớp A cũng phải là abstract.
CODE

public abstract class A {
protected int a;
public A() {
a = 100;
}
public int getA() {
return a;
}
/**
* Nếu phương thức setA có phần thân hàm sẽ bị báo lỗi.
*/
abstract void setA(int a);
}

public class A1: A {
/**
* Nếu lớp A1 không có hàm setA thì sẽ bị báo lỗi.
*/
public void setA(int a) {
this.a = a;
}
static void Main() {
A1 a1 = new A1();
a1.setA(1);
Console.WriteLine("a = " + a1.getA());//kết quả là: a = 1
}
}
----------------------------------------------------------------------------------
Từ khóa interface:
Một lớp A là interface nghĩa là mọi phương thức, hàm đều không có phần thân hàm mà chỉ là liệt kê những phương thức, hàm cho các lớp khác implements. Nếu lớp A1 implements interface A và không có đủ các phương thức, hàm được liệt kê trong A thì sẽ bị báo lỗi.
Vd :
CODE

public interface A {
/**
* Trong C#, không được đưa các từ khóa public, private, protected
* vào trước hàm.
*/
int getNextA();
void setA(int a);
}
public class A1 {
private int a = 0;
static void Main() {
A a = new A1();
a.setA(10);
Console.WriteLine("a = " + a.getNextA());//kết quả là: a = 11
}
/**
* Nếu thiếu một trong 2 phương thức sau sẽ báo lỗi.
*/
public int getNextA() {
return a+1;
}
public void setA(int a) {
this.a = a;
}
}
---------------------------------------------------------------------------------
Từ khóa virtual và override:
Hàm getA là virtual nghĩa là nó cho phép các lớp con của nó override lên.
Vd:
CODE

public class A {
private int a = 0;
public virtual int getA() {
return a;
}
}
public class A1 {
private int b = 10;
public override int getA() {
return b;
}
}

Hãy xem thêm ví dụ sau để hiểu rõ hơn về virtual và override:
CODE

public class A {
public virtual string getName() {
return "A";
}
}
public class B: A {
public virtual string getName() {
return "B";
}
}
public class C: B {
public override string getName() {
return "C";
}
}
public class D: C {
/**
* Nếu hàm sau là override thì sẽ bị báo lỗi.
*/
public virtual string getName() {
return "D";
}
static void Main() {
D d = new D();
C c = d;
B b = c;
A a = b;
Console.WriteLine(a.getName() + "; "
+ b.getName() + "; "
+ c.getName() + "; "
+ d.getName() + "; ");
//kết quả là: A; C; C; D;
}
}
---------------------------------------------------------------------------
Từ khóa sealed:
Nếu lớp A là sealed thì lớp A sẽ không được kế thừa bởi bất kỳ lớp nào.
CODE

public sealed class A {
public a;
public A() {
}
//và các phương thức khác...
}
/**
* lớp A1 sau sẽ bị báo lỗi.
*/
public class A1: A {
}

Nếu phương thức getA là sealed thì phương thức này sẽ không thể bị override bởi các lớp con.
vd:
CODE

public class A {
public int a;
public A() {
a = 100;
}
public virtual int getA() {
return a;
}
}
public class A1: A {
public sealed override int getA() {
return a-1;
}
}
public class A2: A {
/**
* vì không thể override hàm getA --> bị báo lỗi.
*/
public override int getA() {
return a-1;
}
}
----------------------------------------------------------------------------
Từ khóa static:
Dùng để định nghĩa một biến của một lớp. Đây có thể coi như là một biến toàn cục, vì dù lớp chứa biến static được khởi tao bao nhiêu lần thì nó chỉ có duy nhất một biến static (nằm ở cùng một vùng nhớ). Biến static cũng được dùng để khai báo một phương thức.
Một phương thức static chỉ có thể truy cập tới biến static của class mà thôi.
Điều khác biệt của biến static trong C# và JAVA là C# không cho truy cập vào biến static ở một instance.
Vd :
CODE

public class Math {
public static double s_pi = 3.14;
public double m_pi = 3.14;
public static double calculateCircle(double r) {
return r*r*s_pi; //nếu dùng m_pi thì sẽ sai.
}
public double calculateNonStaticCircle(double r) {
return r*r*s_pi;
}
}
public class MathExecute {
static void Main() {
Console.WriteLine("pi = " + Math.s_pi);
Math.s_pi = 3.1412;
Math m = new Math();
Console.WriteLine("pi = " + m.calculateNonStaticCircle(10));
m.s_pi = 3.141; //sai
Console.WriteLine("pi = " + m.calculateCircle(10));//sai
}
}
-------------------------------------------------------------------------------
Từ khóa const và readonly:
Cả 2 từ khóa đều được dùng để chỉ định một giá trị là hằng số. readonly chỉ được phép dùng cho giá trị của lớp, const có thể dùng cho cả giá trị của lớp và giá trị của hàm. Bất cứ giá trị nào là const phải được khởi tạo lúc khai báo. Giá trị readonly là toàn cục cũng phải được khởi tạo lúc khai báo. Giá trị readonly không toàn cục có thể được khởi tạo trong constructor của lớp.
CODE

public class Math {
public static const double S_PI = 3.141;//nếu không gán giá trị sẽ bị báo lỗi
public readonly double M_PI;
public static readonly double S_MATH_PI = 3.14;//nếu không gán giá trị sẽ sai
/**
* Constructor.
*/
public Math() {
M_PI = 3.14;
S_PI = 3.14128;//sai
int const r = 10;//nếu không gán giá trị sẽ sai
int readonly r = 20;//sai
}
}
--------------------------------------------------------------------------
Từ khóa const và readonly:
Cả 2 từ khóa đều được dùng để chỉ định một giá trị là hằng số. readonly chỉ được phép dùng cho giá trị của lớp, const có thể dùng cho cả giá trị của lớp và giá trị của hàm. Bất cứ giá trị nào là const phải được khởi tạo lúc khai báo. Giá trị readonly là toàn cục cũng phải được khởi tạo lúc khai báo. Giá trị readonly không toàn cục có thể được khởi tạo trong constructor của lớp.

Xin bổ sung thêm như sau:
- const và readonly chỉ có thể sử dụng cho các kiểu dữ liệu giá trị (int, string, double...).
- readonly không cần phải khởi tạo giá trị ngay khi khai báo mà có thể khởi tạo giá trị trong hàm constructor (hàm khởi tạo) của lớp.
CODE
using System;
public class ReadOnlyTest
{
class MyClass
{
public int x;
public readonly int y = 25; // Initialize a readonly field
public readonly int z;

public MyClass()
{
z = 24; // Initialize a readonly instance field
}

public MyClass(int p1, int p2, int p3)
{
x = p1;
y = p2;
z = p3;
}
}

public static void Main()
{
MyClass p1= new MyClass(11, 21, 32); // OK
Console.WriteLine("p1: x={0}, y={1}, z={2}" , p1.x, p1.y, p1.z);
MyClass p2 = new MyClass();
p2.x = 55; // OK
Console.WriteLine("p2: x={0}, y={1}, z={2}" , p2.x, p2.y, p2.z);
}
}