多态性的问题

XinYuJunJunLL 2010-09-29 11:09:00
public abstract class Animal
{
public virtual void EatFood()
{
Console.WriteLine("基类Animal中的EatFood");
}

public void Breed()
{
Console.WriteLine("基类Animal中的Bread");
}
}

public class Chicken : Animal
{
public override void EatFood()
{
Console.WriteLine("派生类Chicken中的EatFood");
}
}

public class Cow : Animal
{
public override void EatFood()
{
Console.WriteLine("派生类Cow中的EatFood");
}

public void Moo()
{
Console.WriteLine("派生类Cow中的Moo");
}
}

class Program
{
static void Main(string[] args)
{
//Cow myCow = new Cow();
//Chicken myChicken = new Chicken();
//myCow.EatFood();
//myChicken.EatFood(); //派生类中的方法
//Console.ReadKey();


//多态性 通过类型转换 用基类对象去调用EatFood
Cow myCow = new Cow();

//Animal myAnimal=(Animal)myCow;
Animal myAnimal = myCow;

myAnimal.EatFood();
Console.ReadKey(); //但是override之后只能调用派生类中的方法
}
}
...全文
187 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
点燃你的火花 2010-09-30
  • 打赏
  • 举报
回复
实际效果上没什么区别

非要说区别,那就是语法上,一句是显示转换,另一句是隐式转换。
XinYuJunJunLL 2010-09-30
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 sp1234 的回复:]
我想lz可以重温一下中国文化中的关于“白马非马”的典故。它是说一个叫做公孙龙的人如何狡辩而蒙混过关的故事。

面向对象设计方式实现了“白马也是马”的编译机制,因此myCow所指引的对象就是myAnimal所指引的对象,死抠字眼把“类型转换”概念仅仅理解为对象之间的复制是错误的。一个Cow同时也就是那个Animal,指的是同一个对象只是我们用两种不同的标识来引用它罢了。
[/Quote]
大侠 你在国外吧?搞这行的都是夜猫子啊...谢谢大家的回复,我慢慢参透
cjh200102 2010-09-30
  • 打赏
  • 举报
回复
路过。。
wjp_116 2010-09-30
  • 打赏
  • 举报
回复
sp1234的解释还是太术语化了,如果是明白的人看了就会更明白,但是楼主显然还是有些糊涂,这么解释好像他还是不会太明白的,
楼主要区分对象和实例之间的概念的不同之处,对象可以理解为名字,实例则是实实在在存在的东西,
Animal myAnimal=new Animal(); 这句话就是虚的,你用的方法就是纸面上的,eatfood不会产生实际的效果
而Cow myCow = new Cow();则是实际产生了一头牛,那么Animal myAnimal = myCow;就是说现在把实实在在存在的牛叫做动物了,那现在再调用那个eatfood方法就是牛的吃了,就是实际产生的动作
至于为什么这么做,我理解的其中一个好处就是为了代码的可复用,可扩展,
j544759698 2010-09-30
  • 打赏
  • 举报
回复
貌似已经解释清楚了
  • 打赏
  • 举报
回复
你可以在运行时打印
myAnimal.GetType().FullName
看看,什么“基类对象”大致纯粹是一种幻觉。
  • 打赏
  • 举报
回复
我想lz可以重温一下中国文化中的关于“白马非马”的典故。它是说一个叫做公孙龙的人如何狡辩而蒙混过关的故事。

面向对象设计方式实现了“白马也是马”的编译机制,因此myCow所指引的对象就是myAnimal所指引的对象,死抠字眼把“类型转换”概念仅仅理解为对象之间的复制是错误的。一个Cow同时也就是那个Animal,指的是同一个对象只是我们用两种不同的标识来引用它罢了。
  • 打赏
  • 举报
回复
“将子类对象赋给基类对象”?

myCow变量所指引的的对象既然是一个Cow,那么当然也就是一个Animal,因此使用变量 myAnimal 跟 变量 myCow 都可以指引一个 Cow 对象实体。

.net是面向对象语言,因此支持最基本的面向对象语法。这里并不存在什么“把子类对象赋值给基类对象”的概念。在定义类型时,我们定义Cow继承自Animal,编译器帮我们处理对于 myCow 所代表的对象的生成。

不要把类型“定义时”的继承关系,误认为是“运行时”的什么子类对象内部还有个什么指针指向父类对象,更不是“运行时”把一个对象赋值给另一个对象。
handong520 2010-09-30
  • 打赏
  • 举报
回复
Animal myAnimal = myCow;
将子类对象赋给基类对象,这时基类对象便可调用子类中的方法;
不同子类具有特定的从基类继承来的方法.
建议看下这本书:
http://ajava.org/book/design/892.html
myg133 2010-09-30
  • 打赏
  • 举报
回复
第一个显示类型转换,第二句隐式类型转换
junes99 2010-09-29
  • 打赏
  • 举报
回复
第二句应该是第一句的简化写法
XinYuJunJunLL 2010-09-29
  • 打赏
  • 举报
回复
这两个关键字的在这的用法我大概知道 就是搞不明白那两句。。有什么区别呢?
wuyq11 2010-09-29
  • 打赏
  • 举报
回复
父类可以指向(引用)子类对象
override重写,是指对父类中的虚方法(标记virtual)或抽象方法(标记为abstract)进行重写,实现新的功能,它必须与父类方法的签名完全一致.与父类方法的可访问性也必须一致 new隐藏,是指在子类中重新定义一个签名与父类的方法相同的方法,这个方法可以不用new修饰,只是编译时会弹出一个警告信息:如果是有意隐藏,请使用关键字new。
guanmingle 2010-09-29
  • 打赏
  • 举报
回复
还有一个关键字是new,你试着把override替换成new试试看,就知道了
XinYuJunJunLL 2010-09-29
  • 打赏
  • 举报
回复
意思是我只要实例化Animal Animal myAnimal=new Animal(); 就可以myAnimal.EatFood();这样用了?
兔子-顾问 2010-09-29
  • 打赏
  • 举报
回复
第二句是第一句的简化写法。调用的虚方法是根据你实例化的对象而定,和指向对象的引用类型无关。
XinYuJunJunLL 2010-09-29
  • 打赏
  • 举报
回复
不好意思 还没说问题
Animal myAnimal=(Animal)myCow;
Animal myAnimal = myCow
这两句代码具体有什么区别呢?放在这里运行后输出的都是 派生类Cow中的EatFood

111,129

社区成员

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

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

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