由于分不够了。只有30分。请教,拜谢
java代码package example;
class m1
{
public int getInt()
{
return 0;

}
}
class m2 extends m1
{
public int getInt()
{
return 1;
}
}
public class Override
{
public static void main(String[] args)
{
m1 m = new m2();
m.getInt();
System.out.println(m.getInt());
}
}
//输出的是1,说明是调用的是m2的getInt()方法下面是C#的代码namespace test1
{
    class Override
    {
        public int getInt()
        {   
            return 0;
        }
    }
    class InheritOverride : Override
    {
         public int getInt()
        {
            return 1;
        }
    }
    class G0
    {
        static void Main()
        {
            Override i = new InheritOverride();
            int j = i.getInt();
            Console.Write(j);//输出的是0,说明调用的是父类的getInt()方法
            Console.ReadKey();
        }
    }
}
疑问:两种语言的重写机制有什么不同吗,C#只有用virtul,abstract,父类的对象才会指向子类的重写方法。而java不是的

解决方案 »

  1.   

    Java不了解。C#需要用virtual/override,否则不会覆盖父类成员,你应该收到一个编译器警告。
      

  2.   

    因为 C# 按照java 那种方式写,子类默认省略了new 修饰关键字区别是早期加载和晚期加载晚期加载
     m1 m = new m2();
    调用的是m2的方法早期加载
     m1 m = new m2();调用的是m的方法,实际上就不是覆盖(重写)了,java不熟悉,不知道有无早期加载C# 有无关键字,是两套机制
      

  3.   

    早期加载(new修饰)和晚期加载(override修饰)
      

  4.   

    如果用new 来修饰m2的getInt()方法输出的也是0(就是m1的getInt()方法)
    我也知道如果m1的方法变成虚的,或者是抽象的。继承m1的类m2用override重写。
    Override i = new InheritOverride();
                int j = i.getInt();
    i对象会指向InheritOverride的getInt()方法的
    还有2楼所说的,覆盖和重写有什么区别
      

  5.   

    覆盖和重写只是不同翻译而已我的意思是    class InheritOverride : Override
        {
             public int getInt()
            {
                return 1;
            }
        }这样的实际 是
      public new int getInt()
            {
                return 1;
            }编译器自动加的区别 主要就是我说的 两种加载
      

  6.   

    C#实现晚期加载是不是父类的方法必须是virsual,abstract的?
      

  7.   

    大哥的意思是不是 如果在C#中实现多态性(方法重写)肯定需要override的。是吗?还有new关键字到底有没有方法重写的特性呢
    如果不写new,会给出警告 
    警告 1 “test1.InheritOverride.getInt()”隐藏了继承的成员“test1.Override.getInt()”。如果是有意隐藏,请使用关键字 new。 E:\NETProgram\重写\test1\Program.cs 17 21 test1
      

  8.   

    结贴了。可以到java板块那里也有同样的帖子。去回帖,我给分
      

  9.   

    大哥你的写的深奥,不怎么理解啊。我对你上面写的理解写在下面,请你看看是不是对的啊
    是不是最好不用new 来有意隐藏。实现方法重载还是用override
      

  10.   

    隐藏成员这种事情对于一般的开发者来说,就如同故意定义一个局部变量混淆成员变量一样,毫无作用,只能是故意刁难其他开发者和制造混乱。new 的意思就是,你虽然用了同一个名字,但是你在定义一个和父类方法毫不相关的新方法。
    所谓毫不相干,就好比你随便拿出两个方法,他们一点关系也没有一样。
    既然毫不相关,那么多单词那么多字母,你就不能起一个另外的名字么???
      

  11.   

    注意你是怎么 实例化对象的!如果你在声明对象的时候用的是  InheritOverride i = new InheritOverride();
    结果就是 1, 这叫 方法的 隐藏 (隐藏父类的方法,执行本类中的方法), 但会出现 警告:隐藏了继承的成员“…Program.Override.getInt()”。如果是有意隐藏,请使用关键字 new。  所以尽量用 new 显式隐藏而你 定义的是Override i = new InheritOverride();  但凡定义一个 派生类对象的时候都默认地生成 匿名的 父类对象, 方法隐藏只是不会调用父类的方法,但其实在子类中还存在 父类的 getInt() 方法,这样调用的其实还是父类的方法怎么表达清楚呢,等你用到virtual –override ,这才叫方法的 重写,来实现多态,就能声明 派生类对象, 达到你想要的结果拉。
      

  12.   

    本来我也没想那么多。只是我记得java中的重写的父方法并不需要是abstract,也可以动态指向子类的对象方法
    C#必须是abstract。。才能
      

  13.   

    举个例子A是1.1版本文件上传,内部采用标准的Request.Files
    B是2.0版本文件上传,内部采用了Flash这个时候,你说,应该覆盖吗?如果我的浏览器不支持Flash呢?
    于是有人想用B,比如安卓
    有人还想用A,比如苹果实际上多态有两种(C++某书的说法)静态和动态
    前者包括了重载,和new
    后者包括了,重写所谓的 早期,和晚期,和静态动态等同早期指的是,在编译期间就确定好的,固定调用
    晚期指的是,在运行期间就决定的,而它具有不确定性,可以由反射等机制创建对象在继承的角度说,是指针指向对,对象区域不同的对象的相同代码偏移(C# via)所以个人认为存在就有道理。编译器提醒,是面向程序员的,而非error多写代码,多用实践来理解。
      

  14.   

    本帖最后由 caozhy 于 2012-04-23 21:18:52 编辑
      

  15.   

    非常谢谢你。你的解释让我记起了java的静态绑定和动态绑定。虽然分不多,但是还是非常感谢大家的解答
      

  16.   

    和C#完全无关。进一步说,C#根本不需要考虑“选择哪个子类实现”这样的问题,这些问题CLR都解决了。从某种程度上说(注意只是某种程度),C#都是“动态联编”。
      

  17.   

    举个例子: 
    class BaseClass 

    public virtual void DoSomething(){} 
    } class SubClass1 : BaseClass 

    public override void DoSomething(){} 
    } class SubClass2 : BaseClass 

    public new void DoSomething(){} 
    } 然后用基类的类型建两个子类的实例 
    BaseClass object1= new SubClass1() 
    BaseClass object2= new SubClass2() object1.DoSomething()调用的是子类Override后的新方法 
    object2.DoSomething()调用的仍然是基类的方法
    下面是从MSDN拷贝来的:准则
    重写通常用在以下情况下:您要定义多态性派生类。您需要安全地让编译器强制执行相同元素类型和调用序列。隐藏通常用在以下情况下:您希望可以修改基类并使用您的名称定义元素。您希望可以随意更改元素类型或调用序列。 
    "C#方法隐藏和重写有何区别" C#允许派生类中的方法与基类中的方法具有相同的名称 ; 
    在基类中引入与派生类中的某个成员具有相同名称的新成员在C#中是完全支持的; 
    这时你必须明确告诉编译器,你希望的操作是怎么样的! 
    // 
    //new 隐藏方法情况 
    // 
    class MyClass 

    public void Get() 

    Console.WriteLine("He is Father"); 


    class YourClass :MyClass 

    public new void Get() //定义了一个与父类同的名方法 而不是实现父类Get() 

    Console.WriteLine("He is Son"); 


    class Program 

    static void Main() 

    YourClass y=new YourClass(); 
    y.Get()//He is Son 
    MyClass m=y; 
    m.Get();//He is Father 


    在派生类中,不加new 程序也会成功编译运行,只不过编译器会发出警告,没有关系不用理它,因为当在派生类上 定义有与基类同名的方法时,编译器的默认行为就是隐藏基类的同名成员! 
    // 
    //Virtual 虚方法 重写实现 
    // 
    class MyClass 

    public virtual void Get() 

    Console.WriteLine("He is Father"); 


    class YourClass :MyClass 

    public override void Get() //子类重新实现Get()方法,但此方法的定义是在父类中 
    { //如果父类此方法不是被虚virtual的或抽象的abstract, 
    Console.WriteLine("He is Son");//不能使用override关键进行重写 

    //public new virtual void Get(){} 隐藏 
    //public new void Get(){} 

    class Program 

    static void Main() 

    YourClass y=new YourClass(); 
    y.Get()//He is Son 
    MyClass m=y; 
    m.Get();//He is Son //输出:相比隐藏情况,调用的是子类的新实现 


    面象对象编程的重要特性之一,就是继承与多态,C#中的每一种类型都是多态的,而每一种类型的成员组成, 都是拥有(继承)父类上定义的成员与自身定义的成员,如果父类上的成员实现,并不适合自己的需要,子类就有 可能重写(替换实现)父类成员,实现自己的需求!C#语法要求父类成员必须虚的或抽象的,子类才可以重写(替换实现). 如果你不是在子类中重写而是在自身类型上定义了一个与父类同名的方法,此时,就需要new关键来隐藏基类的同名 
    成员,告诉编译器,这是你所希望的操作!当然,大多数的情况下,我们都是对基类成员进行重写,而不是进行隐藏操作! 成员有virtual修饰,又会有new(隐藏)修饰的存在,是应对程序的变化!以便不同库中的基类与派生类之间的版本控制可以不断向前发展,同时保持向后兼容.
      

  18.   

    重写=覆盖。
    在java中默认是重写。
    在C#中如果需要重写,得添加关键字virtual
      

  19.   

    java 所有函数都是虚函数,只能重写,不能覆盖。
    C++ 加了virtual的才是虚函数,虚函数只能重写,非虚函数只能覆盖
    C# 加了virtual或者abstract的才是虚函数,虚函数可以重写,也可以覆盖,非虚函数只能覆盖
      

  20.   

    尼玛蛋疼
    C#的两种重写关键字 在逻辑上让人是很清晰的
    反观JAVA的在逻辑层次上让人很不清楚这代码是怎么来的
      

  21.   

    1、c# 的重写和隐藏是来两个概念
    2、java 直接默认是重写
    3、不要把c#的重写和重载混为一谈