再谈重载与覆写

昨天我在新手区发了一篇《重载还是覆写?》的随笔,后来我发现我犯了一个严重的错误,没有具体说明是.NET 1.1还是2.0,在.NET2.0中由于泛型的出现,对重载和覆写有时候就不能按照1.1下那几个特征去要求。

1.重载(Overload

.NET1.1下,我们定义重载:类中定义的方法可能有不同的版本,它具有如下的特征:

I.           方法名必须相同

II.         参数列表必须不相同,与参数列表的顺序无关

III.       返回值类型可以不相同

示意代码:

public class MyClass
{
    
public void Write(string _str)
    

        
//
    }

    
public void Write(string _str, string _target)
    

        
//
    }

    
public bool Write(string _str, string _target, bool _flag)
    

        
//
    }

}

.NET2.0下,由于泛型的出现,我们就不能再用这三个特征来判断重载,如下面的两个方法,它们具有相同的方法名,相同的参数列表,相同的返回值,但是它们却可以构成重载:

public class MyClass
{
    
public void Write<T>(string _str)
    

        
//
    }

    
public void Write(string _str)
    

        
//
    }

}

再看下面这两个方法,它们不能构成重载,因为如果TU如果实例化时传入相同的类型,则这两个方法就具有相同的签名:

public class MyClass8<T,U>
{
    
public T MyMothed(T a, U b)
    
{
        
return a;
    }

    
public U MyMothed(U a, T b)
    
{
        
return b;
    }

}

但是当我们再添加另外一个方法后,这个类却可以编译通过:

public class MyClass8<T,U>
{
    
public T MyMothed(T a, U b)
    
{
        
return a;
    }

    
public U MyMothed(U a, T b)
    
{
        
return b;
    }

    
public int MyMothed(int a, int b)
    
{
        
return a + b;
    }

}

通过调用可以发现,优先匹配的方法是一般方法,而非泛型方法。总之,构成重载的第二个特征参数列表必须不同,其实是让方法具有不同的签名,调用程序可以区分,在有泛型时要特别注意,而第一点和第三点仍然适用。

2.覆写(Override

.NET1.1下,对覆写我们的定义是:子类中为满足自己的需要来重复定义某个方法的不同实现,它具有如下特征:

I.           通过使用关键字Override来覆写

II.         只有虚方法和抽象方法直接可以被覆写

III.       相同的方法名

IV.       相同的参数列表

V.         相同的返回值类型

示意代码:

public abstract class BaseClass
{
    
public abstract void Write(string _str);
}

public class SubClass : BaseClass
{
    
public override void Write(string _str)
    
{
        
//
    }

}

.NET2.0中,泛型方法的覆写,除了要遵守以上几点外,还应该注意:

在重写定义了泛型参数的虚拟方法时,子类方法必须重新定义该方法特定的泛型参数:

public class MyBaseClass
{
    
public virtual void MyMothed<T>(T t)
    
{
        
//  
    }

}

public class MySubClass : MyBaseClass
{
    
public override void MyMothed<T>(T t)//重新定义泛型参数T
    {
        
// 
    }

}

在重写定义了泛型参数的虚拟方法时,子类实现不能重复在基类方法级别出现的约束:

public class MyBaseClass
{
    
public virtual void MyMothed<T>(T t) where T : new()
    

        
//  
    }

}

public class MySubClass:MyBaseClass
{
    
public override void MyMothed<T>(T t)//不能重复任何约束
    {
       
// 
    }

}

作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2006-03-10 13:03 TerryLee 阅读(2286) 评论(12)  编辑 收藏 网摘 所属分类: [01]  .NET大本营

  回复  引用  查看    
#1楼 2006-03-10 13:35 | windwolf      
指正楼主一个错误:
并非”只有虚方法和抽象方法才能够被覆写“,普通方法也能用new关键字覆写
class A
{public void Fun(){}}
class B : A
{public new void Fun(){}}
不过这种覆写不支持多态
  回复  引用  查看    
#2楼 2006-03-11 01:20 | Sheva      
@windwolf
你说的那种不能叫做重写(overriding),只能算是一种隐藏基类相同签名方法的一种方式,而且这种方式在没有必要的时候最好不要用。这和重写的概念是完全不一样的。

Sheva
  回复  引用    
#3楼 2006-03-11 07:54 | coolWarter [未注册用户]
Sheva 说的对啵:
new(新方法,通知VM我是新方法,你不搞错了,如果你引用的是上级Class类型,请不要调用我)
Overrdie(覆盖基类方法,我的实例,我的方法)
好像是这样。。。。。
  回复  引用    
#4楼 2006-03-11 08:06 | coolWarter [未注册用户]
new 关键字的使用,主要是解决软件版本的问题。
比如:你继承一个XXX类,但是XXX类是别人写的,你不知道XXX类以后会新增方法,会做什么修改,你新增一个方法,3个月后某美眉修改了XXX类,可能她新增的方法和你的方法有相同的签名,怎么办,就New一下嗦。哇色就是设计规划不好的结果
  回复  引用  查看    
#5楼 [楼主]2006-03-11 11:05 | Terrylee      
我已经改正过来了:)
  回复  引用  查看    
#6楼 2006-03-11 14:23 | windwolf      
@sheva
你所说的override,其实是polymorphism。覆写和多态是两个层面上的意思。
覆写只是一种表现手段,而多态是一类行为方式(玄了点:))
new覆写是覆写,但不支持多态。(这个我在第一个feedback就指出过了)
  回复  引用  查看    
#7楼 2006-03-11 14:24 | windwolf      
@coolWarter
严重同意~
  回复  引用  查看    
#8楼 2006-03-13 17:48 | xiao_p      
对于覆写和多态也有些怀疑,还特意查了一下,今天又看了Allen Lee的http://www.cnblogs.com/allenlooplee/archive/2006/03/13/348760.html
之后,感觉明白了许多……
  回复  引用  查看    
#9楼 [楼主]2006-03-13 17:54 | Terrylee      
@xiao_p
嗯,Allen Lee的这篇文章对new解释得很清楚,我以前对于用new的这种方式不是很了解:)

今天看了Allen Lee的文章之后,感觉大有收获
  回复  引用  查看    
#10楼 2007-11-09 19:52 | mswwt      
看了好多您的文章,受益非浅,谢谢了




标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2006-03-21 18:50 编辑过
Google站内搜索

相关文章:

相关链接: