當前位置:首頁 » 編程軟體 » 面向鴨編程

面向鴨編程

發布時間: 2022-07-01 19:26:37

1. 面向對象編程中,介面既然不能直接描述方法,要他有何用

初學時確實很不明白為什麼要費這么個二道手……
簡單地說:介面就是一個約定,凡是實現了介面的類,必定是遵守了該約定的。
比如有Dog、Cat、Duck三種動物,我想聽他們的叫聲,然後這樣進行了實現。
class Dog
{
public void Shout()
{
Console.WriteLine("汪汪");
}
}
class Cat
{
public void Shout()
{
Console.WriteLine("喵喵");
}
}
class Duck
{
public void Shout()
{
Console.WriteLine("呱呱");
}
}
class Test
{
static void Main(String[] args)
{
var dog = new Dog();
var cat = new Cat();
var ck = new Duck();
dog.Shout();
cat.Shout();
ck.Shout();
Console.Read();
}
}

然後發現,這樣好麻煩啊!明明都是在叫,能不能把「叫」這一行為進行抽離,然後統一處理呢?這時候就可以用到介面了:
interface IShout
{
void Shout();
}
class Dog : IShout
{
public void Shout()
{
Console.WriteLine("汪汪");
}
}
class Cat : IShout
{
public void Shout()
{
Console.WriteLine("喵喵");
}
}
class Duck : IShout
{
public void Shout()
{
Console.WriteLine("呱呱");
}
}
class Test
{
static void Main(String[] args)
{
var lstIShout = new List<IShout>() { new Dog(), new Cat(), new Duck() };
lstIShout.ForEach(x =>
{
x.Shout();
});
Console.Read();
}
}

在這次實現中,不管對象是狗、貓還是鴨子,他們都實現了IShout介面,因此他們都必須要實現Shout方法(必須遵從的約定),從而我就可以對他們的共性進行統一化的處理。與此同時,在我看到了Dog:IShout這種聲明方式時,我不需要去關注狗到底是怎麼叫的,只需要知道狗會叫就足夠了。這只是介面最簡單的一種應用,更復雜的情況可以去研究控制反轉與依賴注入。

_______________________________________________
這里再補充一下用鴨子類型(ck typing,詳情可進行檢索)的思想來實現,與用介面實現進行一下對比。

class Dog
{
public void Shout()
{
Console.WriteLine("汪汪");
}
}
class Cat
{
public void Shout()
{
Console.WriteLine("喵喵");
}
}
class Duck
{
public void Shout()
{
Console.WriteLine("呱呱");
}
}
class Test
{
static void Main(String[] args)
{
var lstDynamic = new List<dynamic>() { new Dog(), new Cat(), new Duck() };
lstDynamic.ForEach(x =>
{
x.Shout();
});
Console.Read();
}
}

運行後發現同樣可以實現目的。那麼為什麼要用介面呢?

因為這里的代碼都是我自己寫的,我知道三種動物都實現了Shout方法,所以我才敢大膽去直接動態調用這個方法,但是這不代表這樣的動態調用是安全的。
假如現在又新增了一個動物類Monkey
class Monkey{
public void Cry()
{
Console.WriteLine("唧唧");
}
}

由於手誤,把方法名起成了Cry,那麼可以預見的,在動態調用的過程中,就會觸發運行時錯誤了。
class Test
{
static void Main(String[] args)
{
var lstDynamic = new List<dynamic>() { new Dog(), new Cat(), new Duck() ,new Monkey()};
lstDynamic .ForEach(x =>
{
x.Shout();//執行到猴子時,會觸發運行時錯誤。
});
Console.Read();
}
}

如果是用實現IShout介面的方式定義的Monkey,那麼這種情況是不會出現的,因為約定是必須遵守的。

2. 求一些有關java面向對象繼承的編程題

魚有游泳功能 , 麻雀有飛行功能 , 鴨子既可以飛也可以游 , 鴨子和麻雀都可以行走,三者都需要呼吸.
通過java多態的思想,用繼承描述上述事物結構.

3. 賣鴨子 c語言

