2013-03-04 95 views
2
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace LearnOverride 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Owner owner = new Owner(); 
      Safe safe = new Safe(); 

      Console.WriteLine("When \tLocksmith locksmith = new Locksmith();\n"); 
      Locksmith locksmith = new Locksmith(); 
      locksmith.OpenSafe(safe, owner); 
      Console.WriteLine("when ReturnContents() called from main,"); 
      Jewels openedLocksmith = safe.Open("12345"); 
      locksmith.ReturnContents(openedLocksmith, owner); 
      Console.WriteLine(); 

      Console.WriteLine("\n\nWhen \tJewelThief jewelThief = new JewelThief();\n"); 
      JewelThief jewelThief = new JewelThief(); 
      jewelThief.OpenSafe(safe, owner); 
      Console.WriteLine("when ReturnContents() called from main,"); 
      Jewels opened = safe.Open("12345"); 
      jewelThief.ReturnContents(opened, owner); 
      Console.WriteLine(); 

      Console.WriteLine("\n\nWhen \tLocksmith jewelThiefAsLocksmith = new JewelThief();\n"); 
      Locksmith jewelThiefAsLocksmith = new JewelThief(); 
      jewelThiefAsLocksmith.OpenSafe(safe, owner); 
      Console.WriteLine("when ReturnContents() called from main,"); 
      Jewels j = safe.Open("12345"); 
      jewelThiefAsLocksmith.ReturnContents(j, owner); 

      ///JewelThief jewelThief = new Locksmith(); is error 
      Console.ReadKey(); 
     } 
    } 

    class Jewels 
    { 
     public string Sparkle() 
     { 
      return "Sparkle, sparkle!"; 
     } 
    } 

    class Safe 
    { 
     private Jewels contents = new Jewels(); 
     private string safeCombination = "12345"; 
     public Jewels Open(string combination) 
     { 
      if (combination == safeCombination) 
       return contents; 
      else 
       return null; 
     } 
     public void PickLock(Locksmith lockpicker) 
     { 
      lockpicker.WriteDownCombination(safeCombination); 
     } 
    } 

    class Owner 
    { 
     private Jewels returnedContents; 
     public void ReceiveContents(Jewels safeContents) 
     { 
      returnedContents = safeContents; 
      Console.WriteLine("Owner:Thank you for returning my jewels! " + safeContents.Sparkle()); 
     } 
    } 

    class Locksmith 
    { 
     public void OpenSafe(Safe safe, Owner owner) 
     { 
      safe.PickLock(this); 
      Jewels safeContents = safe.Open(writtenDownCombination); 
      this.ReturnContents(safeContents, owner); 
     } 

     private string writtenDownCombination = null; 
     public void WriteDownCombination(string combination) 
     { 
      writtenDownCombination = combination; 
     } 
     public void ReturnContents(Jewels safeContents, Owner owner) 
     { 
      owner.ReceiveContents(safeContents); 
     } 
    } 

    class JewelThief : Locksmith 
    { 
     private Jewels stolenJewels = null; 
     public void ReturnContents(Jewels safeContents, Owner owner) 
     { 
      stolenJewels = safeContents; 
      Console.WriteLine("JewelThief:I'm stealing the contents! " + stolenJewels.Sparkle()); 
     } 
    } 
} 

上述代碼不覆蓋方法ReturnContents()。它正在隱藏。所以我期待 的聲明隱藏基類中的方法

this.ReturnContents(safeContents,owner);

存在於Locksmith類(OpenSafe()方法內),將調用ReturnContents()方法存在JewelThief對象如果引用對象'JewelThief'。

但每次調用baseclass方法時,ReturnContents。這種行爲如何解釋?

+0

不知道你這是在做代碼,但不會ReturnContents被標記爲鎖匠類虛擬到Override可以將其隱藏的方法。 – TalentTuner 2013-03-04 05:39:14

+0

我知道我可以使用'虛擬覆蓋'。但是當我隱藏一種方法時,我正在學習這種行爲。 – SHRI 2013-03-04 05:43:28

+0

這也沒有隱藏,你需要在重寫的方法上使用新的關鍵字 – TalentTuner 2013-03-04 05:44:37

回答

4

在C#中,你必須聲明你的虛擬方法。也許你在想JAVA?

更改方法簽名:

public virtual void ReturnContents(Jewels safeContents, Owner owner) 

基類和:

public override void ReturnContents(Jewels safeContents, Owner owner) 

的子類。

當子類重新定義基類已經定義的方法時,隱藏發生。在這種情況下,運行時將調用引用類型的方法,而不使用多態性。如果需要這種行爲,則應使用「new」關鍵字在子類中標記該方法。但是,如果您想使用多態,則需要將基類的方法聲明爲虛方法,並在子類中使用方法的「覆蓋」關鍵字。

如果您想要在基類中使用大部分代碼,但希望在某個特定方法的類中出現新行爲並將其暴露給該類的所有子類你正在定義使用隱藏。這將不會改變基類的內部調用方法的行爲,但仍然可以讓您爲新類的用戶提供新的實現。

+0

是的,我正在研究有關隱藏方法的行爲。我的意思是沒有壓倒性的。 – SHRI 2013-03-04 05:42:04

+1

@SHRI沒有重寫,你不能從'Locksmith'變量調用'JewelThief'方法。 – 2013-03-04 05:43:44

+0

@SHRI查看我的更新。 – 2013-03-04 05:47:29

0

如果你不想使用new操作

public new void ReturnContents(Jewels safeContents, Owner owner) 
    { 
     stolenJewels = safeContents; 
     Console.WriteLine("JewelThief:I'm stealing the contents! " + stolenJewels.Sparkle()); 
    } 
+0

我同意,我應該使用那個'新'關鍵字。我想知道區別時:this.ReturnContents()和jewelThief.ReturnContents() – SHRI 2013-03-04 05:55:27