我刚学习,在看到多态时有点不解,教程上说多态有2种:编译时和运行时。编译我懂就是方法的重载,可是运行时教程说的太专业了看不懂,希望大家能通俗点告诉我!以下是我做的小试验,按我个人的理解:输出应该是“derivedClass"。因为我想baseClass tempClass = new derivedClass(); tempClass被赋值为derivedClass的对象了,那么它应该是derivedClass对象。 其实是错的理解。
那么我想问:1、当父对象被赋值为子对象的时候,父对象到底是不是子对象(跟普通的变量赋值有什么区别)?为什么?
2、什么情况下才用到这种赋值操作!我实在抽象不出来。
在此谢谢大家了,顺便祝大家端午节快乐!
static void Main(string[] args)
{
baseClass tempClass = new derivedClass();
tempClass.Method1();
}
} public class baseClass
{
public virtual void Method1()
{
Console.WriteLine("baseClass");
}
} public class derivedClass : baseClass
{
public new void Method1()
{
Console.WriteLine("derivedClass");
}
}
那么我想问:1、当父对象被赋值为子对象的时候,父对象到底是不是子对象(跟普通的变量赋值有什么区别)?为什么?
2、什么情况下才用到这种赋值操作!我实在抽象不出来。
在此谢谢大家了,顺便祝大家端午节快乐!
static void Main(string[] args)
{
baseClass tempClass = new derivedClass();
tempClass.Method1();
}
} public class baseClass
{
public virtual void Method1()
{
Console.WriteLine("baseClass");
}
} public class derivedClass : baseClass
{
public new void Method1()
{
Console.WriteLine("derivedClass");
}
}
override依、你怎么用的new 不解!你父类的虚方法没有被重写。
加上关键字之后才算是真正的多态。然后就是你想要的效果了。
public class Test()
{
static void Main(string[] args)
{
baseClass tempClass = new derivedClass();
tempClass.Method1();
}
} public class baseClass
{
public virtual void Method1()
{
Console.WriteLine("baseClass");
}
} public class derivedClass : baseClass
{
public override void Method1()
{
Console.WriteLine("derivedClass");
}
}
{
static void Main(string[] args)
{
baseClass tempClass = new derivedClass();
tempClass.Method1();
}
} public class baseClass
{
public virtual void Method1()
{
Console.WriteLine("baseClass");
}
} public class derivedClass : baseClass
{
public override void Method1()
{
Console.WriteLine("derivedClass");
}
}
==
这句话就有问题,应该说父类的引用指向子类的对象,此时父类的引用还是只能实现父类的功能,但是,当有子类重写(也就是多态)了父类的方法时调用子类的功能。比如
人类 a = new 男人()
a.嘘嘘() 那么显然这里调用的是男人类嘘嘘的方法,因为子类可以重写父类的这个方法
2、什么情况下才用到这种赋值操作!我实在抽象不出来。
==
用处非常多,比如我写一个方法
public void TestMethod(人类 a)
{}这样的方法就非常灵活,你可以传一个人类的对象,也可以传一个男人类的对象或者是女人类的对象
1.这里并不是赋值,而是类型转换
2.上面你的代码运行和你期望的不符,只是你用了new关键字,而不是override, new是隐藏父类成员,override则是重载
3.理解这个需要对 “对象”在内存中的存在形式有所了解。这个东西描述起来有点复杂,我尽可能简单的讲。
对象实际在内存中拥有一个静态成员表,和一个虚拟成员表。
像你自己的代码:
baseClass--对象开始基地址
虚函数表:Method1() -------相对偏移地址 ------基地址+ 相对偏移地址的内存中放了Console.WriteLine("baseClass"); 这个具体执行代码derivedClass ----对象基地址 new void Method1()
因为是new表明要隐藏父类Method1() 因此虚函数表:Method1()的相对偏移地址被改动到Console.WriteLine("derivedClass")这段代码的内存区域中,同时原来父类中的Method1指向的Console.WriteLine("baseClass")代码任然存在对象中,只是Method1的指向并没有指向他,而是指到了新的位置(从这个层面上讲,父类的Method1被隐藏了) 在看override的情况[code=C#]override void Method1()
overide表示是覆写函数,也就是说他并没有移除虚函数表的 Method1和他对应的相对偏移地址,而是把基地址+ 相对偏移地址的内存中存放的Console.WriteLine("baseClass")直接改写成了Console.WriteLine("derivedClass"); 了解了上面这个,我们在看看“类型转换”具体做的啥事情,“类型转换”实际上就把一个类的静态函数表和虚函数表赋给了另一个类。
new void Method1() ----类型转换时因为载入的是父类的虚函数表,所以其Method1的指向,又被改回父类地址,所以他任然执行父类函数
override void Method1 ------类型转换载入父类函数表,因为指向的内存中的执行语句变了,所以他实际执行的是子类的函数呵呵,讲了这么半天,我突然觉得是在变魔术,兔子变鸡,鸡变兔子,看着挺神奇,只是我们没看见后面的秘密(就像我们通常不了解内存里放了啥一样),只要只到秘密,就不值一提了
3.最后多态实际上用在一些大体相似,但具体不同的情况。给你个粗俗的例子:class 人
{
void virtual sex()
{
}
}class 男人:人
{
override sex()
{
插
}
}class 女人:人
{
override sex()
{
被插
}
} 人 第一个人=new 男人()
第一个人.sex()-----------插
人 第二个人=new 女人()
第二个人.sex()-----------被插看明白了吗,他们都要sex,只是做的事情不一样
我都看得头晕了下面用JAVA的话给你阐述什么是多态
1、继承。
2、方法重写。
3、父类的对象指向子类的实例。OK!
强迫自己去理解是恨难的。
做多了、就明白了。