C# abstract virtual interface的区别(付static、override用法)

1.Virtua:当一个方法被声明为Virtual时,它是一个虚拟方法,直到你使用ClassName variable = new ClassName();声明一个类的实例之前,它都不存在于真实的内存空间中。这个关键字在类的继承中非常常用,用来提供类方法的多态性支持。

virtual 关键字代表虚拟的,虚的,修饰的是方法。

修饰方法的时候:

这个时候叫做虚方法,虚方法代表这个方法是虚的,这个方法可能没有实现,这个方法可以被重写。

关键的一句话是:这个方法可以被重写。

这代表,如果这个方法想要被重写,被override,那么它就必须是一个虚方法,因为abstract修饰的方法是隐式的虚方法,所以abstract和virtual 修饰的方法可以被override。

付:

override 关键字代表重写,修饰的是方法。

override 方法提供从基类继承的成员的新实现。 由 override 声明重写的方法称为重写基方法。 重写的基方法必须与 override 方法具有相同的签名。

修饰方法的时候:

<1>:不能重写非虚方法或静态方法。 重写的基方法必须是 virtual、abstract 或 override 的。

override 方法和 virtual 方法必须具有相同的访问级别修饰符。

<2>:您不能使用 new、static 或 virtual 修饰符来修改 override 方法。

<3>:重写属性声明必须指定与继承属性完全相同的访问修饰符、类型和名称,并且被重写的属性必须

     是 virtual、abstract 或 override 的。

overrride:表示重写 这个类是继承于Shape类 
public override double Area 这个属性再shape中肯定存在 但是这里我们不想用shape中的 所以要重写  virtual,abstract是告诉其它想继承于他的类 你可以重写我的这个方法或属性,否则不允许。 一个生动的例子 :老爸表示基类(被继承的类) 儿子表示子类(继承的类)
老爸用virtual告诉儿子:"孩子,你要继承我的事业,在这块上面可以自己继续发展你自己的"
儿子用override告诉全世界:"这个我可不是直接拿我爸的,他只是指个路给我,是我自己奋斗出来的" 

 付:

new 关键字代表隐藏,修饰的是方法。

new 和override 的区别是,new 是隐藏父类方法,这就好比告诉别人,这个方法和父类的方法是两个不同的方法,只是他们的签名刚好相同罢了,override 则不同,override 告诉别人,以后用我的instance调用的就是我的方法,用父类的instance调用的就是父类的方法。

2.

首先abstract 代表的是抽象,abstract 可以修饰类和方法。

修饰类的时候:

这个时候叫做抽象类,抽象类有下列性质:

  • 抽象类不能实例化。

  • 抽象类可以包含抽象方法和抽象访问器,访问器实际上也是方法

  • 不能用 sealed修饰符修饰抽象类,因为这两个修饰符的含义是相反的。 采用 sealed 修饰符的类无法继承,而 abstract 修饰符要求对类进行继承。

  • 从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实际实现。

 

修饰方法的时候:

这个时候叫做抽象方法,性质如下:

  • 抽象方法是隐式的虚方法(用virtual 修饰方法的叫做虚方法)。

  • 只允许在抽象类中使用抽象方法声明,只要使用抽象方法,那么这个就是抽象类。

  • 因为抽象方法声明不提供实际的实现,所以没有方法体;方法声明只是以一个分号结束,并且在签名后没有大括号 ({ })。 例如:

    public abstract void MyMethod();
    

    实现由一个重写方法override 提供,此重写方法是非抽象类的一个成员。

  • 在抽象方法声明中使用 static 或 virtual 修饰符是错误的,因为抽象方法需要被重写,所以不能用static修饰,因为抽象方法是隐式的虚方法,所以不能用virtual修饰。

  • 除了在声明和调用语法上不同外,抽象属性的行为与抽象方法一样,属性本质上是方法

  • 在静态属性上使用 abstract 修饰符是错误的。

  • 在派生类中,通过包括使用 override 修饰符的属性声明,可以重写抽象的继承属

总结:

abstract

     修饰类名为抽象类,修饰方法为抽象方法。如果一个类为抽象类,则这个类智能是其他某个类的基类。抽象方法在抽象类中没有函数体。抽象类中的抽象方法是没有方法体的,继承其的子类必须实现抽象类的抽象方法。

     抽象类有如下特征:

  • 抽象类不能实例化
  • 抽象类的派生类必须实现所有抽象方法
  • 抽象类中的抽象方法是没有方法体的,继承其的子类必须实现抽象类的抽象方法