#include<stdio.h>
int sum;
int yazi(int n)
{
if(7==n)
return 1;
else
{

printf(" sell=%d",(sum+2)*2);
sum=(sum+1)*2;
return (yazi(n+1)+1)*2;

}
}
int main()
{ int k=1;
printf(" 總數:%d",yazi(k));
printf("\n");
return 0;
}
希望能幫到你

4. 軟體設計模式鴨子模擬器

假設我們需要設計出各種各樣的鴨子,一邊游泳戲水, 一邊呱呱叫。很明顯這時我們需要設計了一個鴨子超類(Superclass),並讓各種鴨子繼承此超類。

public abstract class Duck {
public void Swim() {
//會游泳
}
public abstract display();//各種外觀不一樣,所以為抽象
public void Quack() {
//會叫
}
}
每一隻鴨子就繼承Duck類
public class MallardDuck extends Duck {
public void display() {
// 外觀是綠色的
}
}
public class RedheadDuck extends Duck{
public void display(){
// 外觀是紅色的
}
}
好了,我們完成這些後,但是發現我們需要有一些鴨子是會飛的,應該怎麼修改呢?
也許你要說這很簡單,在Duck類裡面直接加入一個fly()方法,不就可以了。

public abstract class Duck {
public void Swim() {
//會游泳
}
public abstract display();//各種外觀不一樣,所以為抽象
public void Quack() {
//會叫
}
public void fly(){
//會飛
}
}
這時你會發現所有的鴨子都變成了會飛的,很明顯這是不對了,例如橡皮鴨顯然就不是了。
你也許想到了另一種方法,在會飛的鴨子類里才添加該方法不就可以了嘛,

public class MallardDuck extend Duck{
public void display(){
// 外觀是綠色的
}
public void fly(){
//會飛
}
}
這個方法看起來是很不錯,可是有很多種鴨子都會飛的時候,代碼的復用性很明顯是不夠好的,你不得不在
每一個會飛的鴨子類里去寫上同一個fly()方法,這可不是個好主意.
可能你又想到另一個方法:採用繼承和覆蓋,在Duck類里實現fly()方法,在子類里如果不會飛的就覆蓋它

public abstract class Duck {
public void Swim() {
//會游泳
}
public abstract display();//各種外觀不一樣,所以為抽象
public void Quack(){
//會叫
}
public void fly(){
//會飛
}
}
//橡皮鴨吱吱叫,不會飛
public class RubberDuck extend Duck{
public void quack(){
//覆蓋成吱吱叫
}
public void display{
//外觀是橡皮鴨
}
public void fly{
//什麼也不做
}
}

這樣我們真實現了確實能飛的鴨子才可以飛起來了,看起來主意不錯!問題到這兒似乎得到了解決
但我們現在有了一種新的鴨子,誘鉺鴨(不會飛也不會叫),看來需要這樣來寫
public class DecoyDuck extend Duck{
public void quack(){
//覆蓋,變成什麼也不做
}
public void display(){
//誘餌鴨
}
public void fly(){
//覆蓋,變成什麼也不做
}
}

每當有新的鴨子子類出現或者鴨子新的特性出現,就不得不被迫在Duck類里添加並在所有子類里檢查可能需要覆蓋fly()和quark()...這簡直是無窮盡的惡夢。所以,我們需要一個更清晰的方法,讓某些(而不是全部)鴨子類型可飛或可叫。讓鴨子的特性能有更好的擴展性。
用一下介面的方式把fly()取出來,放進一個Flyable介面中,這樣只有會飛的鴨子才實現這個介面,當然我們也可以照此來設計一個Quackbable介面,因為不是所有的鴨子都會叫,也只讓會叫的鴨子才去實現這個介面.
但這個方法和上面提到的在子類里去實現fly一樣笨,如果幾十種都可以飛,你得在幾十個鴨子里去寫上一樣的fly(),如果一旦這個fly有所變更,你將不得不找到這幾十個鴨子去一個一個改它們的fly()方法。
因為改變鴨子的行為會影響所有種類的鴨子,而這並不恰當。Flyable與Quackable介面一開始似乎還挺不錯, 解決了問題( 只有會飛的鴨子才繼承Flyable) , 但是Java的介面不具有實現代碼, 所以繼承介面無法達到代碼的復用。這意味著:無論何時你需要修改某個行為,你必須得往下追蹤並修改每一個定義此行為的類。
策略模式的第一原則:找出應用中可能需要變化之處,把它們獨立出來,不要和那些不需要變化的代碼混在一起。 好吧,回頭看一下這個Duck類,就我們目前所知,除了fly()和quack()的問題之外,Duck類還算一切正常,主要是鴨子的行為總是可能變化的,讓我們頭痛就在於這些行為的變化,那我們就把這些行為獨立出來。
為了要把這兩個行為從Duck 類中分開, 我們將把它們自Duck 類中取出,建立一組新類代表每個行為。我們建立兩組類(完全遠離Duck類),一個是「fly」相關的,一個是「quack」相關的,每一組類將實現各自 的動作。比方說,我們可能有一個類實現「呱呱叫」,另一個類實現「吱吱叫」,另一個類實現「安靜」。我們利用介面代表每組行為,比方說, FlyBehavior來代表飛的行為,QuackBehavior代表叫的行為,而讓每一種行為具體類來實現該行為介面。
在此,我們有兩個介面,FlyBehavior和QuackBehavior,還有它們對應的類,負責實現具體的行為:

public interface FlyBehavior {
public void fly();
}
public class FlyWithWings implements FlyBehavior{
public void fly{}{
//實現鴨子飛行
}
}
public class FlyNoWay implements FlyBehavior{
public void fly{}{
//什麼也不做,不會飛
}
}
public interface QuackBehavior{
public void quack();
}
public class Quack implements QuackBehavior{
public void quack(){
//實現鴨子呱呱叫
}
}
public class Squeak implements QuackBehavior{
public void quack(){
//實現鴨子吱吱叫
}
}
public class MuteQuack implements QuackBehavior{
public void quack(){
//什麼也不做,不會叫
}
}

實際上這樣的設計,我們已經可以讓飛行和呱呱叫的動作被其他的對象復用,因為這些行為已經與鴨子類無關了。如果我們新增一些行為,也不會影響到既有的行為類,也不會影響有已經使用到飛行行為的鴨子類。
好了,我們設計好鴨子的易於變化的行為部分後,該到了整合鴨子行為的時候了。
這時我們該想到策略模式的另一個原則了:
針對介面編程,而不是針對實現編程。
首先, 在鴨子中加入兩個實例變數,分別為「flyBehavior」與「quackBehavior」,聲明為介面類型( 而不是具體類實現類型), 每個變數會利用多態的方式在運行時引用正確的行為類型( 例如:FlyWithWings 、Squeak...等)。我們也必須將Duck類與其所有子類中的fly()與quack()移除,因為這些行為已經被搬移到FlyBehavior與 Quackehavior類中了,用performFly()和performQuack()取代Duck類中的fly()與quack()。

public abstract class Duck(){
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public void swim(){
//會游泳
}
public abstract void display();//各種外觀不一樣,所以為抽象
public void performQuack(){
quackBehavior.quack();
}
public void performFly(){
flyBehavior.fly();
}

}
很容易,是吧?想進行呱呱叫的動作,Duck對象只要叫quackBehavior對象
去呱呱叫就可以了。在這部分的代碼中,我們不在乎QuackBehavior 介面的對象到底是什麼,我們只關心該對象
知道如何進行呱呱叫就夠了。
好吧! 現在來關心如何設定flyBehavior 與quackBehavior的實例變數。
看看MallardDuck類:
public class MallardDuck extends Duck {
public MallardDuck() {
\\綠頭鴨使用Quack類處理呱呱叫,所以當performQuack() 被調用,就把責任委託給Quack對象進行真正的呱呱叫。
quackBehavior = new Quack();
\\使用FlyWithWings作為其FlyBehavior類型。
flyBehavior = new FlyWithWings();
}
}
所以,綠頭鴨會真的『呱呱叫』,而不是『吱吱叫』,或『叫不出聲』。這是怎麼辦到的?當MallardDuck實例化時,它的構造器會
把繼承來的quackBehavior實例變數初始化成Quack類型的新實例(Quack是QuackBehavior的具體實現類)。同樣的處理方式也可以用在飛行行為上: MallardDuck 的構造器將flyBehavior 實例變數初始化成FlyWithWings 類型的實例(
FlyWithWings是FlyBehavior的具體實現類)。
輸入下面的Duck類(Duck.java) 以及MallardDuck 類MallardDuck.java),並編譯之。
public abstract class Duck {

//為行為介面類型聲明兩個引用變數, 所有鴨子子類(在同一個packge)都繼承它們。
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck() {
}
public abstract void display();
public void performFly() {
flyBehavior.fly();//委託給行為類
}
public void performQuack() {
quackBehavior.quack();//委託給行為類
}
public void swim() {
System.out.println("All cksfloat, even decoys!");
}
}

