1. 在程式開發的過程會遇到各種情境
2. 物件導向程式設計的4個重要特性
2.1. 抽象
- 將真實世界的需求轉換成為OOP中的類別
- 類別可以包含狀態(屬性)與行為(方法)
例如我們要做一個CRM,然後分析需要哪些TABLE,接著建立出相對應的類別,類別裡面就有屬性跟方法,這個過程我們叫做抽象。
抽象是從需求轉換而來的
2.2. 封裝
- 隱藏/保護內部實作的細節,並可以對屬性或方法設定存取層級(public,private,protected)。
2.3. 繼承
- 可讓您建立新類別以重複使用、擴充和修改其他類別中定義的行為。
2.4. 多型
- 在相同的介面下,可以用不同的型別來實現。
- 多型有分成好幾種不同類型。
3. 從需求或規格中的進行”抽象化”的過程
- 我們將建立新客戶管理系統
- 該系統必須管理商業、住宅、政府、和教育類型的
客戶
- 我們必須最小程度地紀錄客戶的
姓名
、姓氏
、名字
、電子郵件地址
以及住家地址
和工作地址
- 它必須管理
產品
,我們必須最小程度地記錄產品名稱
、描述
和當前價格
3.1. 透過”抽象化”過程定義出類別
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class Customer { public int CustomerId { get; private set; } public string LastName { get; set; } public string FirstName { get; set; } public string EmailAddress { get; set; } public string HomeAddress { get; set; } public string WorkAddress { get; set; } public bool Validate() { return true; } public void Save() { } public void Load() { } }
public class Product { public int ProductId { get; private set; } public string ProductName { get; set; } public string ProductDescription { get; set; } public decimal? CurrentPrice { get; set; } }
|
3.2. 對實作的細節進行”封裝”(隱藏、保護)
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
| public class Product { public Product(int productId) { this.ProductId = productId; }
public int ProductId { get; private set; } public string ProductName { get; set; } public string ProductDescription { get; set; } private decimal? currentPrice; public decimal? CurrentPrice { get { return currentPrice; } set { if (value == null || value >= 0) { currentPrice = value; } else { currentPrice = null; } } }
public Product Retrieve(int productId) { return new Product(); }
protected bool Save() { return true; }
protected bool Validate() { var isValid = true;
if (string.IsNullOrWhiteSpace(ProductName)) isValid = false; if (CurrentPrice == null) isValid = false;
return isValid; } }
|
3.3. 透過”繼承”來重複利用、擴充和修改基底類別的定義
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
| class BaseClass { public string Name { get; set; } public int Age { get; set; } public virtual void Output() => Console.WriteLine("Hello");
public BaseClass(string name) => Name = name; public BaseClass() => Name = ""; }
class DerivedClass : BaseClass { public string Department { get; set; }
public DerivedClass() : base("Default") { base.Age = 18; base.Output();
this.Age = 19; this.Department = "IT"; this.Output(); }
public override void Output() => Console.WriteLine("Hello !!"); }
|
3.4. 在C#中所有類型都是 “多型”
在設計時期(Design Time)
- 基底類別可以定義和實作「虛擬」屬性或方法(virtual)
- 衍生類別可以「覆寫」這些虛擬的屬性或方法(override)
在執行時期(Runtime)
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
| public class Shape { public int X { get; private set; } public int Y { get; private set; } public int Height { get; set; } public int Width { get; set; }
public virtual void Draw() { Console.WriteLine("Performing base class drawing tasks"); } }
public class Circle : Shape { public override void Draw() { Console.WriteLine("Drawing a circle"); base.Draw(); } } public class Rectangle : Shape { public override void Draw() { Console.WriteLine("Drawing a rectangle"); base.Draw(); } } public class Triangle : Shape { public override void Draw() { Console.WriteLine("Drawing a triangle"); base.Draw(); } }
|
在C#中,所有類型都是多型類型
- 因為所有類型(包括使用者定義的類型)都是繼承自Object
如果要在C#中設計防止衍生類別覆寫虛擬成員
1
| public sealed override void DoWork(){}
|
- 多載(Overloading)比較有點爭議(有些人認為這不算多型)