您的位置:首页 > 编程语言 > C#

覆盖与重载(override/overload) [C#]

2011-02-25 09:07 253 查看
1. 方法签名与方法的显式隐藏

    以下程序中,子类B与父类A存在签名相同的函数,将产生方法隐藏。由于没有显式使用new修饰符,编译时出现警告。

签名相同简单的讲是指忽略访问控制符、函数返回值、参数名后其它内容相同。

如:internal int Print(int x)

     public void Print(int y)

     protected float Print(int z)

    忽略访问控制符、返回值与参数名后都变成了Print(int),所以它们都是签名相同的函数。

      public int Print(int x, int y) 和 public int Print(int x) 属于不同签名的函数

      public int Print(int X) 和 public int Print(float x) 属于不同签名的函数

    当new关键字用作修饰符时,可以在派生类中隐藏基类的方法,也就说在派生类的方法是new关键字新定义出来的方法,而不是基类的方法。在不使用New关键字来隐藏基类方法也是可以的,编译器会出现一个警告,提示如果有意隐藏基类的方法,请使用New关键字修饰。

    这种方法不应该过多地使用,因为它破坏了类型之间良好的继承关系,容易造成理解和维护上的困难。


using
 System;



using
 System.Collections.Generic;



using
 System.Text;





namespace
 LearnCSharp







{



    
class
 A





    



{



        
internal
 
void
 Print(

int

 x)





        



{



            Console.WriteLine(
"
A: {0}
"
, x);



        }



    }





    
class
 B : A





    



{



        
//
当A中的Print()成员用public、protected、internal修饰,B从A继承了Print()方法时,会出现如下警告:



        
//
"LearnCSharp.B.Print()"隐藏了继承的成员"LearnCSharp.A.Print()",如果是有意隐藏,请使用关键字new



        
public
 
void
 Print(

int

 y)





        



{



            Console.WriteLine(
"
B: {0}
"
, y);



        }



    }





    
class
 P





    



{



         
public
 
static
 
void
 Main(
string
[] args)





         



{



             A a 
=
 
new
 A();



             a.Print(
3
);



             Console.ReadKey();





             B b 
=
 
new
 B();



             b.Print(
4
);



             Console.ReadKey();



         }

 



    }



  



}

输出:

A: 3

B: 4

用关键字new,"LearnCSharp.B.Print()"显式隐藏了继承的成员"LearnCSharp.A.Print()":


using
 System;



using
 System.Collections.Generic;



using
 System.Text;





namespace
 LearnCSharp







{



    
class
 A





    



{



        
internal
 
void
 Print(

int

 x)





        



{



            Console.WriteLine(
"
A: {0}
"
, x);



        }



    }





    
class
 B : A





    



{



        
public
 
new

 
void
 Print(

int

 y)





        



{



            Console.WriteLine(
"
B: {0}
"
, y);



        }



    }





    
class
 P





    



{



         
public
 
static
 
void
 Main(
string
[] args)





         



{



             A a 
=
 
new
 A();



             a.Print(
3
);



             Console.ReadKey();





             B b 
=
 
new
 B();



             b.Print(
4
);



             Console.ReadKey();



         }

 



    }



  



}

输出:

A: 3

B: 4

把基类中的Print()方法变成virtual方法后:


using
 System;



using
 System.Collections.Generic;



using
 System.Text;





namespace
 LearnCSharp







{



    
class
 A





    



{



        
internal
 
virtual

 
void
 Print(
int

 x)





        



{



            Console.WriteLine(
"
A: {0}
"
, x);



        }



    }





    
class
 B : A





    



{



        
//
警告:"LearnCSharp.B.Print()"将隐藏继承的成员"LearnCSharp.A.Print()"。若要使当前成员重写该实现,



        
//
请添加关键字override,否则添加关键字new。



        
public
 
void
 Print(

int

 y)





        



{



            Console.WriteLine(
"
B: {0}
"
, y);



        }



    }





    
class
 P





    



{



         
public
 
static
 
void
 Main(
string
[] args)





         



{



             A a 
=
 
new
 A();



             a.Print(
3
);



             Console.ReadKey();





             B b 
=
 
new
 B();



             b.Print(
4
);



             Console.ReadKey();



         }

 



    }



  



}

输出:

A: 3

B: 4

添加override关键字后:


using
 System;



using
 System.Collections.Generic;



using
 System.Text;





namespace
 LearnCSharp







{



    
class
 A





    



{



        
public
 
virtual
 

void
 Print(

int

 x)





        



{



            Console.WriteLine(
"
A: {0}
"
, x);



        }



    }





    
class
 B : A





    



{



        
public
 
override
 

void
 Print(

int

 y)





        



{



            Console.WriteLine(
"
B: {0}
"
, y);



        }



    }





    
class
 P





    



{



         
public
 
static
 
void
 Main(
string
[] args)





         



{



             A a 
=
 
new
 A();



             a.Print(
3
);



             Console.ReadKey();





             B b 
=
 
new
 B();



             b.Print(
4
);



             Console.ReadKey();



         }

 



    }



  



}

输出:

A: 3

B: 4

添加关键字abstract将类A变成抽象类
后,无法创建
抽象类或接口“LearnCSharp.A”的实例
。修改后为:


using
 System;



using
 System.Collections.Generic;



using
 System.Text;





namespace
 LearnCSharp







{



    
abstract
 

class
 A





    



{



        
public
 
virtual
 

void
 Print(

int

 x)





        



{



            Console.WriteLine(
"
A: {0}
"
, x);



        }



    }





    
class
 B : A





    



{



        
public
 
override
 

void
 Print(
int

 y)





        



{



            Console.WriteLine(
"
B: {0}
"
, y);



        }



    }





    
class
 P





    



{



         
public
 
static
 
void
 Main(
string
[] args)





         



{



             B b 
=
 
new
 B();



             b.Print(
4
);



             Console.ReadKey();



         }

 



    }



  



}

输出:

B: 4

以下程序展示了new和override的本质区别



using
 System;



using
 System.Collections.Generic;



using
 System.Text;





namespace
 LearnCSharp







{



    
abstract
 
class
 A





    



{



        
public
 
virtual
 
void
 Print()





        



{



            Console.WriteLine(
"
这是虚方法
"
);



        }



    }





    
class
 B1 : A





    



{



        
public
 
override
 
void
 Print()





        



{



            Console.WriteLine(
"
这是新的方法
"
);



        }



    }





    
class
 B2 : A





    



{



        
public
 
new
 
void
 Print()





        



{



            Console.WriteLine(
"
这是另一个新的方法
"
);



        }



    }





    
class
 P





    



{



         
public
 
static
 
void
 Main(
string
[] args)





         



{



             A a1 
=
 
new
 B1();



             A a2 
=
 
new
 B2();



             a1.Print();



             a2.Print();



             Console.ReadKey();



         }

 



    }



  



}

输出:

这是新的方法

这是虚方法

    总结:New关键字主要用来区别派生类和基类同名方法的选择问题,通过隐藏基类方法,达到使编译器调用正确的方法的目的。Override主要用来对基类的方法和虚方法进行重写。

2. 方法重载与重写(overload & override)


    override表示“重写”,用于继承一个基类的时候,基类当中虚拟成员的实现。一般语境里,如果
说这个method(方法)是被override来的,就是说在定义这个方法的类的父类中有一个与这个方法同名且参数类型列表相同的方法,在子类中,这个
方法被override了。在对这个子类的实例调用该方法时,编译器确切的知道调用的是这个子类的方法。override指它随时随地都只有一种含义。

    overload表示“重载”,用于同一类中同名方法但参数个数或类型不同的实现,也就是让方法有不同签名的版本。一般语境里overload是
对method(方法)而言的,可以指一个类中多个名字相同而参数类型列表不相同的方法,这个名字代表的方法就是被overload了的。编译器会根据参
数类型列表的不同来决定调用叫这个名字的很多方法中具体的哪一个。指同样的东西在不同的地方具有多种含义。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c# string 编译器 float