封裝優點:
1.好的封裝能減少耦合.
2.類的內部的實現可以自由改變.
3.一個類有更清楚的接口.
data hiding(數據隱藏):封裝的一個最有用的形式是數據隱藏.一個類的數據表現一個對象的狀態.
修飾符支持封裝:
private:只有類本身能存取.
protected:類和派生類可以存取.
internal:只有同一個項目中的類可以存取.
protected internal:是protected和internal的結合.
public:完全存取.
other encapsulating strategy:(其他封裝策略)屬性和索引器的目的是封裝一個類的細節和給類的用戶提供一個公共的接口.
封裝和繼承的關系:
封裝的意思是包容(聚合),類與類之間的關系是"has a".一個類里面有另一個類.
繼承,類與類之間的關系是"is a".
多態(polymorphism):就是怎樣重載一個虛擬類.多態是面向對象的重要概念.
implementing polymorphism(實現多態):
例子:
using system;
public class website
{
public string sitename;
public string url;
public string description;
public website()
{
}
public website( string strsitename, string strurl, string strdescription )
{
sitename = strsitename;
url = strurl;
description = strdescription;
}
public override string tostring()
{
return sitename + ", " +
url + ", " +
description;
}
}
abstract public class contact
{
public virtual string updatenotify()
{
return "web site change notification";
}
}
public class customer : contact
{
public new string updatenotify()
{
return @"
this is to let you know your
favorite site, financial times,
has been updated with new links";
}
}
public class siteowner : contact
{
website mysite;
public siteowner(string aname, website asite)
{
mysite = new website(asite.sitename,
asite.url,
asite.description);
}
public new string updatenotify()
{
return @"
this is to let you know your site, " + "\n" +
mysite.sitename + @", has been added as
a link to financial times.";
}
}
public class test
{
public static void main()
{
website lefin = new website("le financier",
"http://www.lefinancier.com",
"fancy financial site");
contact[] contacts = new contact[2];
contacts[0] = new siteowner("pierre doe", lefin);
contacts[1] = new customer();
foreach (contact poc in contacts)
{
if (poc is siteowner)
{
console.writeline("message: {0}\n",
((siteowner)poc).updatenotify());
}
else
{
console.writeline("message: {0}\n",
((customer)poc).updatenotify());
}
}
}
}
在例子中,contact類有個虛擬方法,有兩個派生類分別實現.使用了"new"關鍵字.
可以有更有效和優雅的方法,實現它,就是多態.
例子:
using system;
abstract public class contact
{
public virtual string updatenotify()
{
return "web site change notification";
}
}
public class customer : contact
{
public override string updatenotify()
{
return @"
this is to let you know your
favorite site, financial times,
has been updated with new links";
}
}
public class siteowner : contact
{
string sitename;
public siteowner(string sname)
{
sitename = sname;
}
public override string updatenotify()
{
return @"
this is to let you know your site, " + "\n" +
sitename + @", has been added as
a link to financial times.";
}
}
public class test
{
public static void main()
{
contact[] contacts = new contact[2];
contacts[0] = new siteowner("le financier");
contacts[1] = new customer();
foreach (contact poc in contacts)
{
console.writeline("message: {0}\n",
poc.updatenotify());
}
}
}
例子中,派生類用"override"實現了多態.
虛擬方法是允許多態工作的基類的方法.用"override"修飾符說明,能被派生類重載.虛擬方法和抽象方法的不同
時,虛擬方法有實現,抽象方法沒有.抽象方法,隱式說明是虛擬,必須被重載;虛擬方法不必被重載.
多態,必須是虛擬方法,而且,方法的簽名必須一致,包括方法名稱,參數,和參數類型.
例子:
abstract public class contact
{
public virtual string updatenotify()
{
return "web site change notification";
}
}
public class customer : contact
{
public override string sendmail() {}// error
public override string updatenotify(int number) {}// error
}
例子中,sendmail不是虛擬方法,故錯誤;updatenotify,帶有不同的參數,故也錯誤.
new 和 override 修飾符,都可以實現新的方法.但,new 實現的是派生類新的方法.
例子:
using system;
abstract public class contact
{
public virtual string updatenotify()
{
return "web site change notification";
}
}
public class customer : contact
{
public new string updatenotify()
{
return @"
this is to let you know your
favorite site, financial times,
has been updated with new links";
}
}
public class siteowner : contact
{
string sitename;
public siteowner(string sname)
{
sitename = sname;
}
public override string updatenotify()
{
return @"
this is to let you know your site, " + "\n" +
sitename + @", has been added as
a link to financial times.";
}
}
public class test
{
public static void main()
{
contact[] contacts = new contact[2];
contacts[0] = new siteowner("le financier");
contacts[1] = new customer();
foreach (contact poc in contacts)
{
console.writeline("message: {0}\n",
poc.updatenotify());
}
}
}
結果是:
message:
this is to let you know your site,
le financier, has been added as
a link to financial times.
message: web site change notification
例子中,customer 用"new"實現新的方法,但是,在運行是不是多態.仍然調用基類的方法.
most-derived implementations(多重派生實現)
polymorphic properties(多態的屬性):c#允許,屬性的多態實現.
例子:
using system;
public class sitestats
{
public int numberofvisits = 0;
}
abstract public class contact
{
protected string name;
public virtual string name
{
get
{
return name;
}
set
{
name = value;
}
}
}
public class customer : contact
{
sitestats mystats = new sitestats();
public override string name
{
get
{
mystats.numberofvisits++;
console.writeline("number of visits: {0}",
mystats.numberofvisits);
return name;
}
set
{
base.name = value;
mystats.numberofvisits = 0;
console.writeline("name: {0}", name);
}
}
}
public class test
{
public static void main()
{
contact mycontact = new customer();
mycontact.name = "george";
}
}
例子中,抽象類,有屬性name,派生類重載實現了屬性.
polymorphic indexers(多態的索引器):索引器的多態.
例子:
using system;
using system.collections;
public class sitelist
{
protected sortedlist sites;
public sitelist()
{
sites = new sortedlist();
}
public int nextindex
{
get {
return sites.count;
}
}
public virtual string this[int index]
{
get
{
return (string) sites.getbyindex(index);
}
set
{
sites[index] = value;
}
}
}
public class financialsitelist : sitelist
{
public override string this[int index]
{
get
{
console.writeline("financialsitelist indexer get");
if (index > sites.count)
return (string)null;
return base[index];
}
set
{
console.writeline("financialsitelist indexer set");
base[index] = value;
}
}
}
class sitemanager
{
sitelist sites = new sitelist();
public static void main()
{
sitemanager mgr = new sitemanager();
mgr.sites = new financialsitelist();
mgr.sites[mgr.sites.nextindex] = "great site!";
console.writeline("site: {0}",
mgr.sites[0].tostring());
}
}
例子中,基類的索引器是"virtual",派生類重載了索引器.