public class MallardDuck extends Duck {
public MallardDuck() {
quackBehavior = newQuack();
flyBehavior = newFlyWithWings();
}
public void display() {
System.out.println("I』m a real Mallard ck");
}
}
輸入FlyBehavior介面(FlyBehavior.java)與兩個行為實現類(FlyWithWings.java與FlyNoWay.java),並編譯之。
public interface FlyBehavior {//所有飛行行為類必須實現的介面
public void fly();
}
public class FlyWithWings implements FlyBehavior {//這是飛行行為的實現, 給「真會」飛的鴨子用 .. .
public void fly() {
System.out.println("I』m flying!!");
}
}
public class FlyNoWay implements FlyBehavior {//這是飛行行為的實現, 給「不會」飛的鴨子用( 包括橡皮鴨和誘餌鴨)
public void fly() {
System.out.println("I can』t fly");
}
}

輸入QuackBehavior介面(QuackBehavior.java)及其三個實現類(Quack.java、MuteQuack.java、Squeak.java),並編譯之。
public interface QuackBehavior {
public void quack();
}
public class Quack implements QuackBehavior {
public void quack() {
System.out.println(「Quack」);
}
}
public class MuteQuack implements QuackBehavior {
public void quack() {
System.out.println(「<< Silence >>」);
}
}
public class Squeak implements QuackBehavior {
public void quack() {
System.out.println(「Squeak」);
}
}
輸入並編譯測試類(MiniDuckSimulator.java)

public class MiniDuckSimulator {
public static void main(String[] args) {
Duck mallard = new MallardDuck();
mallard.display();
//這會調用MallardDuck繼承來的performQuack() ,進而委託給該對象的QuackBehavior對象處理。(也就是說,調用繼承來的quackBehavior的quack())
mallard.performQuack();
//至於performFly() ,也是一樣的道理。
mallard.performFly();
}
}
運行結果:
I』m a real Mallard ck
Quack
I』m flying!!

雖然我們把行為設定成具體的類(通過實例化類似Quack 或FlyWithWings的行為類, 並指定到行為引
用變數中),但是還是可以在運行時輕易地改變該行為。
所以,目前的作法還是很有彈性的,只是初始化實例變數的作法不夠彈性罷了。
我們希望一切能有彈性,畢竟,正是因為一開始的設計的鴨子行為沒有彈性,才讓我們走到現在這條路。
我們還想能夠「指定」行為到鴨子的實例, 比方說, 想要產生綠頭鴨實例,並指定特定「類型」的飛行
行為給它。乾脆順便讓鴨子的行為可以動態地改變好了。換句話說,我們應該在鴨子類中包含設定行為的方法。
因為quackBehavior實例變數是一個介面類型,所以我們是能夠在運行時,透過多態動態地指定不同的QuickBehavior實現類給它。
我們在鴨子子類透過設定方法(settermethod)設定鴨子的行為,而不是在鴨子的構造器內實例化。
在Duck類中,加入兩個新方法:從此以後,我們可以「隨時」調用這兩個方法改變鴨子的行為。

public strate class Duck(){
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public void setFlyBehavior(FlyBehavior fb) {
flyBehavior = fb;
}
public void setQuackBehavior(QuackBehavior qb) {
quackBehavior = qb;
}

}
好了,讓我們再製造一個新的鴨子類型:模型鴨(ModelDuck.java)
public class ModelDuck extends Duck {
public ModelDuck() {
flyBehavior = new FlyNoWay();//初始狀態,我們的模型鴨是不會飛的。
quackBehavior = new Quack();//初始狀態,我們的模型鴨是可以叫的.
}
public void display() {
System.out.println("I』m a modelck");
}
}
建立一個新的FlyBehavior類型(FlyRocketPowered.java)
public class FlyRocketPowered implements FlyBehavior {
// 我們建立一個利用火箭動力的飛行行為。
public void fly() {
System.out.println("I』m flying with arocket!");
}
}

