Đối tượng là tham số của hàm Mở rộng lớp Circle với thương thức so sánh với Circle khác.. Phương thức tĩnh• Phương thức độc lập với đối tượng cụ thể • Thí dụ lớp Math với các phương thứ
Trang 1Lập trình hướng đối tượng
Bài 13: Giới thiệu C#
Trang 2Nội dung
• Giới thiệu NET và C#
• Lập trình cấu trúc với C#
• Quản lý ngoại lệ
• Lập trình hướng đối tượng trong C#
• Giá trị và tham chiếu
Trang 3.Net Platform
• Là nền tảng lập trình và cũng là nền tảng thực
thi ứng dụng
• 2 thành phần chính là:
– Common Language Runtime
– Base Class Library
Trang 4Ngôn ngữ C#
• Đơn giản
– Loại bỏ những phức tạp có trong Java hay C++ như
macro, template, đa kế thừa, virtual base class
– Giống về diện mạo cú pháp C và C++ nhưng được cải tiến đơn giản hơn (Ví dụ : “:: , , ->” chỉ còn “.”
Trang 5Thí dụ
Trang 6Một số lưu ý
• Trong C# mọi thứ nằm trong lớp
– Không như C và C++
• Mọi chương trình C# phải có hàm Main
• C# phân biệt chữ hoa, chữ thường
• Chương trình thực hiện được gọi là assembly
Trang 7Dạng dữ liệu cơ bản
int 32 bit integer
long 64 bit integer
float 32 bit floating point
double 64 bit floating point
char thể hiện Unicode 16 bits
string là dạng có thể được gán và so sánh.
decimal 28 significant digits
bool là dạng giá trị true và false
Trang 8Các thay đổi so với C
• Phải gán giá trị cho biến trước khi sử dụng nó
• Lệnh if đòi hỏi biểu thức giá trị bool hoặc biến
}
Trang 12Mọi case trong lệnh switch phải có break
static void Main(string[ ] args)
{
string color = "";
suit trumps = suit.clubs;
switch (trumps) {
Trang 15Sử dụng ngoại lệ
Quản lý ngoại lệ đối với các vấn đề không mong muốn
Dữ liệu tồi
Điều kiện không thể
Không sử dụng với các luồng điều khiển
thông thường
Kết thúc vòng lặp
Kết thúc file
Trang 18Ngoại lệ được chuyển tiếp lên trên nếu không được bắt
static int Divide (int lhs, int rhs)
Console.WriteLine("Error: " + ex.Message);
} }
2 Divide throws exception
(No handler)
1 Call function (rhs == 0)
3 Continue here
Trang 21check và uncheck tràn số nguyên
Mặc định số học số nguyên không được kiểm tra
Tràn số nguyên không phát ra ngoại lệ.
Kiểm tra tràn số nguyên có thể thực hiện
Với toàn dự án
Với các khối code riêng biệt
Với các biểu thức riêng biệt
Trang 22static void Main(string[] args)
Trang 27Lựa chọn trình dịch check
Click here
Trang 28Tất cả số học số nguyên của project sẽ được check
Click OK
Trang 29static void Main(string[] args)
Trang 31case 1 : return "January";
case 2 : return "February";
//
case 12 : return "December";
default : throw new ArgumentOutOfRangeException("Bad Month");
}
}
Lớp được xác định trong không gian tên System
Trang 32Khối finally
Thỉnh thoảng cần đoạn mã để cleanup thậm chí nếu
có ngoại lệ và phương thức không được thực hiện trọn vẹn
// Do something with line.
// May result in an exception.
}
reader.Close();
Trang 33StreamReader reader;
try
{
string line;
reader = new StreamReader(@"c:\test.txt");
while ((line = reader.ReadLine()) != null)
{
// Do something with line.
// May result in an exception.
Trang 34Lập trình hướng đối tượng với
C#
Trang 35Đóng gói • Biến thành phần được gọi là trường (• Hàm thành phần được gọi là phương thức (field ). method ).Interface đối ngược với Implementation
Trang 36Tạo đối tượng
Định nghĩa lớp không cung cấp bộ nhớ cho các
trường dữ liệu của nó
(Ngoại trừ trường tĩnh - static)
Tạo thể hiện của lớp
static void Main(string[ ] args) {
Circle c;
c = new Circle();
}
Trang 37Call function Area() of Circle object c1
Trang 38Thiết lập
Sử dụng phương thức thiết lập để thiết đặt giá trị
khởi tạo cho trường dữ liệu
Phương thức thiết lập là phương thức có cùng tên
với tên lớp Nó được gọi khi ta gọi new để tạo thể
hiện của lớp
Không như C++, trong C# ta phải gọi toán tử new để tạo đối tượng.
chỉ khai báo biến dạng lớp không tạo đối tượng.
Trang 39Phương thức thiết lập cho lớp Circle.
}
Phương thức thiết lập không trả ra giá trị
Trang 40Calls constructor
Trang 41Area of Circle c1
Trang 42Lớp Circle
New member New constructor
Accessor Methods
Trang 45Đối tượng là tham số của hàm
Mở rộng lớp Circle với thương thức so sánh với Circle khác.
Từ khóa "this" Gọi phương thức Radius() của
đối tượng là tham số.
Trang 46Sử dụng phương thức Is_Greater_Than
static void Main(string[] args)
{
Circle Circle_A = Create_Circle();
Console.Write ("Circle " + Circle_A.Name() );
Console.WriteLine (" created with radius " + Circle_A.Radius()); Console.WriteLine ("Its area is " + Circle_A.Area());
Circle c2= Create_Circle();
Console.Write ("Circle " + c2.Name() );
Console.WriteLine (" created with radius " + c2.Radius());
Console.WriteLine ("Its area is " + c2.Area());
Trang 47if (c1.Is_Greater_Than(c2))
{
Console.Write ("Circle " + c1.Name() + " is greater than ");
Console.WriteLine( "Circle " + c2.Name());
}
else if (c2.Is_Greater_Than(c1))
{
Console.Write ("Circle " + c2.Name() + " is greater than ");
Console.WriteLine( "Circle " + c1.Name());
Trang 51Phương thức tĩnh
• Phương thức độc lập với đối tượng cụ thể
• Thí dụ lớp Math với các phương thức Sin, Cos,
Sqrt,…
• Các hàm này không cần bất cứ dữ liệu nào ở
Math Chúng chỉ sử dụng các giá trị tham số
truyền vào Do đó không có lý do gì cần thể hiện đối tượng của Math
Trang 52} Lưu ý: Nếu lớp có trường dữ liệu
không tĩnh nào đó thì các phương thức tĩnh không thể tham chiếu tới nó.
Trang 53Lớp tĩnh
• Có chỉ các phương thức tĩnh
• Không thể thể hiện (không tạo được đối tượng)
• Math là một lớp tĩnh
Trang 54Từng phần lớp
• Trong C# 1 lớp có thể được định nghĩa trong
nhiều file
– Hữu dụng cho các lớp với nhiều phương thức
– Microsoft dùng để tách phần mã người dùng viết và
phần mã do chương trình tự sinh.
• Định nghĩa lớp được chia vào nhiều file, trong mỗi
file lớp phải được khai báo với từ khóa partial
Trang 55Thí dụ
Trong file circ1.cs
partial class Circle
{
// Part of class defintion
}
Trong file circ2.cs
partial class Circle
{
// Another part of class definition
Trang 57Giá trị và tham chiếu
Trang 58Các dạng giá trị
• Các dạng buit-in như int được gọi là các dạng giá trị
• Biến dạng int giữ giá trị của biến
• Khi gán tới 1 biến khác, copy giá trị tới biến đó
Giá trị của j giờ là 42
Trang 59Các dạng tham chiếu
Các biến của dạng phức được gọi là các biến
tham chiếu (reference variable).
Giữ các tham chiếu chứ không phải giá trị
Ngoại trừ ta không thể nhận giá trị số của nó
Không bỏ tham chiếu được (dereference)
Chỉ có thể sử dụng nó để truy cập đối tượng mà
nó đang tham chiếu tới
Trang 60Khai báo dạng tham chiếu
Circle c1; // Bộ nhớ cung cấp chỉ cho
Circle c2; // tham chiếu.
c1 = new Circle(5); // Tạo đối tượng
// Cung cấp bộ nhớ
c2 = c1; // c2 và c1 cùng tham chiếu tới 1 đối tượng
Lệnh gán không tạo đối tượng mới.
Bộ nhớ không được cấp phát bởi lệnh gán.
Trang 61Thí dụ
using System;
class Circle
{
private String name;
private double radius = 0.0;
public Circle(String n, double r)
{
name = n;
radius = r;
}
public String Name() { return name; }
public double Radius() { return radius; }
public double Area()
{
return Math.PI * radius * radius;
}
Trang 62public bool Is_Greater_Than(Circle other)
Trang 67Biến được truyền vào phương thức
• Khi truyền biến dạng giá trị vào phương thức, phương thức nhận bản copy giá trị.
• Phương thức có thể biến đổi bản copy
– Nhưng điều này không ảnh hưởng tới giá trị gốc được sử dụng bởi người gọi.
Trang 68Console.WriteLine ("Back from Set_Int");
Console.WriteLine ("The value of myInt is {0}", myInt); Console.ReadLine();
}
}
Trang 70Truyền Circle tới phương thức
public class Circle
{
private String name;
private double radius;
public String Name () {return name; }
public double Radius() {return radius;}
public double Area() {return 3.141592 * radius * radius;}
public void Set_Radius (double new_radius)
{
radius = new_radius;
}
Trang 72static void Main(string[] args)
{
Circle myCircle = new Circle ("Circle A", 10);
Console.WriteLine ("The radius of {0} is {1}",
myCircle.Name(), myCircle.Radius());
Console.Write ("Calling Set_Circle_Radius to set radius of " ); Console.WriteLine ("{0} to 100", myCircle.Name());
Set_Circle_Radius(myCircle, 100);
Console.WriteLine ("Back from Set_Circle_Radius");
Console.WriteLine ("The radius of {0} is {1}",
myCircle.Name(), myCircle.Radius());
Console.ReadLine();
}
Trang 74Gọi bởi tham chiếu
Có thể viết phương thức lấy tham chiếu (reference) tới
dạng giá trị như đối số
Giống sử dụng tham chiếu như tham số trong C++
Tương tự việc sử dụng con trỏ như tham số trong C.
Thay vì chuyển giá trị tới phương thức, người gọi
chuyển tham chiếu tới giá trị
Người gọi phải đặt trước đối số từ khóa “ref”.
Điều này cho phép phương thức biến đổi biến của người gọi
Trang 75Console.WriteLine ("Back from Set_Int");
Console.WriteLine ("The value of myInt is {0}", myInt); Console.ReadLine();
Trang 77Tham chiếu tới dạng tham chiếu
static void Set_Circle_Radius(Circle target,
double value)
{
Console.WriteLine("Setting target to refer to new Circle");
Console.WriteLine("of radius {0} ", value);
target = new Circle("Circle B", value);
Trang 78Trong Main(), myCircle vẫn tham chiếu tới
đối tượng Circle và nó không đổi.
Trang 79 Biến đổi phương thức để xác lập tham chiếu.
Cũng biến đổi lời gọi
static void Set_Circle_Radius( ref Circle target,
double value)
{
Console.WriteLine("Setting target to refer to new Circle");
Console.WriteLine("of radius {0} ", value);
target = new Circle("Circle B", value);
}
Trang 80static void Main(string[] args)
Set_Circle_Radius(ref myCircle, 100);
Console.WriteLine("Back from Set_Circle_Radius");
Console.WriteLine("The radius of {0} is {1}",
myCircle.Name(), myCircle.Radius());
Console.ReadLine();
}
Trang 81Trong Main, myCircle giờ tham chiếu tới đối tượng
Circle khác.
Trang 82Tham số “out”
Tham số “out” giống tham số “ref”, ngoại trừ:
Phương thức chỉ có thể viết tới nó
Phương thức phải viết tới nó
Người gọi phải đặt trước tham số từ khóa
“out”
(biến không cần khởi tạo).
Trang 83Console.WriteLine ("Back from Set_Int");
Console.WriteLine ("The value of myInt is {0}", myInt); Console.ReadLine();
}
Trang 85Giá trị null và dạng nullable
Các dạng tham chiếu có thể có giá trị null.
Không có cách nào xác lập dạng giá trị là
không thiết lập (not set).
Trang 88Stack và Heap
Stack được sử dụng cho các tham số và các biến địa phương của phương thức.
Như trong C.
Khi các lời gọi kế tiếp được tạo, các tham số và biến địa
phương của mỗi lần gọi được bổ sung và stack.
Cũng trả ra địa chỉ
Do đó gọi là “ngăn xếp”.
Khi phương thức kết thúc hay phát ra ngoại lệ, biến địa
phương và tham số của nó được lấy ra khỏi stack.
Trang 89 Bộ nhớ cho đối tượng được tạo với từ khóa new
được cung cấp trên Heap
Giống malloc trong C và new trong C++.
Khi phương thức mà tạo đối tượng hoàn thành,
không gian không tự động được thu hồi Đối tượng
có thể vẫn được truy cập
Không như C và C++ ta không cần phải giải phóng
bộ nhớ được cung cấp trên Heap
Chúng sẽ được giải phóng một cách tử động bởi bộ thu hồi bộ nhớ (Garbage Collector) tại một thời điểm nào đó sau khi tất cả các tham chiếu tới chúng đã được giải
phóng.
Trang 90Lưu ý
Heap không phải là vô hạn.
Garbage collection chỉ giải phóng bộ nhớ
được sử dụng bởi các đối tượng mà không còn tham chiếu nào trỏ tới.
Nếu ta tạo quá nhiều đối tượng mà có tham chiếu, ta có thể nhận ngoại lệ
OutOfMemoryException.
Trang 91Thí dụ
class Circle
{
private string name;
private double radius = 0;
private Circle My_Model;
Trang 93Ngoại lệ OutOfMemory
Tạo nhiều hơn 70,000,000 đối tượng Circle trước khi phát ra ngoại lệ
OutOfMemor.
Có thể phải đợi vài phút!
Catch không bắt ngoại lệ OutOfMemory.
Trang 94 Trong C# tất cả các lớp được dẫn xuất từ lớp
System.Object
Chúng ta sẽ xem xét lớp dẫn xuất sau
Tương tự lớp dẫn xuất trong C++.
Đối tượng của bất cứ lớp nào cũng có các thành
viên của lớp System.Object
C# cung cấp bí danh “object”
Đồng nhất tới “System.Object”
Lưu ý viết chữ thường.
Trang 95 Tham chiếu tới các đối tượng.
Circle c1;
c1 = new Circle("Circle_42", 42);
object o;
o = c1;
Trang 97 Phải tham chiếu tới một vị trí trên heap.
Biến i là giá trị trên stack
Trang 98Điều này được gọi là boxing.
o tham chiếu tới copy của i.
Thay đổi không ảnh hưởng lẫn nhau.
Trang 99Phải chuyển kiểu o.
int j = (int) o; // This does work.
Điều gì xảy ra nếu o không tham chiếu tới biến nguyên?
Trang 100Chuyển kiểu an toàn
Trang 101static void Main(string[] args)
Trang 102Toán tử as
• Nhận giá trị null nếu không chuyển được kiểu
• Chỉ áp dụng với dạng tham chiếu và dạng nullable
static void Main(string[] args)