首页 新闻 会员 周边 捐助

c#基础问题 请教大侠,没什么豆 谢谢!

0
[已解决问题] 解决于 2013-05-30 23:30

代码:

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             BaseClass bc1 = new SubClass1();
 6             BaseClass bc2 = new SubClass2();
 7             SubClass1 sc1 = new SubClass1();
 8             SubClass2 sc2 = new SubClass2();
 9 
10             bc1.Prinf();
11             bc2.Prinf();
12             sc1.Prinf();
13             sc2.Prinf();
14         }
15     }
16 
17     abstract public class BaseClass
18     {
19         public virtual void Prinf()
20         {
21             Console.WriteLine("虚方法");
22         }
23     }
24 
25     class SubClass1 : BaseClass
26     {
27         public override void Prinf()
28         {
29             Console.WriteLine("重写方法");
30         }
31     }
32 
33     class SubClass2 : BaseClass
34     {
35         public new void Prinf()
36         {
37             Console.WriteLine("新方法");
38         }
39     }
BaseClass bc2 = new SubClass2(); 里面的
 bc2.Prinf();为什么输出的是虚方法呢?
SubClass2类里面的new不是隐藏了基类的方法吗? 

1:还有我看书上说基类对象引用实例只能拥有自己的方法和属性(不能拥有派生类的方法或者属性)
2: 同理派生类对象实例化 就拥有了基类的属性和方法。

后面一句我到没有疑问 :前面一句 "1"(我看书上说基类对象引用实例只能拥有自己的方法和属性(不能拥有派生类的方法或者属性) 不是明显有问题吗?)如上面的例子
BaseClass bc1 = new SubClass1(); 申明一个基类 他的值bc1  并实例化subClass 对象赋值给bc1
这样bc1 不就拥有了 派生类的方法或者属性?

s_p的主页 s_p | 初学一级 | 园豆:140
提问于:2013-05-29 12:07
< >
分享
最佳答案
0

我将代码重新改了一下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            BaseClass bc1 = new SubClass1();
            BaseClass bc2 = new SubClass2();
            SubClass1 sc1 = new SubClass1();
            SubClass2 sc2 = new SubClass2();

            bc1.Prinf();
            bc2.Prinf();
           
            sc1.Prinf();
            sc2.Prinf();
        }

        abstract public class BaseClass
        {
            public int i = 0;
            public virtual void Prinf()
            {
                Console.WriteLine("虚方法");
                Console.WriteLine("i=" + i);
            }
        }

        class SubClass1 : BaseClass
        {
            public int j = 1;
            public override void Prinf()
            {
                Console.WriteLine("重写方法");
                Console.WriteLine("j=" + j);
            }
        }

        class SubClass2 : BaseClass
        {
            public int k = 2;
            public new void Prinf()
            {
                Console.WriteLine("新方法");
                Console.WriteLine("k=" + k);
            }
        }
    }
}

可以运行一下上面的代码。看看结果。

现在来看看问题:

1:

BaseClass bc2 = new SubClass2(); 里面的
bc2.Prinf();为什么输出的是虚方法呢?
SubClass2类里面的new不是隐藏了基类的方法吗? 

答:在用作修饰符时,new 关键字可以显式隐藏从基类继承的成员。 隐藏继承的成员时,该成员的派生版本将替换基类版本 虽然可以在不使用 new 修饰符的情况下隐藏成员,但会生成警告。 如果使用 new 显式隐藏成员,则会取消此警告,并记录要替换为派生版本这一事实。

对同一成员同时使用 newoverride 是错误的做法,因为这两个修饰符的含义互斥。 new 修饰符会用同样的名称创建一个新成员并使原始成员变为隐藏的。 override 修饰符会扩展继承成员的实现。

也就是说SubClass2的new是隐藏基类的方法,但作为基类的对象bc2,是能够看到基类的方法的。

2:

还有我看书上说基类对象引用实例只能拥有自己的方法和属性(不能拥有派生类的方法或者属性)
同理派生类对象实例化 就拥有了基类的属性和方法。

答:面向对象的基本问题,老爸的东西(public的)都会留给儿子,而儿子的东西(public)并不是老爸的
BaseClass bc1 = new SubClass1() 这里也可以看到运行的结果是“重写方法 j=1”,看上去好像bc1拿到了儿子的东西,其实并不是这样,在vs里输入bc1. 然后可以看到弹出的方法或者属性是i和printf(),没有j。也就是说“基类对象引用实例只能拥有自己的方法和属性”。那么为什么显示的结果中确有j呢?这是因为bc1这个对象的类型是SubClass1,而它继承了BaseClass 并对printf进行了override操作。bc1因为printf被重写,所以显示了新的结果,但它自身的成员列表是不变的。



奖励园豆:5
WuRang | 小虾三级 |园豆:1730 | 2013-05-30 10:17

谢谢 朋友你这个解释很好! 

老爸的东西(public的)都会留给儿子,而儿子的东西(public)并不是老爸的........ 我对着你的例子运行 bc1确实点不出j 看来书上说的确实没有错!
s_p | 园豆:140 (初学一级) | 2013-05-30 23:26
其他回答(1)
1

首先new这个关键字在此处的用法你还没太弄明白,override描述的方式在子类中把基类的方法内部实现用子类的实现替换掉,而new描述的方法则是子类中添加一个同名方法,也既是说在方法列表中有两个方法,一个是基类的,一个是子类的,子类在调用时默认调用子类实现的方法,而基类只能调用基类的方法。

不知道这么解释你明白不。

BaseClass bc1 = new SubClass1(); 申明一个基类 他的值bc1  并实例化subClass 对象赋值给bc1
这样bc1 不就拥有了 派生类的方法或者属性?
首先bc1指向的对象还是SubClass1类型的,只是bc1这个变量声明的类型是BaseClass,所以bc1的成员列表是BaseClass的。

Gellio Gao | 园豆:254 (菜鸟二级) | 2013-05-29 15:26

谢谢朋友 明白了!

支持(0) 反对(0) s_p | 园豆:140 (初学一级) | 2013-05-30 23:29

谢谢了朋友! 只能2选1 不好意思

支持(0) 反对(0) s_p | 园豆:140 (初学一级) | 2013-05-30 23:31

@s_p: 没事,让你明白了就好。

支持(0) 反对(0) Gellio Gao | 园豆:254 (菜鸟二级) | 2013-05-31 09:21
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册