改變測試類(MiniDuckSimulator.java),加上模型鴨,並使模型鴨具有火箭動力。
public class MiniDuckSimulator {
public static void main(String[] args) {
Duck mallard = new MallardDuck();
mallard.performQuack();
mallard.performFly();
Duck model = new ModelDuck();
//第一次調用performFly() 會被委託給flyBehavior對象(也就是FlyNoWay對象),該對象是在模型鴨構造器中設置的。
model.performFly();
//這會調用繼承來的setter 方法,把火箭動力飛行的行為設定到模型鴨中。哇咧! 模型鴨突然具有火箭動力飛行能力。
model.setFlyBehavior(new FlyRocketPowered());
//如果成功了, 就意味著模型鴨動態地改變行為。如果把行為的實現綁死在鴨子類中, 可就無法做到這樣。
model.performFly();
}
}
運行一下,看下結果
I』m a real Mallard ck
Quack
I』m flying!!
I』m a model ck
I can』t fly
I』m flying with a rocket!
如同本例一般,當你將兩個類結合起來使用,這就是組合(composition)。這種作法和『繼承』不同的地方在於,
鴨子的行為不是繼承而來,而是和適當的行為對象『組合』而來。
這是一個很重要的技巧。其實是使用了策略模式中的第三個設計原則, 多用組合,少用繼承。
現在來總結一下,鴨子的行為被放在分開的類中,此類專門提供某行為的實現。
這樣,鴨子類就不再需要知道行為的實現細節。
鴨子類不會負責實現Flyable與Quackable介面,反而是由其他類專門實現FlyBehavior與QuackBehavior,
這就稱為「行為」類。由行為類實現行為介面,而不是由Duck類實現行為介面。
這樣的作法迥異於以往,行為不再是由繼承Duck超類的具體實現而來, 或是繼承某個介面並由子類自行實現而來。
(這兩種作法都是依賴於「實現」, 我們被實現綁得死死的, 沒辦法更改行為,除非寫更多代碼)。
在我們的新設計中, 鴨子的子類使用介面( FlyBehavior與QuackBehavior)所表示的行為,所以實際的實現不會被
綁死在鴨子的子類中。( 換句話說, 特定的實現代碼位於實現FlyBehavior與QuakcBehavior的特定類中),這樣我們就獲得了更大的靈活性和可擴展性。

5. C++ 面向對象

面向對象,就是所有的代碼一對象為基礎,比如我有一個鴨子類
class ck{
public:
void yell(){ //鴨子叫喚的方法
cout<<"嘎嘎"<<endl;
}
void Move(){ //鴨子走路方法
cout<<"左搖右擺的走"<<endl;
}
};
這樣就定義一個ck類,如果想生成50隻鴨子,就直接定義
ck xiaoyazi[50]; xiaoyazi就是對象數組啦。
每一個xiaoyazi都是一個ck類的對象,都可以調用yell跟Move方法。

6. C# 抽象類 和結構 和類是的用處包括構造函數 介面!!

結構我沒怎麼用過,認為作用不大。
抽象類和介面可以放在一起看。希望不要看完了越來越混淆。
構造函數的作用:舉個簡單的例子,當你在實例化一個對象的時候需要初始化類中某些屬性值,可以用構造函數。還有就是當我們實例化類時通過調用不同的構造函數得到我們想要的實例對象。
什麼是介面?介面是包含一組虛方法的抽象類型,其中每一種方法都有其名稱、參數和返回值。介面方法不能包含任何實現,CLR允許介面可以包含事件、屬性、索引器、靜態方法、靜態欄位、靜態構造函數以及常數。但是注意:C#中不能包含任何靜態成員。一個類可以實現多個介面,當一個類繼承某個介面時,它不僅要實現該介面定義的所有方法,還要實現該介面從其他介面中繼承的所有方法。定義方法為:

public interface System.IComparable
{
int CompareTo(object o);
}

public class TestCls: IComparable
{
public TestCls()
{
}

private int _value;
public int Value
{
get { return _value; }
set { _value = value; }
}

public int CompareTo(object o)
{

//使用as模式進行轉型判斷
TestCls aCls = o as TestCls;
if (aCls != null)
{

//實現抽象方法
return _value.CompareTo(aCls._value);
}
}
} 什麼是抽象類? 抽象類提供多個派生類共享基類的公共定義,它既可以提供抽象方法,也可以提供非抽象方法。抽象類不能實例化,必須通過繼承由派生類實現其抽象方法,因此對抽象類不能使用new關鍵字,也不能被密封。如果派生類沒有實現所有的抽象方法,則該派生類也必須聲明為抽象類。另外,實現抽象方法由overriding方法來實現。定義方法為:
/// <summary>
/// 定義抽象類
/// </summary>
abstract public class Animal
{
//定義靜態欄位
protected int _id;

//定義屬性
public abstract int Id
{
get;
set;
}

//定義方法
public abstract void Eat();

//定義索引器
public string this[int i]
{
get;
set;
}
}

/// <summary>
/// 實現抽象類
/// </summary>
public class Dog: Animal
{
public override int Id
{
get {return _id;}
set {_id = value;}
}

public override void Eat()
{
Console.Write("Dog Eats.")
}
}
相同點和不同點 相同點 都不能被直接實例化,都可以通過繼承實現其抽象方法。 都是面向抽象編程的技術基礎,實現了諸多的設計模式。 不同點
介面支持多繼承;抽象類不能實現多繼承。 介面只能定義抽象規則;抽象類既可以定義規則,還可能提供已實現的成員。 介面是一組行為規范;抽象類是一個不完全的類,著重族的概念。 介面可以用於支持回調;抽象類不能實現回調,因為繼承不支持。 介面只包含方法、屬性、索引器、事件的簽名,但不能定義欄位和包含實現的方法;抽象類可以定義欄位、屬性、包含有實現的方法。 介面可以作用於值類型和引用類型;抽象類只能作用於引用類型。例如,Struct就可以繼承介面,而不能繼承類。 通過相同與不同的比較,我們只能說介面和抽象類,各有所長,但無優略。在實際的編程實踐中,我們要視具體情況來酌情量才,但是以下的經驗和積累,或許能給大家一些啟示,除了我的一些積累之外,很多都來源於經典,我相信經得起考驗。所以在規則與場合中,我們學習這些經典,最重要的是學以致用,當然我將以一家之言博大家之笑,看官請繼續。規則與場合 請記住,面向對象思想的一個最重要的原則就是:面向介面編程。 藉助介面和抽象類,23個設計模式中的很多思想被巧妙的實現了,我認為其精髓簡單說來就是:面向抽象編程。 抽象類應主要用於關系密切的對象,而介面最適合為不相關的類提供通用功能。 介面著重於CAN-DO關系類型,而抽象類則偏重於IS-A式的關系; 介面多定義對象的行為;抽象類多定義對象的屬性; 介面定義可以使用public、protected、internal 和private修飾符,但是幾乎所有的介面都定義為public,原因就不必多說了。 「介面不變」,是應該考慮的重要因素。所以,在由介面增加擴展時,應該增加新的介面,而不能更改現有介面。 盡量將介面設計成功能單一的功能塊,以.NET Framework為例,IDisposable、IDisposable、IComparable、IEquatable、IEnumerable等都只包含一個公共方法。 介面名稱前面的大寫字母「I」是一個約定,正如欄位名以下劃線開頭一樣,請堅持這些原則。 在介面中,所有的方法都默認為public。 如果預計會出現版本問題,可以創建「抽象類」。例如,創建了狗(Dog)、雞(Chicken)和鴨(Duck),那麼應該考慮抽象出動物(Animal)來應對以後可能出現風馬牛的事情。而向介面中添加新成員則會強制要求修改所有派生類,並重新編譯,所以版本式的問題最好以抽象類來實現。 從抽象類派生的非抽象類必須包括繼承的所有抽象方法和抽象訪問器的實實現。 對抽象類不能使用new關鍵字,也不能被密封,原因是抽象類不能被實例化。 在抽象方法聲明中不能使用 static 或 virtual 修飾符。 以上的規則,我就厚顏無恥的暫定為T14條吧,寫的這么累,就當一時的獎賞吧。大家也可以互通有無,我將及時修訂。 經典示例 絕對經典 .NET Framework是學習的最好資源,有意識的研究FCL是每個.NET程序員的必修課,關於介面和抽象類在FCL中的使用,我有以下的建議: FCL對集合類使用了基於介面的設計,所以請關注System.Collections中關於介面的設計實現; FCL對數據流相關類使用了基於抽象類的設計,所以請關注System.IO.Stream類的抽象類設計機制。 別樣小菜 下面的實例,因為是我的理解,因此給經典打上「相對」的記號,至於什麼時候晉升為「絕對」,就看我在.NET追求的路上,是否能夠一如既往的如此執著,因此我將把相對重構到絕對為止(呵呵)。 本示例沒有闡述抽象類和介面在設計模式中的應用,因為那將是另一篇有討論價值的文本,本文著眼與概念和原則的把握,但是真正的應用來自於具體的需求規范。 設計結構如圖所示: 1. 定義抽象類 public abstract class Animal
{
protected string _name;

//聲明抽象屬性
public abstract string Name
{
get;
}

//聲明抽象方法
public abstract void Show();

//實現一般方法
public void MakeVoice()
{
Console.WriteLine("All animals can make voice!");
}
}
2. 定義介面 public interface IAction
{
//定義公共方法標簽
void Move();
}
3. 實現抽象類和介面
public class Duck : Animal, IAction
{
public Duck(string name)
{
_name = name;
}

//重載抽象方法
public override void Show()
{
Console.WriteLine(_name + " is showing for you.");
}

//重載抽象屬性
public override string Name
{
get { return _name;}
}

//實現介面方法
public void Move()
{
Console.WriteLine("Duck also can swim.");
}

}

