This article
PS6的代码中有错误... xyz()
产生错误:
非静态方法需要Object引用。
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 :(得分:2)
你能解释一下我的
xyz()
调用是什么方法,属性,字段。
这是Method
。
为什么这不起作用?
因为xyz()
未定义为static
且不能为static
,因为修饰符static对接口成员声明无效。所以你应该创建这样的实例:
Demo obj = new Demo();
obj.xyz();
<强> 修改的强>
为什么我们要使用界面?
使用界面不仅可以保证标准化,灵活性,可扩展性,可扩展性,可维护性< / em>,可重用性,可测试性和 power ,但也是在C#中使用接口的主要原因之一是因为C#{{3} }。
答案 1 :(得分:2)
public void xyz()
{
System.Console.WriteLine("In xyz");
}
主要方法被标记为类似c语言,代码执行开始,所以你应该从那里开始。
答案 2 :(得分: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'
现在,除了那些实例变量和实例方法之外,还有静态成员(成员是变量,方法,属性......)。 static意味着它们不属于实例,而是属于类定义。应用程序中只有一个。他们属于阶级而不是实例。
现在,对象实例知道它属于哪个类。如果您创建变量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使您实现接口的原因是因为它是本教程的主题。 ;)
他们在介绍他们的教程时简要总结了界面的优势:
C#中的接口提供了一种实现运行时多态性的方法。运用 我们可以通过接口调用来自不同类的函数 相同的接口参考,而我们可以使用虚函数 从同一继承中的不同类调用函数 层次结构通过相同的参考
所以,如果你有不同类型的Demo类,你可以将它们相互扩展:
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和Bar。三个类实现这些接口中的一个或多个。这些课本身并不相关。它们可以,但从界面的角度来看并不重要。
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() {
}
现在,如果有一种想要'Bar'的方法,它可以接受一个IBar参数。这种方法接受Bar和Foobar的实例。
通过正常继承,这是不可能实现的。您必须从Foo和Bar继承FooBar,这是不可能的,或者您必须使FooBar成为基类,在这种情况下,您必须已经在基类中声明这两个方法。这也意味着Foo实例可以作为Bar传递,反之亦然。这是不可取的。
使用接口,您可以简单地声明一个小功能,并在您喜欢的任何类中实现它。