C# abstract
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
注:
一、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的更多相关文章
- abstract与interface之房祖名张默版
最近把java基础知识拿出来看看,看到abstract与interface的时候,觉得有点模糊,好像面试官也喜欢问这个问题.我在百度了查了好长时间,觉得讲算比较清楚的是那篇讲 Door,然后想要带个报 ...
- [Erlang 0111] Erlang Abstract Format , Part 2
上回书,我们说到飞天玉虎蒋伯芳来到蜈蚣岭,不是,重来,上回咱们说到可以在Erlang Shell里面手工构造,加载并调用一个模块.在那个demo里面,我把多个Form单独生成出来,最后放在一起做 ...
- [Erlang 0110] Erlang Abstract Format , Part 1
Erlang Abstract Format并不难懂,只是枯燥一点罢了,如果把Abstract Format的文档翻译出来,其实就是Erlang教科书中语法入门的部分. Erlang Abstract ...
- C#中Abstract和Virtual的区别
c# 中 Abstract和Virtual比较容易混淆,都与继承有关,并且涉及override的使用.下面讨论一下二者的区别: 一.Virtual方法(虚方法) virtual 关键字用于在基类中修饰 ...
- Java Abstract Class & Interface
一. 抽象类 1. 抽象类:包含了一个抽象方法的类就是抽象类 2. 抽象方法:声明而未被实现的方法,用关键字abstract声明 3. 抽象类被子类继承,子类(如果不是抽象类)必须重写(overrid ...
- java关键字extends(继承)、Supe(父类引用空间)、 This(方法调用者对象)、Instanceof(实例类型-判断对象是否属于某个类)、final(最终)、abstract(抽象) 、interface(接口)0
java 继承使用关键字extends 继承的作用:减少代码量,优化代码 继承的使用注意点: 1子类不能继承父类的私有变量 2.子类不能继承父类的构造方法 3.子类在调用自己的构造方法时 会默认调 ...
- abstract与interface的区别
abstract的用法: //通过abstract 关键字修饰的类叫抽象类. abstract class Animal { String name; String color; abstract p ...
- Delphi之静态方法,虚方法virtual,动态dynamic,抽象abstract,消息
Delphi之静态方法,虚方法virtual,动态dynamic,抽象abstract,消息 http://www.cnblogs.com/zhwx/archive/2012/08/28/266055 ...
- c#中abstract与virtua、overridel的用法
1.abstract 抽象方法 ,virtual 虚方法 ,override 重载函数 父类A.m() 子类B.m() abstract的方法父类可以不实现,让子类去重写(重写=overwrite ...
- 一张图看懂normal,static,sealed,abstract 的 区别
+-------------------------+---+--------+--------+--------+----------+ | Class Type | | normal | stat ...
随机推荐
- NDO to PNP( ndoutils to PNP4Nagios)
How to use this script The aim of this script is to import your ndo database directly into PNP4nagio ...
- nagios二次开发(六)---nagiosql原理及主要文件的介绍
nagiosql的入口文件:index.php,这也是所有php程序的入口文件.是由apache指定的. index.php 文件的开始引入了 require("functions/prep ...
- sharepoint webpart
SharePoint开发中,不仅仅是WebPart,我们都经常会使用的几个关键位置,如下: GAC: C:\Windows\assembly,也就是部署的位置: ISAPI位置,SharePoint ...
- 谈谈springMVC和Strut2的理解
关于struts2框架原理 执行流程 struts2框架的核心是一个过滤器,我们编写的action类都继承ActionSupport的接口(顶层是一个过滤器filter),用户发送请求,经过核心过滤器 ...
- mvc 项目下 webservice 程序无法运行
错误描述: 可以出现调用HelloWorld的界面 点击调用按钮报无法找到该资源 错误分析: 把webservice当成controller了. 解决: global中 添加 routes.Igno ...
- HTTP 错误 500.21 - Internal Server Error 处理程序“PageHandlerFactory-Integrated”
网站发布到IIS上,访问时出现错误 原因:在安装Framework v4.0之后,再启用IIS,导致Framework没有完全安装 解决:开始->所有程序->附件->右键点击“命令提 ...
- I/O流——字节流
流的概念 流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以使文件,内存,或是网络连接.类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流.这时候你就 ...
- C# DataGridView控件清空数据完美解决方法
C# DataGridView控件绑定数据后清空数据在清除DataGridview的数据时: 1.DataSource为NULL(DataGridView.DataSource= null;)这样会将 ...
- (转)java中静态代码块的用法 static用法详解
一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序来 ...
- linux批量复制或删除同命名规则的文件
如图所示,有多个不同后缀的文件,但他们的前缀都是"QC_TZ.impute." 此时想批量复制图中的文件的话,可以考虑用命令行 cp QC_TZ.impute.* /your/de ...