封裝的概念
可以把程序按某種規則分成很多“塊“,塊與塊之間可能會有聯系,每個塊都有一個可變部分和一個穩定的部
分。我們需要把可變的部分和穩定的部分分離出來,將穩定的部分暴露給其他塊,而將可變的部分隱藏起來,以
便於隨時可以讓它修改。這項工作就是封裝.
例如:在用類實現某個邏輯的時候,類就是以上所說的塊,實現功能的具體代碼就是可變的部分,而public的
方法或者屬性則是穩定的部分。
封裝的意義
封裝的意義在於保護或者防止代碼(數據)被我們無意中破壞。在面向對象程序設計中數據被看作是一個中心的原素並且和使用它的函數結合的很密切,從而保護它不被其它的函數意外的修改。
封裝提供了一個有效的途徑來保護數據不被意外的破壞。相比我們將數據(用域來實現)在程序中定義為公用的(public)我們將它們(fields)定義為私有的(privat)在很多方面會更好。
私有的數據可以用兩種方式來間接的控制。下面我們看一些c#例子來學習這兩種方法用以封裝數據。第一種方法,我們使用傳統的存、取方法。第二種方法我們用屬性(property)。無論我們使用哪種的方法,我們的目標是在使用數據的同時不能使它受到任何的破壞和改變。有如下好處
其一: 使用者只需要了解如何通過類的接口使用類,而不用關心類的內部數據結構和數據組織方法。
其二:高內聚,低耦合一直是我們所追求的,用好封裝恰恰可以減少耦合
其三:只要對外接口不改變,可以任意修改內部實現,這個可以很好的應對變化
其四:類具有了簡潔清晰的對外接口,降低了使用者的學習過程
用傳統的讀、寫方法封裝
讓我們來看一個例子有一個類Department,為了操縱這個類中的數據(string departname)我們定義了一個讀方法和一個寫方法。
using system;
public class Department
{
private string departname;
.......
// 讀方法
public string GetDepartname()
{
return departname;
}
//寫方法
public void SetDepartname( string a)
{
departname=a;
}
}
通過上面的方法,我們可以保護私有數據不被外部程序所破壞。現在我們使用兩個不同的方法來寫和讀數據
public static int Main(string[] args)
{
Department d = new Department();
d.SetDepartname("ELECTRONICS");
Console.WriteLine("The Department is :"+d.GetDepartname());
return 0;
}
在上面的例子中,我們不能直接訪問類Department的實例d中的私有數據(string departname),我們只能通過這兩個方法來訪問。
用屬性來實現封裝
屬性是c#引入的一種語言成分,只有很少的語言支持屬性。通過對屬性的讀和寫來保護類中的域。第一種方法體身也是一種好的方式,但用屬性來實現封裝會更方便。
現在我們來看一個例子:
using system;
public class Department
{
private string departname;
public string Departname
{
get
{
return departname;
}
set
{
departname=value;
}
}
}
public class Departmentmain
{
public static int Main(string[] args)
{
Department d= new Department();
d.departname="Communication";
Console.WriteLine("The Department is :{0}",d.Departname);
return 0;
}
}
通過上面的例子,我們可以看到如何通過屬性來實現封裝。屬性具有兩種操作get和set。Get用來返回屬性域的值。Set通過value這個變量來給屬性域賦值。屬性可以設為只讀的(read-only)。這只需屬性只具有一個set操作。
只讀屬性
using system;
public class ReadDepartment
{
private string departname;
public ReadDepartment(string avalue)
{
departname=avalue;
}
public string Departname
{
get
{
return departname;
}
}
}
public class ReadDepartmain
{
public static int Main(string[] args)
{
ReadDepartment d= new ReadDepartment("COMPUTERSCIENCE");
Console.WriteLine("The Department is: {0}",d.Departname);
return 0;
}
}
在上面的例子中我們看到了如何來實現一個只讀的屬性。類ReadDepartment擁有一個Departname屬性只實現了get操作。它省略了寫操作。這個特別的類擁有一個構造器,用來接受一個字符串變量。類ReadDepartmain中的Main方法創建了一個新的對象d。對像d的實例使用了類ReadDepartment帶有一個字符串參數的構造器。因為上面的屬性是只讀的,所以我們不給給域departname賦值並且我們只側讀取此域中的值。當然屬性也可以是只寫的(write-only),這只需屬性只具有一個get操作。
只寫屬性
using system;
public class WriteDepartment
{
private string departname;
public string Departname
{
set
{
departname=value;
Console.WriteLine("The Department is :{0}",departname);
}
}
}
public class WriteDepartmain
{
public static int Main(string[] args)
{
WriteDepartment d= new WriteDepartment();
d.departname="COMPUTERSCIENCE";
return 0;
}
}
在上面的例子中我們看到了如何來實現一個只寫的屬性。類WriteDepartment擁有一個Departname屬性只實現了set操作。它省略了讀操作。
總結
封裝是朝着面向對象程序設計邁出的第一步。本文向您展示了一些封裝的知識。用傳統的讀、寫兩種方法可以實現封裝,另一種實現封裝的方法是使用屬性。使用屬性的好處在於對象的使用者可以用一條語句來操作內部的數據。