惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
Netflix TechBlog - Medium
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
NISL@THU
NISL@THU
MongoDB | Blog
MongoDB | Blog
Microsoft Security Blog
Microsoft Security Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
L
LangChain Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
CERT Recently Published Vulnerability Notes
aimingoo的专栏
aimingoo的专栏
B
Blog RSS Feed
WordPress大学
WordPress大学
Know Your Adversary
Know Your Adversary
The Register - Security
The Register - Security
Jina AI
Jina AI
Spread Privacy
Spread Privacy
Recent Commits to openclaw:main
Recent Commits to openclaw:main
T
The Blog of Author Tim Ferriss
GbyAI
GbyAI
J
Java Code Geeks
S
Securelist
Y
Y Combinator Blog
T
Threat Research - Cisco Blogs
酷 壳 – CoolShell
酷 壳 – CoolShell
Vercel News
Vercel News
W
WeLiveSecurity
Hugging Face - Blog
Hugging Face - Blog
小众软件
小众软件
Martin Fowler
Martin Fowler
TaoSecurity Blog
TaoSecurity Blog
S
Schneier on Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
D
DataBreaches.Net
L
LINUX DO - 热门话题
T
Tailwind CSS Blog
T
Tor Project blog
博客园 - 叶小钗
Blog — PlanetScale
Blog — PlanetScale
I
Intezer
V
V2EX
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
C
Cyber Attacks, Cyber Crime and Cyber Security
雷峰网
雷峰网
The GitHub Blog
The GitHub Blog
量子位
AI
AI
Cyberwarzone
Cyberwarzone
T
Troy Hunt's Blog
N
News | PayPal Newsroom
H
Help Net Security

博客园 - 阳春三月

工作态度两则 泛型小经验 【转载】看图测性格 【转载】乔海燕-外科医生的手术技巧 记念 33-101 使用 MyMeta 组件获取数据库结构 获取 SQL Server 2005 中的元数据 看博客园文章的一点感想 事件与委托有别, delegate 与 Delegate 相异 - 阳春三月 伟大的 PL/Sql Developer——数据库结构比较 新年礼物:推荐小工具 C#属性的实质还是方法 在 IE 中承载 Winform 应用程序 安装 VS2008 SP1 后需要给 TFS2008 装 SP1 更新下载程序集缓存 尼康 P5100 的几张片子 吃油饼的男人 Linq error: Sequence contains no elements TFS 问题两则
abstract、virtual、override 和 new
阳春三月 · 2008-12-31 · via 博客园 - 阳春三月

    abstract、virtual、override 和 new 是在类的继承关系中常用的四个修饰方法的关键字,在此略作总结。

1. 常用的中文名:abstract 抽象方法,virtual 虚方法,override 覆盖基类方法,new 隐藏基类方法,override 和 new 有时都叫重写基类方法。

2. 适用场合:abstract 和 virtual 用在基类(父类)中;override 和 new 用在派生类(子类)中。

3. 具体概念:

    abstract 抽象方法,是空方法,没有方法体,派生类必须以 override 实现此方法。

    virtual 虚方法,若希望或预料到基类的这个方法在将来的派生类中会被重写(override 或 new),则此方法必须被声明为 virtual。

    override 重写继承自基类的 virtural 方法,可以理解为拆掉老房子,在原址上建新房子,老房子再也找不到了(除非显式地用 base. 调用基类方法)。

    new 隐藏继承自基类的 virtual 方法,老房子还留着,在旁边盖个新房,想住新房住新房(作为派生类对象调用),想住老房住老房(作为基类对象调用)。

    当派生类中出现与基类同名的方法,而此方法前面未加 override 或 new 修饰符时,编译器会报警告,但不报错,真正执行时等同于加了 new。

4. abstract 和 virtual 的区别:abstract 方法还没实现,连累着基类也不能被实例化,除了作为一种规则或符号外没啥用;virtual 则比较好,派生类想重写就重写,不想重写就吃老子的。而且继承再好也是少用为妙,继承层次越少越好,派生类新扩展的功能越少越好,virtual 深合此意。

5. override 和 new 的区别:当派生类对象作为基类类型使用时,override 的执行派生类方法,new 的执行基类方法。如果作为派生类类型调用,则都是执行 override 或 new 之后的。

演示 override 和 new 区别的例子:


// Define the base class
class Car
{
   
public virtual void DescribeCar()
   {
       System.Console.WriteLine(
"Four wheels and an engine.");
   }
}
// Define the derived classes
class ConvertibleCar : Car
{
   
public new virtual void DescribeCar()
   {
       
base.DescribeCar();
       System.Console.WriteLine(
"A roof that opens up.");
   }
}
class Minivan : Car
{
   
public override void DescribeCar()
   {
       
base.DescribeCar();
       System.Console.WriteLine(
"Carries seven people.");
   }
}
public static void TestCars1()
{
   Car car1 
= new Car();
   car1.DescribeCar();
   System.Console.WriteLine(
"----------");

   ConvertibleCar car2 

= new ConvertibleCar();
   car2.DescribeCar();
   System.Console.WriteLine(
"----------");

   Minivan car3 

= new Minivan();
   car3.DescribeCar();

   System.Console.WriteLine("----------");

}

输出类似如下所示:

Four wheels and an engine.

----------

Four wheels and an engine.

A roof that opens up.

----------

Four wheels and an engine.

Carries seven people.

----------

但是,如果我们声明一个从 Car 基类派生的对象的数组。此数组能够存储 Car、ConvertibleCar 和 Minivan 对象,如下所示:


public static void TestCars2()
{
    Car[] cars 
= new Car[3];
    cars[
0= new Car();
    cars[
1= new ConvertibleCar();

    cars[2] = new Minivan();

}

然后用一个 foreach 循环来访问该数组中包含的每个 Car 对象,并调用 DescribeCar 方法,如下所示:


foreach (Car vehicle in cars)
{
  System.Console.WriteLine(
"Car object: " + vehicle.GetType());
  vehicle.DescribeCar();

  System.Console.WriteLine("----------");

}

此循环的输出如下所示:

Car object: YourApplication.Car

Four wheels and an engine.

----------

Car object: YourApplication.ConvertibleCar

Four wheels and an engine.

----------

Car object: YourApplication.Minivan

Four wheels and an engine.

Carries seven people.

----------

注意,ConvertibleCar 的说明可能与您的预期不同。由于使用了 new 关键字来定义此方法,所调用的不是派生类方法,而是基类方法。Minivan 对象正确地调用重写方法,并产生预期的结果。