抽象方法:
  • 抽象方法是隐式的虚方法
  • 只允许在抽象类中使用抽象方法声明
  • 抽象方法在抽象类中没有方法体
  • 在抽象方法声明中,不能使用static或者virtual修饰符

abstract

抽象方法声明使用,是必须被派生类覆写的方法,抽象类就是用来被继承的;可以看成是没有实

现体的虚方法;如果类中包含抽象方法,那么类就必须定义为抽象类,不论是否还包含其他一般方法;抽

象类不能有实体的。

abstract:抽象方法声明使用,是必须被派生类覆写的方法,抽象类就是用来被继承的;可以看成是没有实现体的虚方法;如果类中包含抽象方法,那么类就必须定义为抽象类,不论是否还包含其他一般方法;抽象类不能有实体的。

3.interface用来声明接口
1.只提供一些方法规约,不提供方法主体. 如: public interface IPerson {
    void getName();//不包含方法主体 }
2.方法不能用public abstract等修饰,无字段变量,无构造函数。 3.方法可包含参数。 如 public interface IPerson {

3.方法可包含参数。 如

 public interface IPerson {

    void getAge(string s); }
一个例子(例1):

public interface IPerson {
   IPerson();              //错误 

string name;            //错误  

 public void getIDcard();//错误   

void getName();         //right   

void getAge(string s); //right

 }

实现interface的类
1.与继承类的格式一致,如 public class Chinese:IPerson{} 2.必须实现 interface 中的各个方法    例2,继承例1
public class Chinese:IPerson {
   public Chinese(){}                  //添加构造    public void getName(){}          //实现getName()    public void getAge(string s){} //实现getAge() }

实现interface的类
1.与继承类的格式一致,如 public class Chinese:IPerson{} 2.必须实现 interface 中的各个方法    例2,继承例1
public class Chinese:IPerson {
   public Chinese(){}                  //添加构造    public void getName(){}          //实现getName()    public void getAge(string s){} //实现getAge() }

abstract声明抽象类、抽象方法 1.抽象方法所在类必须为抽象类
2.抽象类不能直接实例化,必须由其派生类实现。
3.抽象方法不包含方法主体,必须由派生类以override方式实现此方法,这点跟interface中的方法类似







public abstract class Book {
public Book() {   }
public abstract void getPrice();      //抽象方法,不含主体 public virtual void getName()   //虚方法,可覆盖 {
      Console.WriteLine("this is a test:virtual getName()"); }
public virtual void getContent()   //虚方法,可覆盖 {
      Console.WriteLine("this is a test:virtual getContent()"); }
public void getDate()                           //一般方法,若在派生类中重写,须使用new关键字 {
      Console.WriteLine("this is a test: void getDate()");    } }
public class JavaBook:Book {
      public override void getPrice()   //实现抽象方法,必须实现       {
           Console.WriteLine("this is a test:JavaBook override abstract getPrice()");






      }
      public override void getName()   //覆盖原方法,不是必须的       {
           Console.WriteLine("this is a test:JavaBook override virtual getName()");       } }
测试如下: public class test {
   public test()    {
    JavaBook jbook=new JavaBook();
         jbook.getPrice();      //将调用JavaBook中getPrice()          jbook.getName();       //将调用JavaBook中getName()          jbook.getContent();    //将调用Book中getContent()          jbook.getDate();       //将调用Book中getDate()     }
   public static void Main()    {
       test t=new test();    } }
virtual标记方法为虚方法
1.可在派生类中以override覆盖此方法 2.不覆盖也可由对象调用






3.无此标记的方法(也无其他标记),重写时需用new隐藏原方法 abstract 与virtual : 方法重写时都使用 override 关键字 
接口定义以大写字母I开头。方法只定义其名称,在C#中,方法默认是公有方法;用public修饰方法是不允许的,否则会出现编译错误;接口可以从别的接口继承,如果是继承多个接口,则父接口列表用逗号间隔。  接口可以通过类来实现,当类的基列表同时包含基类和接口时,列表中首先出现的是基类;类必须要实现其抽象方法; 
接口使用:见代码(转) interface使用 
interface使用(实例一) using System; 
namespace Dage.Interface  { 
//打印机接口  public interface IPrint  { 
string returnPrintName();  }  } 
//--------------------------------------------  using System;  using Dage.Interface;  namespace Dage.Print  { 
//HP牌打印机类  public class HP: IPrint  { 
public string returnPrintName()  { 
return "这是HP牌打印机";  }  }  } 
//--------------------------------------------  using System;  namespace Dage.Print  { 
//Eps牌打印机类  public class Eps: IPrint  { 
public string returnPrintName() 







