下面是我做的测试:

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. python leetcode 日记--231. Power of Two

    题目: Given an integer, write a function to determine if it is a power of two. class Solution(object): ...

  2. Hadoop随笔(二):Hadoop V1到Hadoop V2的主要变化

    一.消失的概念与新鲜的名词 Hadoop V2相对于Hadoop V1的变化主要在于资源管理和任务调度,计算模型仍然保持map/reduce的模型.资源管理和任务调度的变化导致了工作流程的变化,一些概 ...

  3. MySQL字符集乱码

    学数据库,最让人丧气的就是字符集的问题了,一旦出问题,就会有砸电脑的冲动,特别是在修改很多次字符集后依然不成功的时候! 我用的数据库软件是MySQL 5.1.28.最初出问题的时候,是这样的: 情景一 ...

  4. Eclipse设置JSP页面的默认编码

    1.一般新建jsp页面是默认编码为ISO-8895-1编码.但是,实际应用中为避免编码问题带来的麻烦,我们一般需要设置默认编码为UTF-8. 2.设置 Eclipse->Window->P ...

  5. 关于在listView中优化的问题 更多方

    面试官 说 需要至少说出8种 (--) 1.convertView的复用,切忌每次getView()都新建.listView的核心原理就是重用view. 2.ViewHolder 减少findView ...

  6. angularjs 迭代器

    angularjs 迭代器可以使用管道字符(|)添加到表达式和指令中. 有以下五种转换数据的迭代器: (1)currency-格式化数字为货币格式. (2)filter-从数组中选择一个一个子集. ( ...

  7. substring,substr,和slice的区别详解。

    1.Substring(x,y) : 输出一个字符串,当其中只有一个参数时,会输出从x开始到结尾的String. 举例: var str="hello";        conso ...

  8. 【转载】张逸--ThoughtWorks(中国)程序员读书雷达

    原文地址:ThoughtWorks(中国)程序员读书雷达 软件业的特点是变化.若要提高软件开发的技能,就必须跟上技术发展的步伐.埋首醉心于项目开发与实战,固然能够锤炼自己的开发技巧,却难免受限于经验与 ...

  9. PAT (Basic Level) Practise:1012. 数字分类

    [题目链接] 给定一系列正整数,请按要求对数字进行分类,并输出以下5个数字: A1 = 能被5整除的数字中所有偶数的和: A2 = 将被5除后余1的数字按给出顺序进行交错求和,即计算n1-n2+n3- ...

  10. bootstrap-11

    下拉菜单(基本用法) 在使用Bootstrap框架的下拉菜单时,必须调用Bootstrap框架提供的bootstrap.js文件.当然,如果你使用的是未编译版本,在js文件夹下你能找到一个名为“dro ...