首页 新闻 会员 周边

关于创建对象的疑问

0
悬赏园豆:20 [已解决问题] 解决于 2013-05-06 22:46
 1 public class Bird
 2 { 
private string type = "Bird"; 3 public override void ShowType() 4 { 5 Console.WriteLine("Type is {0}", type); 6 } 7 } 8 public class Chicken : Bird 9 { 10 private string type = "Chicken"; 11 public override void ShowType() 12 { 13 Console.WriteLine("Type is {0}", type); 14 } 15 }

 

Bird bird2 = new Chicken(); 
Chicken chicken = new Chicken();

 

请问各位大侠,这上面两个对象的创建有什么区别?

另外:

bird2.type=?;

bird2.ShowType=?

我看到一本书上是说第一个等于Bird,第二个又是Type is chicken

小弟看不明白,还请各位指点下,谢谢了

xiaoqiangzhou的主页 xiaoqiangzhou | 初学一级 | 园豆:83
提问于:2013-05-05 12:44
< >
分享
最佳答案
1

确实是个细节问题,之前也没注意过,也想不起有什么官方解释,我把代码弄下来执行了下,个人结论是:能发生隐士转换的两个对象,由Chicken(具体类)向上隐士\强制转换为bird(基类)都不会创建新对象,使用其GetHashCode()得知还是原来的对象,所以Bird bird2 = new Chicken(); 其bird2只是指向Chicken对象的一个引用,所以其“Type is Chicken”。。。(装箱和拆箱---即值类型和引用类型之间转换是会创建新对象的)

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Chicken chicken1 = new Chicken();
            Console.WriteLine(chicken1.GetHashCode());
            Bird bird2 = chicken1;
            Console.WriteLine(bird2.GetHashCode());
            Console.WriteLine();
            bird2.ShowType();
            Chicken chicken = new Chicken();
            chicken.ShowType();
            Console.Read();
        }
    }

    public class Bird
    {
        private string type = "Bird";
        public virtual void ShowType()   // 注意这里是 virtual
        {
            Console.WriteLine("Type is {0}", type);
        }
    }
    public class Chicken : Bird
    {
        private string type = "Chicken";
        public override void ShowType()
        {
            Console.WriteLine("Type is {0}", type);
        }
    }
}

输出:

37121646
37121646

Type is Chicken
Type is Chicken

收获园豆:15
滴答的雨 | 老鸟四级 |园豆:3660 | 2013-05-05 23:44

滴答的雨:

谢谢您的回答,您说bird2只是指向Chicken对象的一个引用,这句话我不太理解。

网上有人说:bird2為Bird類型的指針,而chicken為Chicken類型的指針,那麼之後再調用方法的時候將會有筆筒的方法權限。比如說,bird2就不能調用showcolor這個方法。再看看shotype方法。chicken.ShowType()的結果是"Type is Chicken:",bird2.ShowType();的結果是“Type is Chicken”。明顯看出了,bird2調用的是Bird類中的方法。而chicken調用的是Chicken的方法。又一次說明了引用類型的區別決定不同的對象在方法裱中的訪問權限。 按到上面这段话既然bird2調用的是Bird類中的方法那应该是输出Type is Bird啊,是这样理解吗?另外我将Chicken类中的ShowType()方法去掉override关键字,执行运行的结果是Type is Bird。这又是做何解呢?

xiaoqiangzhou | 园豆:83 (初学一级) | 2013-05-06 11:21

网上有说对象执行就近原则:对于同名字段或者方法,编译器是按照其顺序查找来引用的,也就是首先访问离它创建最近的字段或者方法,例如上例中的bird2,是Bird类型引用,因此会首先访问Bird_type(注意编译器是不会重新命名的,在此是为区分起见),如果type类型设为public,则在此将返回“Bird”值。按这个意思他既然是Bird类型应该也首先访问Bird类里面的方法啊?

xiaoqiangzhou | 园豆:83 (初学一级) | 2013-05-06 11:27

@xiaoqiangzhou: 我的理解是,bird2和new Chicken()出来的对象是一样的,GetHashCode()码是一样的嘛。所以输出会是  type is chicken

另外:bird2為Bird類型的指針,Chicken也是bird类型,他们具有父子关系。至于你说的方法权限,除了修饰符(eg:publick,private等)限制外,当然是方法属于谁谁才能调用。bird2此时是指向new Chicken()对象,所以他调用的是被override的方法。

滴答的雨 | 园豆:3660 (老鸟四级) | 2013-05-06 11:32

@xiaoqiangzhou: 至于你说的就近原则我是这样理解,抽象类属于高层,具体类处于底层。从低往上。其实也可以这样理解bird开出了虚方法virtual,chicken重写了override该方法,最后被改的地方应该属于最近的

滴答的雨 | 园豆:3660 (老鸟四级) | 2013-05-06 11:35

@滴答的雨: Bird bird2 = new Chicken();

Chicken chicken = new Chicken();这两个对象初始化操作,我知道bird2, chicken和都是Chicken()的对象,关键就在于他们的引用类型,前者是Bird类型,后者是Chicken类型,我不太理解的就是这连个引用类型有啥区别,从bird2不能访问showcolor这个方法,可以知道bird2的访问权限是在Bird类中的(因为它是Bird的引用,是这样理解吗?)当bird2调用ShowType()时,开始应该是访问父类Bird的ShowType(),但是该方法在子类Chicken()被重写了,所以它具体的调用应该是重写的那个方法,这也是为什么当我在Chicken()类中不重写ShowType()方法的话,bird2.ShowType()输出type is Bird的原因

请问是这样理解吗?

xiaoqiangzhou | 园豆:83 (初学一级) | 2013-05-06 13:37

@xiaoqiangzhou: 

这时这两个引用类型没啥区别,bird2和chicken都类似指针(存储着一个引用地址),这个指针指向同一个new Chicken()对象

 

对于你重写的理解是正确的

滴答的雨 | 园豆:3660 (老鸟四级) | 2013-05-06 14:16

@滴答的雨: 

谢谢你的不吝赐教,我大概理解了,希望以后有问题还能请教与你

xiaoqiangzhou | 园豆:83 (初学一级) | 2013-05-06 22:46
其他回答(1)
0

这个问题Debug一下看一下执行顺序就明白了。

收获园豆:5
@@@一统@@@ | 园豆:1551 (小虾三级) | 2013-05-05 12:56

你好,但是为什么会是这样呢?既然

bird2.type=Bird

为什么

bird.ShowType不是等于Type is Bird的呢,请指教

支持(0) 反对(0) xiaoqiangzhou | 园豆:83 (初学一级) | 2013-05-05 14:06

@xiaoqiangzhou: 

bird.ShowType 你上面的代码没有写出来这个对象的实例

支持(0) 反对(0) @@@一统@@@ | 园豆:1551 (小虾三级) | 2013-05-05 14:44

@@@@一统@@@: 

bird.ShowType 不就是调用 public override void ShowType()
4    {
5     Console.WriteLine("Type is {0}", type);
6    }
吗?

支持(0) 反对(0) xiaoqiangzhou | 园豆:83 (初学一级) | 2013-05-05 19:39

@xiaoqiangzhou: 

我的意思是 bird  的实例化,类似 Chicken chicken = new Chicken();

支持(0) 反对(0) @@@一统@@@ | 园豆:1551 (小虾三级) | 2013-05-05 19:54

@@@@一统@@@: 

你好,不好意思,我上面打错了,应该是:bird2.ShowType=?

实例化为Bird bird2 = new Chicken();

支持(0) 反对(0) xiaoqiangzhou | 园豆:83 (初学一级) | 2013-05-06 11:12
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册