以操做數據庫爲例:
既然是操做數據庫就必須會用到 Insert Update Select ,因此Insert Update Select 作成接口數據庫
可是,每一個功能操做的內容又不同,因此,作一個抽象類繼承接口而後抽象類的派生類去實現抽象類的具體方法ide
面向對象,就是要把一些代碼上的東西當成實體來理解.實體有自己的屬性和行爲.好比你這個對數據庫的操做,你就要把數據庫當作一個對象,其行爲能夠是增刪改查.因此你應該聲明一個類去進行這些操做.
固然,考慮到各類業務的特性,你還能夠將這些類抽象出來,聲明一個接口類,爲數據庫接口類.其實現類爲各業務的具體操做..this
一、接口是一組規則的集合,它規定了實現本接口的類或接口必須擁有的一組規則
二、抽象類和接口的區別在於使用動機。使用抽象類是爲了代碼的複用,而使用接口的動機是爲了實現多態性。spa
假設有2個類,一個類是主力球員,一個類是替補球員。設計
1 public class NormalPlayer 2 { 3 public int ID 4 { 5 get; 6 set; 7 } 8 public string FirstName 9 { 10 get; 11 set; 12 } 13 public string LastName 14 { 15 get; 16 set; 17 } 18 public decimal WeekSalary 19 { 20 get; 21 set; 22 } 23 public string GetFullName() 24 { 25 return this.FirstName + " " + this.LastName; 26 } 27 public decimal GetDaySalary() 28 { 29 return WeekSalary / 7; 30 } 31 } 32 public class SubPlayer 33 { 34 public int ID 35 { 36 get; 37 set; 38 } 39 public string FirstName 40 { 41 get; 42 set; 43 } 44 public string LastName 45 { 46 get; 47 set; 48 } 49 public decimal MonthSalary 50 { 51 get; 52 set; 53 } 54 public string GetFullName() 55 { 56 return this.FirstName + " " + this.LastName; 57 } 58 public decimal GetWeekSalary() 59 { 60 return MonthSalary / 4; 61 } 62 }
咱們發現,NormalPlayer和SubPlayer有共同的屬性和方法,固然也有不一樣的屬性和方法。把2個類的共同部分抽象出一個基類。code
1 public class BasePlayer 2 { 3 public int ID 4 { 5 get; 6 set; 7 } 8 public string FirstName 9 { 10 get; 11 set; 12 } 13 public string LastName 14 { 15 get; 16 set; 17 } 18 19 public string GetFullName() 20 { 21 return this.FirstName + " " + this.LastName; 22 } 23 }
而後讓先前的2個類派生於這個基類。orm
1 public class NormalPlayer: BasePlayer 2 { 3 public decimal WeekSalary 4 { 5 get; 6 set; 7 } 8 public decimal GetDaySalary() 9 { 10 return WeekSalary / 7; 11 } 12 } 13 public class SubPlayer : BasePlayer 14 { 15 public decimal MonthSalary 16 { 17 get; 18 set; 19 } 20 public decimal GetWeekSalary() 21 { 22 return MonthSalary / 4; 23 } 24 }
接着,咱們發現NormalPlayer和SubPlayer計算日薪和週薪的方法也能夠抽象出來,做爲虛方法放到基類中對象
public class BasePlayer { public int ID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string GetFullName() { return this.FirstName + " " + this.LastName; } public virtual decimal GetSalary() { throw new NotImplementedException(); } }
在NormalPlayer和SubPlayer這2個派生類中,須要重寫基類的虛方法blog
public class NormalPlayer: BasePlayer { public decimal WeekSalary { get; set; } //獲取日薪 public override decimal GetSalary() { return WeekSalary / 7; } } public class SubPlayer : BasePlayer { public decimal MonthSalary { get; set; } //獲取週薪 public override decimal GetSalary() { return MonthSalary / 4; } }
但在實際狀況中,BasePlayer只是一個抽象出來的類,咱們並不但願實例化這個類。這時候,就能夠把BasePlayer設計爲abstract抽象類。同時,在抽象類中,提供一個計算薪水的抽象方法。一旦在基類中聲明瞭沒有方法體的抽象方法,全部派生於這個抽象類的類必須實現或重寫基類中的抽象方法。
查看源代碼打印幫助繼承
public abstract class BasePlayer { public int ID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string GetFullName() { return this.FirstName + " " + this.LastName; } public abstract decimal GetSalary(); }
因而可知,當2個或多個類中有重複部分的時候,咱們能夠抽象出來一個基類,若是但願這個基類不能被實例化,就能夠把這個基類設計成抽象類
理解:
一、抽象類裏面能夠有非抽象方法但接口裏只能有抽象方法 聲明方法的存在而不去實現它的類被叫作抽像類(abstract class),它用於要建立一個體現某些基本行爲的類,併爲該類聲明方法,但不能在該類中實現該類的狀況。...
二、抽象類不能直接new對象,它只能被繼承,並且單一繼承。也就是說它把公共的東西抽象出來,子類能夠調用父類的方法,也能夠拓展本身的功能,就像子承父業同樣。接口能夠被屢次繼承,這是和抽象類的最大區別。也就是說接口是一個公共用品誰均可以拿來用的,不想抽象類,不是他的子類是不能調用的。但願對你有幫助
三、當描述一組方法的時候使用接口 當描述一個虛擬的物體的時候使用抽象類