先看代码(很简单的):
先看代码(很简单的):
class baseclass
{
public int a;
public int b;
public virtual void inc()
{
a = -a;
b = -b;
Console.WriteLine("Call base::inc()");
Console.WriteLine();
}
public baseclass()
{
a = 0;
b = 0;
Console.WriteLine("Call base().");
Console.WriteLine();
}
public baseclass(int va , int vb)
{
a = va;
b = vb;
Console.WriteLine("Call base(int va , int vb).");
Console.WriteLine();
}
public int add()
{
inc();
Console.WriteLine("Call base:add(int va , int vb).");
return a + b;
}
} class sub:baseclass
{
public override void inc()
{
a ++;
b ++;
Console.WriteLine("Call SUB::inc()");
Console.WriteLine();
}
public sub():base()
{
Console.WriteLine("Call SUB()");
Console.WriteLine();
}
public sub(int va , int vb):base(va , vb)
{
Console.WriteLine("Call SUB(va , vb)");
Console.WriteLine(); }
}sub继承自baseclass
public class test
{
public static void Main()
{
int ret;
baseclass base1;
sub sub2 = new sub(1, 1);
base1 = (baseclass)sub2;//在此进行了显式类型转换
ret = base1.add();//还是调用add方法还是调用sub:inc()
if(base1 is sub)//测试条件为true
{
Console.WriteLine("base1 is sub");
Console.WriteLine("ret = {0}" , ret);
Console.WriteLine();
}
}
}
我想问
1.为何进行了显式类型转换,ret = base1.add()还是调用sub:inc(),(base1 is sub)为True?
2.有没有方法把派生类对象完完全全转换成基类对象?
先看代码(很简单的):
class baseclass
{
public int a;
public int b;
public virtual void inc()
{
a = -a;
b = -b;
Console.WriteLine("Call base::inc()");
Console.WriteLine();
}
public baseclass()
{
a = 0;
b = 0;
Console.WriteLine("Call base().");
Console.WriteLine();
}
public baseclass(int va , int vb)
{
a = va;
b = vb;
Console.WriteLine("Call base(int va , int vb).");
Console.WriteLine();
}
public int add()
{
inc();
Console.WriteLine("Call base:add(int va , int vb).");
return a + b;
}
} class sub:baseclass
{
public override void inc()
{
a ++;
b ++;
Console.WriteLine("Call SUB::inc()");
Console.WriteLine();
}
public sub():base()
{
Console.WriteLine("Call SUB()");
Console.WriteLine();
}
public sub(int va , int vb):base(va , vb)
{
Console.WriteLine("Call SUB(va , vb)");
Console.WriteLine(); }
}sub继承自baseclass
public class test
{
public static void Main()
{
int ret;
baseclass base1;
sub sub2 = new sub(1, 1);
base1 = (baseclass)sub2;//在此进行了显式类型转换
ret = base1.add();//还是调用add方法还是调用sub:inc()
if(base1 is sub)//测试条件为true
{
Console.WriteLine("base1 is sub");
Console.WriteLine("ret = {0}" , ret);
Console.WriteLine();
}
}
}
我想问
1.为何进行了显式类型转换,ret = base1.add()还是调用sub:inc(),(base1 is sub)为True?
2.有没有方法把派生类对象完完全全转换成基类对象?
public sub():base()
{
......
}
public sub(int va , int vb):base(va , vb)
{
......
}
定义成员之后的base(va,vb)是什么意思?
-------------------------------------调用基类的构造函数。
base1指向的对象是sub类的实例,这个操作是运行时决定的。
根据多态原则,base1.Add调用baseclass的add函数,下面
if(base1 is sub) 是判断引用的对象是什么类型,这里判断的是对象,不是引用本身。引用还是基类的没错。但这个对象是用sub实例化的。
在声明派生类构造函数的时候,
可以通过base关键字调用直接基类构造函数,并另外可以新增字段的值
base1.add()也是调用的sub 类继承下来的add()方法;没有必要把派生类对象完完全全转换成基类对象,你直接定义基类对象不就可以了吗?
基类的add改一下,改为:
public int add(int i)
{
inc();
Console.WriteLine("Call base:add(int va , int vb).");
return a + b + i;
}
class baseclass
{
public int a;
public int b;
public virtual void inc(){
a = -a;
b = -b;
Console.WriteLine("Call base::inc()");
Console.WriteLine();
}
public baseclass()
{
a = 0;
b = 0;
Console.WriteLine("Call base().");
Console.WriteLine();
}
public baseclass(int va , int vb)
{
a = va;
b = vb;
Console.WriteLine("Call base(int va , int vb).");
Console.WriteLine();
}
public int add()
{
inc();
Console.WriteLine("Call base:add(int va , int vb).");
return a + b;
}
} class sub:baseclass
{
public override void inc()
{
a ++;
b ++;
Console.WriteLine("Call SUB::inc()");
Console.WriteLine();
}
public sub():base()
{
Console.WriteLine("Call SUB()");
Console.WriteLine();
}
public sub(int va , int vb):base(va , vb)
{
Console.WriteLine("Call SUB(va , vb)");
Console.WriteLine(); }
public new int add()
{
inc();
Console.WriteLine("Call sub:add(int va , int vb).");
return -(a + b);
}
}public class test
{
public static void Main()
{
int ret;
baseclass base1;
baseclass base2 = (baseclass)(new sub(1,1));
sub sub2 = new sub(1, 1);
base1 = (baseclass)sub2;
ret = base1.add();
if(base1 is sub)
{
Console.WriteLine("base1 is sub");
Console.WriteLine("ret = {0}" , ret);
Console.WriteLine();
}
ret = base2.add();
if(base2 is sub)
{
Console.WriteLine("base2 is sub");
Console.WriteLine("ret = {0}" , ret);
Console.WriteLine();
}
}
}运行结果如下:Call base(int va , int vb).Call SUB(va , vb)Call base(int va , int vb).Call SUB(va , vb)Call SUB::inc()Call base:add(int va , int vb).
base1 is sub
ret = 4Call SUB::inc()Call base:add(int va , int vb).
base2 is sub
ret = 4Press any key to continue
可见base1与base2行为完全一样.base1.add()与base2.add()均调用base:add(),而base:add()又调用sub:inc().因为base:add()方法未声名为virtual,sub:add()也未声名为override.而inc()被声名为virtual,且被重载.将add()改为virtual,结果显示sub:add()被调用.
base1与base2为baseclass引用,但引用的对象为sub类型对象.
对吗?
但我比较困惑的是baseclass base2 = (baseclass)(new sub(1,1));与base1 = (baseclass)sub2;都进行了显式转换,它们引用的对象还是sub类型对象.这一点好像与C++中不同,比如在C++中:
(base:inc()是virtual函数,在sub类中重载)
base* pbase2;
sub sub3(1 , 1);
pbase2 = &(base)sub3;
ret = pbase2->add();//add()调用base:inc()
cout<<"ret = "<<ret<<endl<<endl;C#中有没有方法能达到同样的效果呢?
base construct function with two Variables.
Call child construct function with two Variables.
base construct function with two Variables.
Call child construct function with two Variables.
Call child::inc()///////////////这里也调用的是子类的,不是基类的。
Call base:add(int va , int vb).
#include <stdlib.h>class BaseClass
{
public:
virtual void inc()
{
a*=-1;
b*=-1;
cout<<"base inc";
} BaseClass()
{
cout<<"base construct function without any Variable."<<endl;
} BaseClass(int a,int b)
{
this->a = a;
this->b = b;
cout<<"base construct function with two Variables."<<endl;
} int add()
{
inc();
cout<<"Call base:add(int va , int vb)."<<endl;
return a + b;
}protected:
int a;
int b;
};class Child:BaseClass
{
public:
Child():BaseClass()
{
cout<<"Call child construct function without any Variable."<<endl;
}
Child(int a,int b):BaseClass(a,b)
{
cout<<"Call child construct function with two Variables."<<endl;
} void inc()
{
a ++;
b ++;
cout<<"Call child::inc()"<<endl;
} int add()
{
inc();
cout<<"Call child:add(int a , int b)."<<endl;
return -(a + b);
}
};int main()
{
int ret = 0;
BaseClass *pBase1 = NULL;
BaseClass *pBase2 = (BaseClass*)new Child(1,1);
Child *child = new Child(1,1);
pBase1 = (BaseClass*)child;
ret = pBase1->add();
system("pause");
return 0;
}
试试这一句(在你的程序中):
pBase1 = &(BaseClass)(*child);ret = pBase1->add();