2015-09-10 34 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的语言,以便代码执行开始,因此您应该从那里开始。

相关问题