Thứ Hai, 9 tháng 3, 2009

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);
}
}

Không có nhận xét nào: