2015-09-10 32 views
0

This article 已經在PS6代碼中的錯誤... xyz()產生錯誤:試圖調用從接口結果的方法錯誤「對象引用必須」

An Object reference is required for the non-static method.

class Demo : abc 
{ 
    public static void Main() 
    { 
     System.Console.WriteLine("Hello Interfaces"); 
     xyz(); 

    } 

    public void xyz() 
    { 
     System.Console.WriteLine("In xyz"); 
    } 
} 

interface abc 
{ 
    void xyz(); 
} 

你能解釋一下什麼是我的xyz()電話是它的方法,財產,領域。我迷失在真正被稱爲的東西上?

以及爲什麼這不起作用?當我們做一個Demo的新實例嗎?

這樣做......

Demo obj = new Demo(); 
obj.xyz(); 
+0

第一部分是一種方法。在開始一個關於接口的特定教程之前,首先了解類和其他基本的C#東西是個好主意。問題的其餘部分有點模糊(r)。我不清楚什麼是有效的,什麼是不行的,以及它不起作用。你有什麼錯誤嗎?如果是這樣,請將它們添加到您的問題。 – GolezTrol

+0

謝謝@GolezTrol我沒有忘記它在問題中給我的錯誤。我一直在努力通過更詳細地學習OOP來構建更好的應用程序,我認爲我對類有一個好的概念,但其中的很多內容僅僅是一個難以理解的東西,因爲這讓我很困惑,爲什麼一個人會想要一個接口來封裝他們在使用接口的方法中公開的內容。 – RiePwe

回答

0

xyz是一種方法。一個實例方法是精確的,所以讓我試着解釋爲什麼你不能從靜態方法Main調用它,以及如何解決這個問題。

類定義定義了哪些方法(和屬性等)。如果你製作了一個實例(new Demo),你就得到了一個對象。一個對象是指類,所以你知道它包含的是什麼功能,它有它自己的數據塊,你可以在其中存儲值,所以10個實例可以包含10個不同的值。

因此,例如:

class Demo { 
    public string name; 
} 

var a = new Demo(); 
a.name = 'John'; 
var b = new Demo(); 
b.name = 'Bob'; 
// At this point, a.name is still John. a and b each have their own name. 

通常的方法是一個實例方法。它可以達到並使用這些實例變量。因此,延續前面的例子,你可以這樣做:

class Demo { 
    public string name; 
    public void WhoAmI() { 
    System.Console.WriteLine(this.name); 
    } 
} 

var a = new Demo(); 
a.name = 'John'; 
var b = new Demo(); 
b.name = 'Bob'; 
a.WhoAmI(); // outputs 'John' 

現在,除了那些實例變量和實例方法,你也得到了靜態成員(成員變量,方法,屬性...)。靜態意味着它們不屬於實例,而是屬於類定義。在應用程序中只有一個。他們屬於班級而不是實例。

現在,對象實例知道它屬於哪個類。如果你創建一個變量var a = new Demo(),那麼a知道它是一個Demo,所以從它或通過它,你可以在你的例子中調用一個靜態方法,如Main

但是,在靜態方法中,如果沒有它所屬的實例的知識。畢竟,甚至不需要成爲一個實例。您可以撥打a.Main(),但您也可以撥打Demo.Main()。 因此,您不能使用實例變量,也不能調用實例方法。由於xyz是一種實例方法,因此無法從靜態方法Main中調用。

現在解決方案可以使xyz靜態。畢竟,它不涉及其他實例成員。但是,接口不允許這樣做,所以這會引發另一個錯誤。一個接口描述了一個實例的外觀,不支持靜態成員。這是C#中的一個設計決定。

所以,或者,您可以引入額外的靜態實現並從接口方法調用它。這樣,接口實現仍然可以調用靜態版本,如同Main方法:

class Demo : abc 
{ 
    public static void Main() 
    { 
     System.Console.WriteLine("Hello Interfaces"); 
     zyx(); 
    } 

    public static void zyx() { 
     System.Console.WriteLine("In zyx"); 
    } 

    public void xyz() 
    { 
     zyx(); 
    } 
} 

interface abc 
{ 
    void xyz(); 
} 

關於接口。看到你在評論中問這個問題。接口有很多用途,雖然他們的解釋在這裏有點超出範圍。但請注意,您並不需要需要每個班級的所有時間。因此,如果在特定實現中不需要接口,則不需要我引入的額外方法。 CodeProject讓你實現一個接口的原因是因爲它是本教程的主題。 ;)