public class Dog : Animal, IAction
{
public Dog(string name)
{
_name = name;
}

public override void Show()
{
Console.WriteLine(_name + " is showing for you.");
}

public override string Name
{
get { return _name; }
}

public void Move()
{
Console.WriteLine(_name + " also can run.");
}

}
4. 客戶端實現
public class TestAnmial
{
public static void Main(string [] args)
{
Animal ck = new Duck("Duck");
ck.MakeVoice();
ck.Show();

Animal dog = new Dog("Dog");
dog.MakeVoice();
dog.Show();

IAction dogAction = new Dog("A big dog");
dogAction.Move();
}
}
他山之石 正所謂真理是大家看出來的,所以將園子里有創新性的觀點潛列於此,一是感謝大家的共享,二是完善一家之言的不足,希望能夠將領域形成知識,受用於我,受用於眾。 nai認為:抽象類是提取具體類的公因式,而介面是為了將一些不相關的類「雜湊」成一個共同的群體。至於他們在各個語言中的句法,語言細節並不是我關心的重點。 樺山澗的收藏也很不錯。 Artech認為:所代碼共用和可擴展性考慮,盡量使用Abstract Class。當然介面在其他方面的優勢,我認為也不可忽視。 shenfx認為:當在差異較大的對象間尋求功能上的共性時,使用介面;當在共性較多的對象間尋求功能上的差異時,使用抽象基類。 最後,MSDN的建議是: 如果預計要創建組件的多個版本,則創建抽象類。抽象類提供簡單易行的方法來控制組件版本。通過更新基類,所有繼承類都隨更改自動更新。另一方面,介面一旦創建就不能更改。如果需要介面的新版本,必須創建一個全新的介面。 如果創建的功能將在大范圍的全異對象間使用,則使用介面。抽象類應主要用於關系密切的對象,而介面最適合為不相關的類提供通用功能。 如果要設計小而簡練的功能塊,則使用介面。如果要設計大的功能單元,則使用抽象類。 如果要在組件的所有實現間提供通用的已實現功能,則使用抽象類。抽象類允許部分實現類,而介面不包含任何成員的實現。 結論介面和抽象類,是論壇上、課堂間討論最多的話題之一,之所以將這個老話題拿出來再議,是因為從我的體會來說,深刻的理解這兩個面向對象的基本內容,對於盤活面向對象的抽象化編程思想至關重要。本文基本概況了介面和抽象類的概念、異同和使用規則,從學習的觀點來看,我認為這些總結已經足以表達其核心。但是,對於面向對象和軟體設計的深入理解,還是建立在不斷實踐的基礎上,Scott說自己每天堅持一個小時用來寫Demo,那麼我們是不是更應該勤於鍵盤呢。對於介面和抽象類,請多用而知其然,多想而知其奧吧。

