Abstract:

  1、用途:提供一个可供多个派生类共享的通用基类定义。

  2、抽象类也可以定义抽象方法,方法是将关键字 abstract 添加到方法的返回类型的前面(抽象方法没有实现,所以方法定义后面是分号,而不是常规的方法块),

     抽象类的派生类必须实现所有抽象方法。当抽象类从基类继承虚方法时,抽象类可以使用抽象方法重写该虚方法,

public class D
{
  public virtual void DoWork(int i)
  {
    // Original implementation.
  }
}
 
public abstract class E : D
{
  public abstract override void DoWork(int i);
}
 
public class F : E
{
  public override void DoWork(int i)
  {
    // New implementation.
  }
}
public abstract class Shape
{
private string name; public Shape(string s)
{
// calling the set accessor of the Id property.
Id = s;
} public string Id
{
get
{
return name;
} set
{
name = value;
}
} // Area is a read-only property - only a get accessor is needed:
public abstract double Area
{
get;
} public override string ToString()
{
return Id + " Area = " + string.Format("{0:F2}", Area);
}
}
public class Square : Shape
{
private int side; public Square(int side, string id)
: base(id)
{
this.side = side;
} public override double Area
{
get
{
// Given the side, return the area of a square:
return side * side;
}
}
} public class Circle : Shape
{
private int radius; public Circle(int radius, string id)
: base(id)
{
this.radius = radius;
} public override double Area
{
get
{
// Given the radius, return the area of a circle:
return radius * radius * System.Math.PI;
}
}
} public class Rectangle : Shape
{
private int width;
private int height; public Rectangle(int width, int height, string id)
: base(id)
{
this.width = width;
this.height = height;
} public override double Area
{
get
{
// Given the width and height, return the area of a rectangle:
return width * height;
}
}
}

class TestClass
{
static void Main()
{
Shape[] shapes =
{
new Square(, "Square #1"),
new Circle(, "Circle #1"),
new Rectangle( , , "Rectangle #1")
}; System.Console.WriteLine("Shapes Collection");
foreach (Shape s in shapes)
{
System.Console.WriteLine(s);
}
}
}
//输出:
//Shapes Collection
//Square #1 Area = 25.00
//Circle #1 Area = 28.27
//Rectangle #1 Area = 20.00

  注:

    1、C#中Abstract和Virtual

      一、Virtual方法(虚方法)

      virtual 关键字用于在基类中修饰方法。virtual的使用会有两种情况:

        情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法。那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法。

        情况2:在基类中定义了virtual方法,然后在派生类中使用override重写该方法。那么在对派生类实例的调用中,该虚方法使用的是派生重写的方法。

      二、Abstract方法(抽象方法)

      abstract关键字只能用在抽象类中修饰方法,并且没有具体的实现。抽象方法的实现必须在派生类中使用override关键字来实现。

    2、接口和抽象类:

       最本质的区别:抽象类是一个不完全的类,是对对象的抽象,而接口是一种行为规范。

       1、抽象类中可以有非抽象方法;

        但接口中只提供一些方法规约,不提供方法主体,方法不能用public abstract等修饰,无字段变量,无构造函数。且实现interface的类必须实现接口的各个方法。

      2、抽象类虽不能实例化(然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例),但可以有构造函数,抽象类的构造函数用来初始化抽象类的一些字段,而这一切都在抽象类的派生类实例化之前发生。不仅如此,抽线类的构造函数还有一种巧妙应用:就是在其内部实现子类必须执行的代码。

      

class Program
{
static void Main(string[] args)
{
Employee employee = new Employee();
Console.WriteLine(employee.ID);
Console.ReadKey();
}
}
public abstract class Base
{
private Guid _id;
public Base()
{
this._id = Guid.NewGuid();
}
public Guid ID
{
get { return this._id; }
}
}
public class Employee : Base
{ }

    3、一个类只能继承一个抽象类,但可以实现多个接口。

    4、当一个类继承了一个抽象类,它必须要重写父类抽象类中的抽象方法,如果不去重写父类抽象方法的实例,那么这个类也是抽象类(这个抽象子类,直到重写这个抽象方法的实例为止,才能摆脱抽象的命运)。

        实现接口也必须实现接口中的每个行为。

一个类可以同时继承多个“接口”,但只能继承一个“抽象类”

  

    

public class Square : Shape
{
  private int side;
 
  public Square(int side, string id)
    : base(id)
  {
    this.side = side;
  }
 
  public override double Area
  {
    get
    {
      // Given the side, return the area of a square:
      return side * side;
    }
  }
}
 
public class Circle : Shape
{
  private int radius;
 
  public Circle(int radius, string id)
    : base(id)
  {
    this.radius = radius;
  }
 
  public override double Area
  {
    get
    {
      // Given the radius, return the area of a circle:
      return radius * radius * System.Math.PI;
    }
  }
}
 
public class Rectangle : Shape
{
  private int width;
  private int height;
 
  public Rectangle(int width, int height, string id)
    : base(id)
  {
    this.width = width;
    this.height = height;
  }
 
  public override double Area
  {
    get
    {
      // Given the width and height, return the area of a rectangle:
      return width * height;
    }
  }
}
 
 
 

接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。

下面比较一下两者的语法区别:

1.抽象类可以有构造方法,接口中不能有构造方法。

2.抽象类中可以有普通成员变量,接口中没有普通成员变量

3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。

4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。

5. 抽象类中可以包含静态方法,接口中不能包含静态方法

6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。

7. 一个类可以实现多个接口,但只能继承一个抽象类。