他們簡要介紹他們的教程總結了優勢的接口:

Interfaces in C# provide a way to achieve runtime polymorphism. Using interfaces we can invoke functions from different classes through the same Interface reference, whereas using virtual functions we can invoke functions from different classes in the same inheritance hierarchy through the same reference

所以,如果你將有各種不同演示類的,你可以從彼此延伸他們:

現在
class BaseDemo { 
    abstract void xyz() { 
    System.Console.WriteLine("in Basedemo.xyz"); 
    } 
} 

class SpecificDemo1: BaseDemo { 
    override void xyz() { 
    System.Console.WriteLine("in SpecificDemo1.xyz"); 
    } 
} 

class SpecificDemo2: BaseDemo { 
    override void xyz() { 
    System.Console.WriteLine("in SpecificDemo2.xyz"); 
    } 
} 

,你可以聲明這樣的方法:

class DemoUser { 
    static void CallXyz(BaseDemo d) { 
    d.xyz(); 
    } 
} 

var a = new SpecificDemo2(); 
DemoUser.CallXyz(a); 

CallXyz接受類型爲SpecificDemo1和SpecificDemo2的變量。這個工作的原因是它的參數聲明爲BaseDemo類型,所以它接受BaseDemo的所有後代的實例。

然而,使的類來支持這個大的層次,只是沒有用處和維護,因此,這就是接口進來,你可以捕捉的接口一小片的功能,並使用它。

例如,在下面的代碼中,我聲明瞭兩個功能,Foo和酒吧,在接口。三個類實現一個或多個這些接口。這些類本身並不相關。他們可以是,但從界面的角度來看並不重要。

class Foo: IFoo { 
    public void DoFoo() { 
    System.Console.WriteLine('Foo is fooing'); 
    } 
} 
class Bar: IBar { 
    public void DoBar() { 
    System.Console.WriteLine('Bar is barring'); 
    } 
} 

class FooBar: IFoo, IBar { 
    public void DoFoo() { 
    System.Console.WriteLine('FooBar is fooing'); 
    } 
    public void DoBar() { 
    System.Console.WriteLine('FooBar is barring'); 
    } 
} 

IFoo { 
    void DoFoo() { 
} 
IBar { 
    void DoBar() { 
} 

現在,如果存在要「酒吧」的東西的方法,它可以接受的IBAR參數。這種方法接受Bar和Foobar的實例。

與正常的繼承,這將無法實現。你必須從Foo和Bar繼承FooBar,這是不可能的,否則你必須將FooBar作爲基類,在這種情況下,你必須在基類中聲明兩個方法。這也意味着Foo實例可以作爲Bar傳遞,反之亦然。這是不可取的。

使用接口,您可以簡單地聲明一個小功能,並在任意類中實現它。

+0

你是最棒的。謝謝 – RiePwe

2

Could you explain what is my xyz() call is it the method,property, field.

這是一個Method

Why this does not work ?

由於xyz()沒有被定義爲static且不能static因爲修飾符靜態無效接口成員聲明。所以,你應該這樣創建實例:

Demo obj = new Demo(); 
obj.xyz(); 

編輯

Why would we use the interface at all ?

隨着界面不僅你保證標準化靈活性可擴展性擴展可維護性,可重用性,可測性功耗但也是接口在C#中使用的主要原因之一是因爲C#doesn't support multiple (class) inheritance

+0

我想混淆的部分是它的接口類的方法,並在演示類中的方法,但接口類是單純只指向在類中的方法是它的接口(即..演示(?):ABCD ) 我以前做過濾器類,並且這種模式聽起來類似於我的頭,但不知何故,這個概念似乎失去了我。爲什麼我們會使用界面呢? – RiePwe

+0

@RiePwe ...檢查我的更新答案爲你關於接口的問題。 –

2
public void xyz() 
{ 
    System.Console.WriteLine("In xyz"); 
} 
  • 公共意味着它是一個公共方法和其它類可以與之交互 。
  • 無效意味着它返回void又名什麼
  • xyz是名稱的方式
  • 的 ()是參數去,但這裏有沒有,該方法被調用,參數,因此它是空
  • 捲曲圓括號之間的代碼塊也被稱爲函數或方法體

主要方法被標記爲類似c的語言,以便代碼執行開始,因此您應該從那裏開始。

相關問題