1. 程式人生 > >C# 通過 Observer觀察者 設計模式 來理解 抽象類 和 介面 應用在什麼地方

C# 通過 Observer觀察者 設計模式 來理解 抽象類 和 介面 應用在什麼地方

什麼時候用抽象類?什麼時候用介面?怎麼理解抽象類?怎麼理解介面?

一、百度解釋抽象類和介面的區別

總而言之就是一句話:抽象類可以包含具體實現,介面只能包含定義。

實現介面時必須實現介面定義的方法等,抽象類中如果給方法加上了“abstract”,那麼這個方法也需要在繼承後實現這個方法,從這裡來看,介面是不包含具體實現的特殊抽象類。

二、觀察者模式體會介面和抽象類的區別

觀察者模式是什麼? 我來舉個例子,你家裡有4口人,有一個嬰兒、爸爸、媽媽、奶奶,現在模擬一個場景: baby在睡覺,baby一旦醒了之後就會哭,如果baby哭了之後爸爸、媽媽、奶奶都會做一些事情(具體做什麼事等會看程式碼),那麼baby什麼時候醒呢?不知道,這種情況下,爸爸、媽媽、奶奶就得不停的去看baby醒了沒,幹不了其他事情,這樣很不合理,於是我們就應該變成baby醒了這個事件觸發爸爸、媽媽、奶奶的響應事件。 請看如下程式碼:

using System;
using System.Collections;

//觀察者, 定義為介面
public interface Observer
{
    void Do();
}

//爸爸, 實現觀察者介面後變為一個觀察者
public class Father : Observer
{

    public void Do()
    {
        //爸爸告訴媽媽,baby醒了
        Console.WriteLine("Father tell baby's mother the baby is weak up.");
    }
}

//媽媽, 實現觀察者介面後變為一個觀察者
public class Mother : Observer
{
    public void Do()
    {
        //媽媽要來抱baby
        Console.WriteLine("Mother embrace the baby.");
    }
}

//奶奶, 實現觀察者介面後變為一個觀察者
public class GrandMother : Observer
{
    public void Do()
    {
        //奶奶要去拿牛奶
        Console.WriteLine("Grandmother take the milk to baby.");
    }
}

//被觀察物件, 定義為抽象類
public abstract class Subject
{
    public ArrayList list = new ArrayList();
    public void Attach(params Observer[] dst)
    {
        for (int i = 0; i < dst.Length; i++)
        {
            list.Add(dst[i]);
        }
    }
    public void DeTach(params Observer[] dst)
    {
        for (int i = 0; i < dst.Length; i++)
        {
            list.Remove(dst[i]);
        }
    }
    public abstract void WeakUpAndCry();
}

//寶寶, 繼承被觀察者抽象類後成為被觀察者
public class Baby:Subject
{
    public Baby(string name)
    {
        this.Name = name;
    }
    private string Name { get; set; }

    public override void WeakUpAndCry()
    {
        foreach (Observer item in list)
            item.Do();
    }
}

//程式入口    
public class Client
{
    public static void Main(string[] args)
    {
        Baby baby = new Baby("simon");
        baby.Attach(new Father(), new Mother(),new GrandMother());
        baby.WeakUpAndCry();
        Console.Read();
    }
}


問題1:Subject抽象類定義了一個抽象方法“public abstract void WeakUpAndCry();”,這個方法必須在子類重寫,為什麼我們不把這個方法也實現在抽象類中,這樣就不用抽象類了,直接使用普通的class就好了?

假如我的業務要求:如果baby叫simon,爸爸、媽媽、奶奶都要做出響應,如果baby叫lucy,爸爸不做任何操作。這種需求如果把WeakUpAndCry方法實現在抽象類中,就沒辦法做到了。

從上面的程式碼可以發現:1. 觀察者是介面 2.被觀察者是抽象類

那麼我們就能得出結論:

1.介面是用來定義實現類長什麼樣子

2.抽象類就是提供一組公用的方法,對於非公用部分它會定義好,但不實現它,可以根據你自己的需求在各個子類中寫出不同的實現