7. C語言編程題:雞兔鴨同籠問題

無語了 僅供參考= =
#include<stdio.h>
void main()
{
int chicken,ck,rabbit;
int footSum,answerNum;
for(chicken=1,answerNum=0;chicken<=A;chicken++)
{
for(ck=1;ck<=A;ck++)
{
rabbit=A-chicken-ck;
footSum=chicken*2+ck*2+rabbit*4;
if(footSum==B)
printf("第%d個答案:籠子里雞數量%d\t籠子里鴨數量%d\t籠子里兔子數量%d\n",answerNum);
}

8. 面向對象到底是什麼意思

面向對象是可以說是為了軟體的健壯性而生。
通過面向對象的方法編程可更輕松,重用性、可維護性等更強

面向對象編程,其實就是把你要編的程序當成一個世界,它由哪些種類構成(類:包含屬性,[方法->即此種類所能做的事,如人可以吃東西,取款機可以取款]等),種類之間有什麼關系(繼承,介面等),再像拼圖一樣把它拼接好,這就是面向對象

封裝是為了類屬性、方法的隱蔽,如我們吃肯德基並不需要知道肯德基是怎麼做成的,肯德基是個類,雞是它的屬性,製作是它的方法

介面是特徵,一些類具有相同的屬性、方法等,如鵝、鴨等都會吃,會叫,但具體怎麼樣吃、叫不一樣,那麼就在鵝、鴨各自的類里具體實現

汗,這都是我自己的理解,我也正在學,希望沒誤導你

9. 測試人員學python時,應該如何理解面向對象更合適

與面向對象相對應的是面向過程。python如果不採用面向對象呢,就要採用面向過程。要理解面向對象,我們需要先了解什麼是面向過程。
面向過程是流水線思維方式,舉例面向過程吃烤鴨,那就是自己去養鴨子,殺鴨子,自己烤鴨子。自己吃。中間過程每一個步驟都是自己去實現。過於注重步驟和過程,不注重職責和分工,這樣的話,去開發大型項目,代碼會非常復雜。
而面向對象,是上帝思維方式。碰到事情,首先明確職責,然後根據職責來明確不同的對象。比如還是以吃烤鴨為例,吃烤鴨, 創建農民對象,去養鴨子,創建烤鴨店對象去烤鴨子,自己只需要去賣鴨子的店裡買烤鴨,吃,再長胖即可。面向對象就是專門應對復雜項目開發,而提供的固定套路。所以一般的編程語言都有面向對象的概念。

10. C語言編程某老闆想從5隻雞、6隻鴨、7隻鵝中任意拿出10隻出售,且其中至少有2隻

利用循環嵌套循環,循環起始值為2,窮舉所有組合,並判斷取出其中和為10的組合。

下面是代碼:

#include <stdio.h>

int main()

{

int j,y,e,cnt=1;

for(j=2;j<=5;j++)

for(y=2;y<=6;y++)

for(e=2;e<=7;e++)

if(j+y+e==10)

printf("方案%d:雞%d只,鴨%d只,鵝%d只 ",cnt++,j,y,e);

return 0;

}

熱點內容
我的世界怎麼擴容伺服器內存 發布:2024-05-05 17:19:54 瀏覽:46
java讀取文件字元 發布:2024-05-05 17:15:18 瀏覽:10
三星怎麼應用加密 發布:2024-05-05 17:13:18 瀏覽:151
cad字體在那個文件夾 發布:2024-05-05 17:08:20 瀏覽:329
什麼時候用編譯器 發布:2024-05-05 17:08:20 瀏覽:764
應急救援腳本 發布:2024-05-05 17:08:17 瀏覽:336
我的世界搭建無正版驗證伺服器 發布:2024-05-05 17:03:48 瀏覽:817
我的世界伺服器地址寶可夢 發布:2024-05-05 17:00:16 瀏覽:254
dede企業源碼 發布:2024-05-05 16:57:53 瀏覽:786
如何查看java版本 發布:2024-05-05 16:45:05 瀏覽:494