return "这是Eps牌打印机";  }  }  } 
//--------------------------------------------  using System;  using Dage.Interface;  namespace Dage  {  //打印类 
public class Printer  { 
public Printer()  {} 
public string PrintName(IPrint iPrint)  { 
return iPrint.returnPrintName();  }  }  } 
//--------------------------------------------  --WinFrom中调用代码: 
private void button1_Click(object sender, System.EventArgs e)  { 
Printer p= new Printer();  switch (this.comboBox1.Text)  {  case "HP": 
MessageBox.Show(p.PrintName(new HP()));  break;  case "Eps": 
MessageBox.Show(p.PrintName(new Eps()));  break;  default: 
MessageBox.Show("没有发现这个品牌!");  break;  }  }

关于abstract和Interface的区别比较难区分,因为两者主要是从语义上的区别:再具体说明如下:

1.

  四、抽象类和接口的使用:
      1. 如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单的方法来控制组件版本。
      2.如果创建的功能将在大范围的全异对象间使用,则使用接口。如果要设计小而简练的功能块,则使用接口。
      3.如果要设计大的功能单元,则使用抽象类.如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。   
      4.抽象类主要用于关系密切的对象;而接口适合为不相关的类提供通用功能。


 以下是我在网上看到的几个形象比喻,真的非常不错,呵呵:
1.飞机会飞,鸟会飞,他们都继承了同一个接口“飞”;但是F22属于飞机抽象类,鸽子属于鸟抽象类。(太精辟了。。)
2. 就像铁门木门都是门(抽象类),你想要个门我给不了(不能实例化),但我可以给你个具体的铁门或木门(多态);而且只能是门,你不能说它是窗(单继承);一个门可以有锁(接口)也可以有门铃(多实现)。 门(抽象类)定义了你是什么,接口(锁)规定了你能做什么(一个接口最好只能做一件事,你不能要求锁也能发出声音吧(接口污染))。

