下面是我做的测试:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections; namespace ClassDemo
{
class Program
{
static void Main(string[] args)
{
//BaseClass bc = new BaseClass();
//bc.sayHello(); //DerivedClass dc = new DerivedClass();
//dc.sayHello(); //BaseClass bc2 = new DerivedClass();
//bc2.sayHello(); //Test test = new Test();
//test.sayHello(); //BaseClass bc = new DerivedClass2();
//bc.sayHello(); //索引器
//IndexDemo id = new IndexDemo();
//id[0] = "chen";
//id[1] = "yu";
//id[2] = "ming";
//Console.WriteLine("{0}{1}{2}", id[0], id[1], id[2]); //抽象类和接口
//ITest it = new ITest(); //error:无法创建抽象类或接口的实例
//ATest at = new ATest(); //error:无法创建抽象类或接口的实例
Test t = new Test();
t.sayHello();
//t.X = 100;
//Console.WriteLine(t.X);
Test2 t2 = new Test2();
t2.sayHello();
Console.WriteLine(t2.add());
Console.WriteLine(t2.add2());
t2.x = ;
Console.WriteLine(t2.x);
} //嵌套类
private class Test //类里面定义类,这里的类是可以有修饰符的private
{
public void sayHello()
{
Console.WriteLine("ClassTest sayHello");
}
}
} //抽象类与接口
public interface ITest
{
//public int x; //error:接口不能包含字段
void sayHello(); //error:不能有如public、abstract的修饰符
//int add() { return 1 + 2; }//error:接口成员不能有定义
int X { get; set; }
} public class Test : ITest
{
private int _x;
public void sayHello()
{
Console.WriteLine("Test sayHello");
}
public int X { get { return _x; } set { _x = value; } }
} abstract class ATest
{
public int x;
public abstract void sayHello();
public int add() { return + ; }
public virtual int add2() { return + ; }
} class Test2 : ATest
{
public override void sayHello()//重写virtual、abstract必须通过override
{
Console.WriteLine("Test2 sayHello");
} public override int add2() { return + ; }
} public class BaseClass //命名空间中定义的元素无法显式声明为private、protected 或protected internal但可以是public
{
public BaseClass()
{
Console.WriteLine("BaseClass");
}
public BaseClass(string str)
{
Console.WriteLine("BaseClass " + str);
}
public virtual void sayHello()
{
Console.WriteLine("BaseClass sayHello");
}
} class DerivedClass : BaseClass
{
public DerivedClass()
{
Console.WriteLine("DerivedClass");
} public new void sayHello()//有意掩藏基类的方法 new
{
Console.WriteLine("DerivedClass sayHello");
} public void drawLine(params Point[] pt)
{ }
} class Point
{
private int _x;
public int X { get { return _x; } set { _x = value;} }
private int _y;
public int Y { get { return _y; } set { _y = value; } }
} //void sayHello()//error:命名空间并不直接包含诸如字段或方法之类的成员
//{
//} class DerivedClass2 : BaseClass
{
public override void sayHello()
{
Console.WriteLine("DerivedClass2 sayHello");
}
} class IndexDemo
{
protected ArrayList al = new ArrayList(); public object this[int index]
{
get
{
if (index > - && index < al.Count)
{
return al[index];
}
else
{
return null;
}
}
set
{
if (index > - && index < al.Count)
{
al[index] = value;
}
else if (index == al.Count)
{
al.Add(value);
}
else
{ }
}
}
}
}

  以上测试得出以下几个结论:

  1、抽象类与接口均不能实例化。

  2、接口不能包含字段。

  3、包含的方法只能有声明,不能定义,且不能有如public、abstract的修饰符。

  4、抽象类与一般的类的的区别是:它不能实例化。

  

  一、抽象类:
      抽象类是特殊的类,只是不能被实例化;除此以外,具有类的其他特性;重要的是抽象类可以包括抽象方法,这是普通类所不能的。抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖,如果不覆盖,则其派生类必须覆盖它们。

二、接口:
      接口是引用类型的,类似于类,和抽象类的相似之处有三点:
      1. 不能实例化;
      2. 包含未实现的方法声明;
      3. 派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员(不仅是方法包括其他成员);
      另外,接口有如下特性:
      接口除了可以包含方法之外,还可以包含属性、索引器、事件,而且这些成员都被定义为公有的。除此之外,不能包含任何其他的成员,例如:常量、域、构造函数、析构函数、静态成员。一个类可以直接继承多个接口,但只能直接继承一个类(包括抽象类)。

三、抽象类和接口的区别:
      1. 类是对对象的抽象,可以把抽象类理解为把类当作对象,抽象成的类叫做抽象类.而接口只是一个行为的规范或规定,微软的自定义接口总是后带able字段,证明其是表述一类类“我能做。。。”。抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中;
      2. 接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法;
      3. 一个类一次可以实现若干个接口,但是只能扩展一个父类;
      4. 接口可以用于支持回调,而继承并不具备这个特点;
      5. 抽象类不能被密封;
      6. 抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的;
      7.(接口)与非抽象类类似,抽象类也必须为在该类的基类列表中列出的接口的所有成员提供它自己的实现。但是,允许抽象类将接口方法映射到抽象方法上;
      8. 抽象类实现了oop中的一个原则,把可变的与不可变的分离。抽象类和接口就是定义为不可变的,而把可变的座位子类去实现;
      9. 好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染;
     10. 尽量避免使用继承来实现组建功能,而是使用黑箱复用,即对象组合。因为继承的层次增多,造成最直接的后果就是当你调用这个类群中某一类,就必须把他们全部加载到栈中!后果可想而知。(结合堆栈原理理解)。同时,有心的朋友可以留意到微软在构建一个类时,很多时候用到了对象组合的方法。比如 asp.net中,Page类,有Server Request等属性,但其实他们都是某个类的对象。使用Page类的这个对象来调用另外的类的方法和属性,这个是非常基本的一个设计原则;
     11.如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法。

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

