OOP三特性:繼承、封裝、多态
繼承:C#屬于單繼承,即派生類最多隻能有一個直接基類,但可以傳遞繼承,即A類派生B類,B類派生C類,派生類會保留所有基類以及傳遞基類的字段、屬性、方法等所有内容。如果要在派生類中隐藏基類内容,可以通過new關鍵字實作,或是通過base來調用基類的内容
傳遞繼承示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 繼承
{
public class Program
{
public class A
{
public string _fieldA = "A類字段";
public int PropertyA { get; set; }
//如果要提供一個示例方法,則使用virtual關鍵字修飾,派生類如果不重寫virtual方法,則使用基類提供的virtual方法,且必須有對應的實作,重寫則使用重寫方法
//如果隻提供一個規範,則使用abstract關鍵字,注意abstract方法隻能在abstract類中使用,而且沒有任何實作,且必須在派生類中重寫,除非派生類也是抽象類(抽象派生類會直接繼承抽象方法而不實作)
public virtual void FuncA()
{
Console.WriteLine("A類示例方法FuncA");
}
}
public class B : A
{
public string _fieldB = "B類字段";
public override void FuncA()
{
Console.WriteLine("重寫A類方法");
}
}
public class C : B
{
public string _fieldC = "C類字段";
}
static void Main(string[] args)
{
C c = new C();
Console.ReadKey();
}
}
}
傳遞繼承如圖,執行個體方法的調用必須基于有一個對象,而靜态方法不屬于對象,可以直接調用。
抽象類:使用abstract關鍵字建立不完整且必須在派生類中實作的類和class成員。使用sealed可以防止繼承以前标記為virtual的類或某些成員。抽象類用于繼承,故隐式的為public,且不可被private、protected、internal修飾。
注意:1.基類virtual方法若不在派生類中override重寫,則對派生類執行個體調用會使用基類的virtual方法,相當于預定義
2.若基類virtual方法在派生類override重寫,則對派生類執行個體調用會使用重寫的override方法
3.抽象方法隻能在抽象類中修飾,且沒有實作,結束時一個分号,必須在派生類中override實作
接口:
1.由于C#是單繼承,要實作多重繼承可以通過接口實作,C#接口不能有public、private、internal、protected修飾符,接口隐式public
2.如果接口繼承接口,子接口有與父接口同名方法,可以new隐藏父接口方法
3.接口無構造函數,不能new來執行個體化,接口一旦實作,實作類中必須實作接口所有方法,除非實作類是抽象類
差別:接口更多的表是一種can-do的規範,多用于實作多重繼承,且與繼承類關系并不緊密。抽象則類似于IS-A關系,與繼承類關系較為緊密。抽象類不可以new,不可以sealed,接口中繼承父接口的子接口可以通過new來重寫覆寫同名父方法。兩者都不可以使用private、protected、internal修飾。接口通常用于規範行為,而抽象類是對對象的模拟,例如C#和java都實作oop接口,但C#是MS抽象類,java是sun抽象類
接口示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 接口和集合
{
class Program
{
//接口解釋和用途:
//⑴由于C#是單繼承,要實作多重繼承可以通過接口實作,C#接口不能有public、private、internal、protected修飾符,接口隐式public
//⑵如果接口繼承接口,子接口有與父接口同名方法,可以new隐藏父接口方法
//⑶接口無構造函數,不能new來執行個體化,接口一旦實作,實作類中必須實作接口所有方法,除非實作類是抽象類
//賬戶接口1:通用
public interface IBankGeneralCustomer
{
//存錢
void Save(double _payMoney);
//取錢
bool Withdraw(double _withdrawMoney);
//餘額
void Surplus(double _surplusMoney);
}
//賬戶接口2:土豪專用
public interface IBankTuhaoCustomer
{
//土豪提醒
void startReminder(string message);
void endReminder(string message);
}
//屌絲客戶
public class LiaoRan:IBankGeneralCustomer
{
public double balance { get; set; }
public void Save(double _payMoney)
{
balance = balance + _payMoney;
}
public bool Withdraw(double _withdrawMoney)
{
if (balance - _withdrawMoney <= 0)
return false;
else
{
balance = balance - _withdrawMoney;
Console.WriteLine("取出{0}剩餘{1}", _withdrawMoney, balance);
return true;
}
}
public void Surplus(double _surplusMoney)
{
Console.WriteLine("餘額{0}", balance);
}
}
//土豪客戶
public class Guhao:IBankGeneralCustomer,IBankTuhaoCustomer
{
public double balance { get; set; }
public void Save(double _payMoney)
{
balance = balance + _payMoney;
}
public bool Withdraw(double _withdrawMoney)
{
if (balance-_withdrawMoney <= 0)
return false;
else
{
balance = balance - _withdrawMoney;
Console.WriteLine("取出{0}剩餘{1}", _withdrawMoney, balance);
return true;
}
}
public void Surplus(double _surplusMoney)
{
Console.WriteLine("餘額{0}", balance);
}
public void startReminder(string message)
{
Console.WriteLine("交易開始{0}",message);
}
public void endReminder(string message)
{
Console.WriteLine("交易結束{0}",message);
}
}
static void Main(string[] args)
{
LiaoRan lr = new LiaoRan();
lr.Save(50.00);
lr.Withdraw(49.00);
Guhao gh = new Guhao();
gh.startReminder("1号台");
gh.Save(100.00);
gh.Withdraw(20.00);
gh.endReminder("2号台");
Console.ReadKey();
}
}
}