多态的问题,请指教(贴子标标题过短怎么还有这限制了)

king2003 2008-06-22 11:58:27
class Animal
{
public Animal()
{
Console.WriteLine("Animal constructor");
}
public void Greet()
{
Console.WriteLine("Animal says Hello");
}
public void Talk()
{
Console.WriteLine("Animal talk");
}
public virtual void Sing()
{
Console.WriteLine("Animal song");
}
};


class Dog : Animal
{
public Dog()
{
Console.WriteLine("Dog constructor");
}
public new void Talk()
{
Console.WriteLine("Dog talk");
}
public override void Sing()
{
Console.WriteLine("Dog song");
}
};


Animal a2 = new Dog();
a2.Talk();//这一步为什么访问的是父类的方法?不是说关注对象吗?
a2.Sing();
a2.Greet();
...全文
97 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
wanghui0380 2008-06-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 king2003 的回复:]
哦这个才是我所说的关注对象的使用范围呵
[/Quote]

注意:你这个例子是因为代码是你从头到尾自己写的,所以你认为所有东西你都关注并实现了
可是如果上面那些类Chicken,Bird,Animal 都不是你写的而是别人提供的。

那么你作为调用者,你认为你关注了些啥呢?

Bird bird2 = new Chicken();
bird2.ShowType();


看见了吗?你并没有关注Chicken的具体实现,但你同样取得了Chicken的方法。明白没有!这里的一些都是对调用者说的,多态是对调用者来说ShowType()这个方法会根据new的对象不同而有不同的执行结果。




king2003 2008-06-22
  • 打赏
  • 举报
回复
哦这个才是我所说的关注对象的使用范围呵
king2003 2008-06-22
  • 打赏
  • 举报
回复
public abstract class Animal
{

public abstract void ShowType();

public void Eat()
{

Console.WriteLine("Animal always eat.");

}

}

public class Bird : Animal
{

private string type = "Bird";

public override void ShowType()
{

Console.WriteLine("Type is {0}", type);

}

private string color;

public string Color
{

get { return color; }

set { color = value; }

}

}

public class Chicken : Bird
{

private string type = "Chicken";

public override void ShowType()
{

Console.WriteLine("Type is {0}", type);

}

public void ShowColor()
{

Console.WriteLine("Color is {0}", Color);

}

}

Bird bird2 = new Chicken();
bird2.ShowType();

那你们说这个应该显示什么?
amandag 2008-06-22
  • 打赏
  • 举报
回复
a2.Talk();//这一步为什么访问的是父类的方法?不是说关注对象吗?
==
因为你这个方法不是虚方法,只有虚方法或抽象方法会实现多态
viena 2008-06-22
  • 打赏
  • 举报
回复
多态性 是一种特殊实现

如果没有多态性的特殊实现,一般方法只与类型有关,而与对象无关
数据可以在每个对象中有一份copy,
而方法在代码区而不是数据区,只与类型有关,只有一份全局copy
类型是父类 访问的当然是父类的方法
sunshine_anycall 2008-06-22
  • 打赏
  • 举报
回复
你这里的这个东西没有用到多态。
多态一定要有继承和虚方法。
这个时候你所说的问题就解决了。

你这里用到的是用c++的说法是覆盖。子类和基类有同名的成员,所以子类覆盖了基类的成员。
问题是,你这用子类初始化了基类的实例,所以。。。
viena 2008-06-22
  • 打赏
  • 举报
回复
只有基类中virtual、abstract或override的方法
派生类前面加override关键字进行重写的
才有多态
不加override关键字,会默认为加了new关键字,隐藏基类中的方法,不会有多态
kiraqian 2008-06-22
  • 打赏
  • 举报
回复
因为你用子类的对象实例化了一个父类的引用,而父类的方法Talk()没有在子类中被覆盖,只是子类中用new关键字隐藏了父类的同名方法,
系统内部函数调用都是用指针实现的,这个引用对于子类没有覆盖的父类方法还是调用父类的,覆盖后指针调用子类方法。
多态性其实是程序运行时指针实现的。
king2003 2008-06-22
  • 打赏
  • 举报
回复
我的意思是为什么会这样,我见有人说要关注对象不要关注引用呀!这和他说的有冲突
wenbin 2008-06-22
  • 打赏
  • 举报
回复
要用虚方法才可以,回复内容太短了!
春天的气息 2008-06-22
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 wanghui0380 的回复:]
我想你的问题实际是,你不知道为什么要转化成父类
给个例子给你

现在有一个函数 飞()
他的形式是:void 飞(鸟 obj)
{
obj.飞()
}

这样对于调用者来说,他的调用方式是
飞(new 麻雀());
飞(new 鸡());

ok,这样的方式是简单的,而且只要他是继承鸟类,麻雀也好,鸡也好,老鹰也好,你都可以使用飞这个函数。

如果你不用多态,你会如何写这个飞的函数???

void 飞(鸡 obj)
void…
[/Quote]

精彩,讲的深入又浅出
wanghui0380 2008-06-22
  • 打赏
  • 举报
回复
我想你的问题实际是,你不知道为什么要转化成父类
给个例子给你

现在有一个函数 飞()
他的形式是:void 飞(鸟 obj)
{
obj.飞()
}

这样对于调用者来说,他的调用方式是
飞(new 麻雀());
飞(new 鸡());

ok,这样的方式是简单的,而且只要他是继承鸟类,麻雀也好,鸡也好,老鹰也好,你都可以使用飞这个函数。

如果你不用多态,你会如何写这个飞的函数???

void 飞(鸡 obj)
void 飞(麻雀 obj)
void 飞(老鹰 obj)

!!!!!!!!!!!!!!!!!很明显,后面一种方式无疑是一件很麻烦的形式,而且他直接依赖于你是否实现了 飞(某种鸟类 obj)这个函数
zhiguo2008 2008-06-22
  • 打赏
  • 举报
回复
答案是:Type is chicken 吗?

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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