(注:这段话引自:http://www.cnblogs.com/yoyozhou/archive/2008/05/13/1195131.html   博客园的一位博主 收藏以便查看。)

2.一段通俗易懂的理解:

车都有轮子,能行进等公共功能,只是汽车和自行车具体的实现不同,这就是abstract
车和椅子都能座人,但两者不是同一种类型,这种能座人的相同的功能就是interface

是不是一瞬间明白了?

注:引http://bbs.csdn.net/topics/30391031  CSDN一问答帖子)

3.英文好的同学可以看看这段话(老外写的东西也是很清楚理解的)

There are technical differences between Abstract Classes and Interfaces, that being an Abstract Class can contain implementation of methods, fields, constructors, etc, while an Interface only contains method and property prototypes. A class can inherit multiple interfaces but only one class (abstract or otherwise).

However, in my opinion, the most important difference between Interfaces and Abstract Classes is the semantic difference.

An Interface defines what something can do (how it behaves), and an Abstract Class defines what something is.

Take for example IEnumerable, the semantic meaning behind this is that anything that implementsIEnumerable is enumable, it doesn't mean that it's an enumeration, but that it can behave like one.

Contrast that with the washing machine example, anything that inherits it is a type of washing machine. Anything that inherits it would be a type of washing machine, a top loader, or side loader, w/ever.

Instead, if you had an interface called IWashable, which could contain a method called Wash. You could have various things implement IWashable, be it a Person, an abstract washing machine class, etc, where the actual implementation does not matter, just you need to know that the behavior is that it can wash things.

tl;dr; Classes define what something is, Interfaces define what something can do.

(引用自: http://stackoverflow.com/questions/15178219/whats-the-difference-between-an-abstract-class-and-an-interface


另付:

static用法解释:

Static:当一个方法被声明为Static时,这个方法是一个静态方法,编译器会在编译时保留这个方法的实现。也就是说,这个方法属于类,但是不属于任何成员,不管这个类的实例是否存在,它们都会存在。就像入口函数Static void Main,因为它是静态函数,所以可以直接被调用。


自此,abstract virtual interface static override的问题应该就告一段落,感谢网上各位博主,集合各位的文章理解了很多,同时也希望来我这里找答案的各位朋友希望你我共同进步。

C#的static,interface,virtual,abstract,override的区别用法

 

C# 

是面向对象的程序设计语言,每一个函数都属于一个类。

 


Static:

当一个方法被声明为Static时,这个方法是一个静态方法,编译器会在编译时保留这个方法的实现。也就是说,这个方法属于类,但是不属于任何成员,

不管这个类的实例是否存在,它们都会存在。就像入口函数Static void Main,因为它是静态函数,所以可以直接被调用。

 

Virtua:当一个方法被声明为Virtual时,它是一个虚拟方法,直到你使用

ClassName variable = new 

ClassName();

声明一个类的实例之前,它都不存在于真实的内存空间中。这个关键字在类的继承中非常常用,用来提供类方法的多态性支持。

 

overrride:表示重写这个类是继承于Shape类public override double Area 这个属性再hape中肯定存在但是这里我们不想用shape中的所以要重写virtual,

abstract是告诉其它想继承于他的类你可以重写我的这个方法或属性,否则不允许。

 

一个生动的例子:

老爸表示基类(被继承的类)

儿子表示子类(继承的类)

老爸用virtual告诉儿子:"孩子,你要继承我的事业,在这块上面可以自己继续发展你自己的" 儿子用override告诉全世界:"这个我可不是直接拿我爸的,

他只是指个路给我,是我自己奋斗出来的" 


abstract:

抽象方法声明使用,是必须被派生类覆写的方法,抽象类就是用来被继承的;可以看成是没有实

现体的虚方法;如果类中包含抽象方法,那么类就必须定义为抽象类,不论是否还包含其他一般方法;抽

象类不能有实体的。

 

详解

----------------------------------------------

 

interface

用来声明接口

 

1.

只提供一些方法规约,不提供方法主体

public interface IPerson 

    

void getName();//

不包含方法主体

 

2.

方法不能用

public abstract

等修饰

,

无字段变量,无构造函数。

 

3.

方法可包含参数。

 

 

public interface IPerson 

{

 抽象方法必须在派生类中重写,这一点跟接口类似,虚方法不必。抽象方法不能声明方法实体 而虚方法可以 包含抽象方法的类不能实例化 ,而包含虚方法的类可以实例化!

void getAge(string s); 



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C# 中,virtualoverride 都是关键字,用于实现面向对象编程中的多态性。 首先,virtual 关键字用于定义一个虚拟方法,即可以被子类重写的方法。使用 virtual 关键字标记的方法可以在父类中被定义,但是在子类中也可以被重新实现。 例如: ``` public class Animal { public virtual void Speak() { Console.WriteLine("I am an animal."); } } public class Dog : Animal { public override void Speak() { Console.WriteLine("I am a dog."); } } ``` 在上面的代码中,Animal 类中的 Speak() 方法被标记为 virtual,因此它可以在 Dog 类中被重写。在 Dog 类中,我们使用 override 关键字来重写 Speak() 方法。 在运行时,如果我们创建一个 Dog 实例并调用 Speak() 方法,将输出“我是一只狗”。 ``` Dog myDog = new Dog(); myDog.Speak(); // 输出 "I am a dog." ``` 注意:只有 virtual 方法才能被重写。 另一方面,override 关键字用于在子类中重写父类中已经定义的虚拟方法。重写方法必须与基类中定义的虚拟方法具有相同的名称、返回类型和参数列表。 例如,在上面的代码中,Dog 类重写了 Animal 类中的 Speak() 方法,并使用 override 关键字来标记它。这意味着在 Dog 类中,Speak() 方法将覆盖 Animal 类中的 Speak() 方法。 总之,virtualoverride 关键字都是用于实现多态性的重要工具,它们可以帮助我们在面向对象编程中更好地管理代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值