发表于 @ 2006年10月06日 02:18:00

今晚在群里讨论很久关于隐藏方法,的一些相关东东,总结一下内容.

Java

1.根据Java Language Specification (Version 3) 8.4.8 的描述,子类在继承父类时,对于方法而言,存在两种关系:


A. override 即覆盖,这是对实例方法(instance method)而言的;子类与父类中形构相同的方法(原文中是 subsignature,它的范围比“形构相同”要大,请参考原文)会override 父类中的那个方法。


B. hide 即隐藏,这是对类方法(class method)即static 方法而言的。如果子类中定义了静态方法,则它会隐藏父类中形构相同的(原文中是 subsignature,它的范围比“形构相同要”大,请参考原文)所有方法,但如果隐藏了父类中的实例方法,则会编译报错。


public 
     
   class 
    TestHideMethod
{
     
   public 
     
   static 
     
   void 
    staticMethod()
    {
        System.out.println( 
   " 
   Test 's static Method 
   " 
   );
    }

     
   public 
     
   static 
     
   void 
    main(String[] args)
    {
        TestHideMethodSub ts  
   = 
     
   new 
    TestHideMethodSub();
           
   // 
   调用的还是子类的方法,相当于 TestHideMethodSub.staticMethod(); 
   
 
           ((TestHideMethod) ts).staticMethod();
    }
}

 
   class 
    TestHideMethodSub  
   extends 
    TestHideMethod
{
     
   // 
   隐藏方法 
   
 
        
   public 
     
   static 
     
   void 
    staticMethod()
    {
        System.out.println( 
   " 
   TestStatic 's static Method 
   " 
   );
    }
}



结论:

隐藏方法:重写父类的一个static方法. JAVA中除了static方法外,实例方法是无法被隐藏的因为当调用static method时,即使是通过实例调用此方法,但实际上编译时,就首先取出该实例的类型,并对类型的该方法进行了绑定,所以再动态转型也时无济于事的.(引用群主:midthinker)


 

C#

new方法


class 
    Test
{
     
   public 
     
   virtual 
      
   void 
    test()
    {
        Console.WriteLine( 
   " 
   test 
   " 
   );
    }
     
   static 
     
   void 
    Main(String[] args)
    {
        Test3 t3  
   = 
     
   new 
    Test3();
        t3.test();
         
   // 
   调用的是父类的方法. 
   
 
           ((Test)t3).test(); 
     }
} 
  
 
   class 
    Test3
{
    
   // 
   隐藏方法 
   
 
        
   public 
     
   new 
     
   void 
    test()
    {
        Console.WriteLine( 
   " 
   Test3 
   " 
   );
    }
}



结论:

对方法得调用依据得是引用类型,而不是实例本身得类型啊,所以当你将t3得引用类型转型成Test后,她实际调用得是Test.test method,而不管实际得类型是什么,所以这里就排斥了多态.(引用群主:midthinker) Java和C#的隐藏方法的区别在Java中隐藏方法只能对static method进行,因为static成员属于类成员,所以java中即便是动态转换,调用的还是改类(子类)的静态方法.进行隐藏主要目的是不要从父类继承下来的静态方法. C#中则不一样,可以对父类得virtual函数进行隐藏,而且隐藏方法可以通过动态转换来调用父类的virtual方法,这一点跟override是不一样的..感觉灵活性大,但具体在哪种场景下使用还未知.