下面接着再说说两者在应用上的区别:

接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。

而抽象类在代码实现方面发挥作用,可以实现代码的重用

C# abstract的更多相关文章

  1. abstract与interface之房祖名张默版

    最近把java基础知识拿出来看看,看到abstract与interface的时候,觉得有点模糊,好像面试官也喜欢问这个问题.我在百度了查了好长时间,觉得讲算比较清楚的是那篇讲 Door,然后想要带个报 ...

  2. [Erlang 0111] Erlang Abstract Format , Part 2

       上回书,我们说到飞天玉虎蒋伯芳来到蜈蚣岭,不是,重来,上回咱们说到可以在Erlang Shell里面手工构造,加载并调用一个模块.在那个demo里面,我把多个Form单独生成出来,最后放在一起做 ...

  3. [Erlang 0110] Erlang Abstract Format , Part 1

    Erlang Abstract Format并不难懂,只是枯燥一点罢了,如果把Abstract Format的文档翻译出来,其实就是Erlang教科书中语法入门的部分. Erlang Abstract ...

  4. C#中Abstract和Virtual的区别

    c# 中 Abstract和Virtual比较容易混淆,都与继承有关,并且涉及override的使用.下面讨论一下二者的区别: 一.Virtual方法(虚方法) virtual 关键字用于在基类中修饰 ...

  5. Java Abstract Class & Interface

    一. 抽象类 1. 抽象类:包含了一个抽象方法的类就是抽象类 2. 抽象方法:声明而未被实现的方法,用关键字abstract声明 3. 抽象类被子类继承,子类(如果不是抽象类)必须重写(overrid ...

  6. java关键字extends(继承)、Supe(父类引用空间)、 This(方法调用者对象)、Instanceof(实例类型-判断对象是否属于某个类)、final(最终)、abstract(抽象) 、interface(接口)0

    java 继承使用关键字extends   继承的作用:减少代码量,优化代码 继承的使用注意点: 1子类不能继承父类的私有变量 2.子类不能继承父类的构造方法 3.子类在调用自己的构造方法时 会默认调 ...

  7. abstract与interface的区别

    abstract的用法: //通过abstract 关键字修饰的类叫抽象类. abstract class Animal { String name; String color; abstract p ...

  8. Delphi之静态方法,虚方法virtual,动态dynamic,抽象abstract,消息

    Delphi之静态方法,虚方法virtual,动态dynamic,抽象abstract,消息 http://www.cnblogs.com/zhwx/archive/2012/08/28/266055 ...

  9. c#中abstract与virtua、overridel的用法

    1.abstract 抽象方法 ,virtual 虚方法 ,override 重载函数 父类A.m() 子类B.m()   abstract的方法父类可以不实现,让子类去重写(重写=overwrite ...

  10. 一张图看懂normal,static,sealed,abstract 的 区别

    +-------------------------+---+--------+--------+--------+----------+ | Class Type | | normal | stat ...

随机推荐

  1. Java入门记(三):初始化顺序

    初始化顺序的规则 1.在一个类的对象实例化时,成员变量首先初始化,然后才调用构造器,无论书写顺序.如果调用构造器前,没有显式初始化,那么会赋默认值. 这样做法的原因可以理解为:构造器执行时可能会用到一 ...

  2. Perl爬取铁路违章旅客信息

    #! /usr/bin/perl use strict; use Encode qw(encode decode); binmode(STDIN,":encoding(utf8)" ...

  3. 正则表达式提取string 中的表名

    简单版本: Regex reg = new Regex(@"(?i)\bfrom\b(?![^\[\]]*\])\s+(\[[^\[\]]+\]|\S+)"); MatchColl ...

  4. Highcharts 在低版本 IE 上使用注意事项

    来源:https://segmentfault.com/a/1190000004272693 很多人经常遇到图表在主流浏览器上运行正常,在低版本IE(包括IE6.IE7.IE8等)下运行出错(图表显示 ...

  5. PostgreSQL9.2安装和配置指南

    本文只介绍PostgreSQL9.2在centos上的安装和配置过程 1.执行yum 命令安装PostgreSQL yum install postgresql-server 2.初始化Postgre ...

  6. 国内npm镜像源推荐及使用

    NPM(Node Package Manager),是NodeJs的模块依赖管理工具.由于Npm源在国外,使用起来不方便, 故需要国内可靠的npm源可以使用,现整理如下: 一.国内镜像 1.淘宝NPM ...

  7. java 线性规划 和lingo 比较

    model:max=13*A+ 23*B; 5*A + 15*B <480 ; 4*A + 4 *B <160 ; 35* A + 20 *B <1190 ; end Variabl ...

  8. 汉化PLSQL怎么改变字体的大小及关键字颜色

    打开工具---首选项-----编辑器---语法高亮进行设置自己喜欢的颜色---应用--确定 英文版PLSQL:tools----preferences---userinterface项目下的edite ...

  9. UI设计趋势:渐变设计风格重新回归主流

    在扁平化设计刚刚兴起之时,渐变是设计师们避之不及的设计手法,然而今天它已经正式回归.几乎是在一夜之间,无数的网站开始使用渐变色. 从背景到图片上的色彩叠加,包括UI元素上所遮盖的色彩,所有的这一切都表 ...

  10. 利用Unity制作“表”

    一枚小菜鸟   目前没发现在Unity有其他路径制作类似于c# WinForm中的表:但是利用Unity自带的UGUI,制作了一张"伪表",具体方案如下: 效果图如下: 步骤: 1 ...