从零系列的插曲,前天被问到了一个这样的问题:如何用父类实例去调用子类方法。恕我当时学业不精对多态认识还是不到位,今天就此问题稍作研究。
class Animal {
public string Name;
public Animal() {
this.Name = "Animal";
}
public void Called() {
Console.WriteLine("Animal");
}
}
class Cat : Animal {
public Cat() {
this.Name = "Cat";
}
public void Called() {
Console.WriteLine("Cat");
}
public void Called(string str) {
Console.WriteLine(str);
}
public void Called1() {
Console.WriteLine("NoCat");
}
}
为了实际验证一下如何才能达到父类调用子类的方法,我创建了一个Animal类包含一个简单的方法用来检测。然后派生了一个子类Cat,并重载了父类的方法Called(str),和添加了一个新方法Called1。
Animal animal = new Animal();
Cat cat = new Cat();
animal.Called();
cat.Called();
cat.Called("YesCat");
cat.Called1();
首先是简单测试一下,输出结果正常:分别是Animal 、Cat、YesCat、NoCat
接着就是测试父类如何调用子类了。
Animal animal1 = new Cat();
声明一个Animal类型的变量animal1,用子类去创建它的实例。上面这句话的意思就是Animal类型的引用去指向一个Cat类实例,因为new 在内存上的是一个Cat类。按这个道理来想那么直接就可以调用子类方法呀,于是...
animal1.Called();
animal1.Called("YesCat");
animal1.Called1();
高高兴兴写了这三行然后按下了启动,(⊙v⊙)......
并不能启动...( ⊙ o ⊙ )
很显而易见animal1中无法调用Called(str)和Called1这两个方法。
原因是:在编译的时候Animal类型中不包含对Called(str)方法和Called1()方法的定义,编译将会报错。于是乎注释了下面条:
animal1.Called();
//animal1.Called("YesCat");
//animal1.Called1();
可喜可贺,返回的结果是Animal
这说明了Animal类型的引用虽然指向了Cat类,但是只能访问Cat类中所继承的Animal类方法。
那要如何才能调用子类的方法呢?
这就需要使用强转或者as
(animal1 as Cat).Called();
(animal1 as Cat).Called("YesCat");
(animal1 as Cat).Called1();
返回的结果是:Cat、YesCat、NoCat
恩,这就实现了父类调用子类方法的目的。
as 与 强转的区别
as 只支持引用类型的转换,且不会抛出异常。
强转则支持值类型和引用类型,在转换不匹配时会抛出异常。
网友评论