首页 新闻 会员 周边

c#面向对象

0
悬赏园豆:10 [已解决问题] 解决于 2013-01-24 20:03

最近温习了一下面向对象程序设计的基本知识,做了个小小的实验:

以下为c#代码:

 public class TestParameterFather
    {

    }
    public class TestParameterSon : TestParameterFather
    {

    }

    public class TestClassFather
    {

        public void TestMethod(TestParameterSon p)
        { }
    }

    public class TestClassSon : TestClassFather
    {
        public void TestMethod(TestParameterFather p)
        { }
    }

以下为Java代码

 public class TestParameterFather
    {

    }
    public class TestParameterSon extends TestParameterFather
    {

    }

    public class TestClassFather
    {

        public void TestMethod(TestParameterSon p)
        { }
    }

    public class TestClassSon extends  TestClassFather
    {
        public void TestMethod(TestParameterFather p)
        { }
    }

调用方法:

TestClassSon father = new TestClassSon();
father.TestMethod(new TestParameterSon());

结果发现在 c#里面这个 TestMethod 调用的是TestClassSon 里的TestMethod,而在java里面调用的是TestClassFather里的TestMethod,如果按照里氏替换原则来说,应该调用TestClassFather的TestMethod才对,就是说c#里面是错误的,难道说jvm和clr对于面向对象的这种调度机制不一样么

C#
zxding1986的主页 zxding1986 | 初学一级 | 园豆:192
提问于:2012-12-20 18:56
< >
分享
最佳答案
0

你自己搞混淆了吧?如果就看这样的代码

public class TestClassFather
    {

       
public void TestMethod()
        { }
    }

   
public class TestClassSon : TestClassFather
    {
       
public void TestMethod()
        { }
    }

你觉得应该调用谁的TestMethod()?再看看如下代码的结果,你这个问题是继承的问题,不要把其它的因数加进来,会把自己搞晕

 

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            TestClassFather TF = new TestClassFather();
            TestClassSon TC = new TestClassSon();
            TestClassFather TK = new TestClassSon();
            TF.TestMethod(); TC.TestMethod(); TK.TestMethod();

            TestClassFather1 TK1 = new TestClassSon1();
            TK1.TestMethod();
        }
        public class TestClassFather
        {

            public void TestMethod()
            { Console.WriteLine("父类TestMethod被调用"); }
        }

        public class TestClassSon : TestClassFather
        {
            public void TestMethod()
            {
                Console.WriteLine("子类TestMethod被调用");
            }
        }



        public class TestClassFather1
        {

            public virtual void TestMethod()
            { Console.WriteLine("父类TestMethod被调用"); }
        }

        public class TestClassSon1 : TestClassFather1
        {
            public override void TestMethod()
            {
                Console.WriteLine("子类TestMethod被调用");
            }
        }

    }
}

 

 

收获园豆:10
happydaily | 菜鸟二级 |园豆:301 | 2012-12-21 09:28
其他回答(4)
0

你搞错了吧。java不是这样的,看花眼了。

angelshelter | 园豆:9887 (大侠五级) | 2012-12-20 19:53

其实这个我是在看设计模式之禅的时候发现书上是这么描述的(java描述)然后我试了一下,确实发现有这种区别,书上描述的是会调用父类的Method。按照里氏替换原则的话应该是按java这样的。

支持(0) 反对(0) zxding1986 | 园豆:192 (初学一级) | 2012-12-20 20:50

@zxding1986: 

你确实打错了,应该是

TestClassFather father = new TestClassSon();
father.TestMethod(new TestParameterSon());
支持(0) 反对(0) angelshelter | 园豆:9887 (大侠五级) | 2012-12-20 21:00

@angelshelter: 

TestClassSon father = new TestClassSon();
father.TestMethod(new TestParameterSon());
就是这么用啊,为什么一定要用父类去引用。
支持(0) 反对(0) zxding1986 | 园豆:192 (初学一级) | 2012-12-20 21:03

@zxding1986: 扩展性强。

支持(0) 反对(0) angelshelter | 园豆:9887 (大侠五级) | 2012-12-21 10:23
0

按照里氏替换原则 子类跟 父类有同名方法,会隐藏父类方法,C#的显示就是正常的,正是符合里氏替换原则的后果,只是不建议这样用。

java不懂,不知道你的java代码是怎么搞得,既能无法访问自己的方法,那访问子类自己的方法,又该怎么办呢?

Qlin | 园豆:2403 (老鸟四级) | 2012-12-20 19:58

子类的入参应该宽于父类的同名参数吧,这样的话应该调用的是父类的方法。所以c#这样应该是不符合的的

支持(0) 反对(0) zxding1986 | 园豆:192 (初学一级) | 2012-12-20 20:53

我还是觉得c#这样是不对的,因为这样相当于我在没有override父类的方法的情况下居然子类的方法被调用了,这样违背了里氏替换原则吧。

支持(0) 反对(0) zxding1986 | 园豆:192 (初学一级) | 2012-12-20 23:03

@zxding1986: 

里氏替换 原则告诉我们 不要这样写,你这样写 同名函数 是违背里氏替换原则。

但是 既能 你这样写了,就会隐藏父类函数,这也正是 里氏替换 告诉我们的后果,执行结果 也是如此。

我相信 java 也会隐藏 父类的同名函数,要不然就 没有这个原则了,这个原则 就是提醒我们这个(不要隐藏 父类的同名函数,而不是 虚拟机来实现的,是 我们编程代码不要这样去做)。

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2012-12-21 09:03
0

晕了!!!!

jason2013 | 园豆:1998 (小虾三级) | 2012-12-21 08:18
0

你自己搞错了。Java的方法不加关键字默认都是虚方法(即C#里的virtual关键字),而C#的方法不加关键字默认不是虚方法。因此这里跟里氏替换原则没有关系。

水牛刀刀 | 园豆:6350 (大侠五级) | 2012-12-21 10:21

这个应该是正解了。我用c#比较少,确实是virtual的原因。

支持(0) 反对(0) angelshelter | 园豆:9887 (大侠五级) | 2012-12-21 10:24
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册