C#中抽象类和接口的更多相关文章

  1. 转:二十一、详细解析Java中抽象类和接口的区别

    转:二十一.详细解析Java中抽象类和接口的区别 http://blog.csdn.net/liujun13579/article/details/7737670 在Java语言中, abstract ...

  2. C#中抽象类和接口的区别

    原文:C#中抽象类和接口的区别 大家在编程时都容易把抽象类和接口搞混,下面为大家从概念上讲解抽象类和接口的区别: 一.抽象类: 含有abstract修饰符的class即为抽象类,抽象类是特殊的类,只是 ...

  3. 关于JAVA中抽象类和接口的区别辨析

    今天主要整理一下新学习的有关于Java中抽象类和接口的相关知识和个人理解. 1 抽象类 用来描述事物的一般状态和行为,然后在其子类中去实现这些状态和行为.也就是说,抽象类中的方法,需要在子类中进行重写 ...

  4. java 8中抽象类与接口的异同

    1.java 8中抽象类与接口的异同 相同点: 1)都是抽象类型: 2)都可以有实现方法(以前接口不行): 3)都可以不需要实现类或者继承者去实现所有方法,(以前不行,现在接口中默认方法不需要实现者实 ...

  5. 谈谈php中抽象类和接口的区别

    php中抽象类和接口的区别 1) 概念 面向对象的三大概念:封装,继承,多态 把属性和方法封装起来就是类.        一个类的属性和方法被另外的类复制就是继承,PHP里面的任何类都可以被继承,被继 ...

  6. PHP中抽象类与接口的区别

    PHP中抽象类与接口的区别 抽象类abstract 概念 定义为抽象的类不能被实例化.任何一个类,如果有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的类. 继承一个抽象类的时候,子类必须定义 ...

  7. 浅谈我对C#中抽象类与接口的理解

    C#中的抽象类与接口有些相似,初学者很容易混淆,今天就让我来谈谈对二者的理解. 首先我们得明确二者的含义,分述如下: 如果一个类不与具体的事物相联系,而只是表达一种抽象的概念,仅仅是作为其派生类的一个 ...

  8. PHP中抽象类,接口定义

    这里先介绍接口,因为在我最近看的好几本php工具书中都没有提到抽象类. 本人也觉得,在理解了接口后抽象类也非常好理解. 例子代码随便写了一下.例子代码是很ok的,测试过了不会报错,懒得看代码的筒靴们看 ...

  9. 转载:详细解析Java中抽象类和接口的区别

    在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力.abstract class和int ...

  10. Java中抽象类和接口的区别

    转载自:http://dev.yesky.com/436/7581936.shtml 在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种 ...

随机推荐

  1. 64位Win7下编译hadoop 1.2.1问题解决

    0.报sed的错误.原因在于没有安装cygwin.安装cygwin的时候要选择sed 1.Cannot run program "autoreconf". 这个问题在网上看了很多解 ...

  2. “cv”: 具有该名称的命名空间不存在

    记得添加#include<highgui.h> 无法解析的外部符号 遇到这种问题一般都是由于缺少相应的库文件 右击项目,选择“属性”--“链接器”--“输入”--“附加依赖项” 根据错误中 ...

  3. HDU 4576 简单概率 + 滚动数组DP(大坑)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4576 坑大发了,居然加 % 也会超时: #include <cstdio> #includ ...

  4. ios 各种技术

    1.NSlog  发布后不打印 #ifdef DEBUG// 如果有DEBUG这个宏就编译下面一句代码 #define DDLog(...) NSLog(__VA_ARGS__) #else // 如 ...

  5. cocos2d/x 自带字体(label)

    CCLabelTTF* label1 = CCLabelTTF::labelWithString("1掼蛋as", "AppleGothic", 15); la ...

  6. Python培训12期-day2作业-购物车

    #!/usr/bin/env python import sys import os import getpass 商品={ '图书': { "<Puppet实战>": ...

  7. C++ 迭代器模式实现

    STL模板库中有大量迭代器实现,这些迭代器隔离了算法实现与访问接口,我们也可以编写属于自己的迭代器.STL中的迭代器均继承至一个通用迭代器接口: template <class _Categor ...

  8. SVG裁剪和平移的顺序

    SVG 里为元素添加 clip-path 属性即可做出裁剪效果,添加 transfrom 属性可以平移.旋转元素. 根据需求不同,有两种情况: 先裁剪元素,再把裁剪后的图形平移 先平移元素,再按区域裁 ...

  9. php建立MySQL数据表

    <?php $connect = mysql_connect("127.0.0.1","root",""); mysql_select ...

  10. 启动运行下载gradle速度太慢,手动添加

    启动运行下载gradle速度太慢,并且容易卡死(感谢群友ˋ狠ㄨ得意提供支持)---国内网络访问地址 我们经常运行项目的时候会需要进行下载gradle,不过由于网络或者和谐的问题经常下载需要花很长时间或 ...