类中已实现接口的方法,为什么类的实例化对象却不能直接调用该接口方法?

tellyu 2011-10-17 06:13:19
 public abstract class Animal
{
protected string _name;

//声明抽象属性
public abstract string Name
{
get;
}

//声明抽象方法
public abstract void Show();

//实现一般方法
public void MakeVoice()
{
Console.WriteLine("All animals can make voice!");
}
}

public interface IAction
{
//定义公共方法标签
void Move();
}

public class Duck : Animal, IAction
{
public Duck(string name)
{
_name = name;
}

//重载抽象方法
public override void Show()
{
Console.WriteLine(_name + " is showing for you.");
}

//重载抽象属性
public override string Name
{
get { return _name; }
}

//实现接口方法
public void Move()
{
Console.WriteLine("Duck also can swim.");
}

}

public class Dog : Animal, IAction
{
public Dog(string name)
{
_name = name;
}

public override void Show()
{
Console.WriteLine(_name + " is showing for you.");
}

public override string Name
{
get { return _name; }
}

public void Move()
{
Console.WriteLine(_name + " also can run.");
}

}
public class TestAnmial
{
public static void Main(string[] args)
{
Animal duck = new Duck("Duck");
duck.MakeVoice();
duck.Show();

duck.move();

Animal dog = new Dog("Dog");
dog.MakeVoice();
dog.Show();

IAction dog1= new Dog("zhu");
dog1.Move();

IAction dog1 = new Dog("A big dog");
dog1.Move();

Console.ReadKey();
}
}


如上面的代码所示,在duck 和 dog类中已经实现了接口方法,为什么类的实例化对象不能直接用 类似 dog.Move();的形式调用类里面的接口方法呢?

vs报错提示 Animal中并不包含"Move"的定义。

这样是不是说明,抽象类的继承类不能增加方法?
而必须使用 IAction dog1 = new Dog("A big dog");
dog1.Move();
这样才能调用接口方法。
为什么呢?


我是新手,大家不要笑我
...全文
860 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
tellyu 2011-10-19
  • 打赏
  • 举报
回复
谢谢各位的解答,我大概明白了一点,我的理解是
如果用子类实例化父类型 调用的字段和方法是看实例的类型是什么就调用什么的。
比如
class A
{}
class B:A
{}

A a=new B();

这里的a是A类型的,所以调用的字段是方法应该是A的,而如果B中有方法的重写,则调用的方式为B的重写的方法,我这样理解对吗?

希望大家指出啊
threenewbee 2011-10-19
  • 打赏
  • 举报
回复
如果基类用virtual修饰一个方法,而子类用override去覆盖。那么子类中根本就不存在父类的那个方法了。
所以
class A
{
public virtual void foo() { }
}
class B : A
{
public override void foo() { }
}

A a = new B();
a.foo();
(a as B).foo();
以上两行调用的都是B.foo(),无论任何情况,都调用不了a.foo()了。

引用类型和对象类型是2个概念,比如:
A a = new B();
Console.WriteLine(a.GetType()); //输出还是 B
越活越不精彩 2011-10-18
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 tellyu 的回复:]
引用 5 楼 lingto1 的回复:

你实例化的是Animal类,但Animal类中是没有Move()方法的。
所以要转换成IAction后才可调用。

我最想明白的是:子类实例化父类 其方法与字段的调用 ,是怎么回事
[/Quote]

就是9,10楼说的那样,我再用你的代码说下吧:
Animal dog = new Dog("Dog");
你声明的dog是Animal类型,而Animal中并没有Move()方法啊,所以你无法调用,你也就只能调Animal中公开的东东。。。
你把Dog类的一个实例引用,给了Animal的变量:dog,那么,现在你dog.Show()中将会引用的是Dog类中的:Show().(这个Show是你重写父类的方法)

建议你还是再去看看接口和抽象类吧。
tellyu 2011-10-18
  • 打赏
  • 举报
回复
其实我是没弄懂子类实例化父类,字段、属性以及方法的是怎么调用的。调用的是父类的还是子类的?
求讲解啊
threenewbee 2011-10-18
  • 打赏
  • 举报
回复
你要明确,类型和对象之间的关系。

比如
人 张三;
中国人 张三;
张三是人,也是中国人
作为人,他未必会说中国话,作为中国人,他会说中国话。
将张三视作人,或者视作中国人,类型是不同的。但是张三本身没有改变。他作为人,他还是那个人,不会说因为他是人,就不会说中国话了。
threenewbee 2011-10-18
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 tellyu 的回复:]
引用 5 楼 lingto1 的回复:

你实例化的是Animal类,但Animal类中是没有Move()方法的。
所以要转换成IAction后才可调用。

我最想明白的是:子类实例化父类 其方法与字段的调用 ,是怎么回事
[/Quote]

道理很简单,看下面的代码:
class A
{

}
class B : A
{
public void foo();
}
class C : A
{

}

A a = new B();
a = new C(); //合法
B b = new B();
//b = new C(); //不合法
我们假设可以通过a调用foo()会如何呢?
A a = new B();
a.foo(); //此时a是B类型
a = new C();
a.foo(); //此时a是C类型,这个怎么调用?
coder_s 2011-10-18
  • 打赏
  • 举报
回复
Animal duck = new Duck("Duck");

因为你已经明确指明duck 实例的类型是 Animal.

zhujiazhi 2011-10-18
  • 打赏
  • 举报
回复
Animal类中是没有Move()方法
tellyu 2011-10-18
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 lingto1 的回复:]

你实例化的是Animal类,但Animal类中是没有Move()方法的。
所以要转换成IAction后才可调用。
[/Quote]
我最想明白的是:子类实例化父类 其方法与字段的调用 ,是怎么回事
越活越不精彩 2011-10-18
  • 打赏
  • 举报
回复
你实例化的是Animal类,但Animal类中是没有Move()方法的。
所以要转换成IAction后才可调用。
threenewbee 2011-10-17
  • 打赏
  • 举报
回复
一个很简单的例子,比如
class A //相当于 class A : System.Object
{
public void foo() { }
}

object a = new A(); //可行,任何类都是object的派生类。
a.foo(); //报错
tellyu 2011-10-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 caozhy 的回复:]

duck.move();

=〉

(duck as IAction).move();
[/Quote]
这样是不是说明,抽象类的继承类不能增加方法?
直接使用实例dog.move()调用会报错
vs报错提示 Animal中并不包含"Move"的定义。

threenewbee 2011-10-17
  • 打赏
  • 举报
回复
duck.move();

=〉

(duck as IAction).move();

7,765

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