C#中抽象类和接口
下面是我做的测试:
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#中抽象类和接口的更多相关文章
- 转:二十一、详细解析Java中抽象类和接口的区别
转:二十一.详细解析Java中抽象类和接口的区别 http://blog.csdn.net/liujun13579/article/details/7737670 在Java语言中, abstract ...
- C#中抽象类和接口的区别
原文:C#中抽象类和接口的区别 大家在编程时都容易把抽象类和接口搞混,下面为大家从概念上讲解抽象类和接口的区别: 一.抽象类: 含有abstract修饰符的class即为抽象类,抽象类是特殊的类,只是 ...
- 关于JAVA中抽象类和接口的区别辨析
今天主要整理一下新学习的有关于Java中抽象类和接口的相关知识和个人理解. 1 抽象类 用来描述事物的一般状态和行为,然后在其子类中去实现这些状态和行为.也就是说,抽象类中的方法,需要在子类中进行重写 ...
- java 8中抽象类与接口的异同
1.java 8中抽象类与接口的异同 相同点: 1)都是抽象类型: 2)都可以有实现方法(以前接口不行): 3)都可以不需要实现类或者继承者去实现所有方法,(以前不行,现在接口中默认方法不需要实现者实 ...
- 谈谈php中抽象类和接口的区别
php中抽象类和接口的区别 1) 概念 面向对象的三大概念:封装,继承,多态 把属性和方法封装起来就是类. 一个类的属性和方法被另外的类复制就是继承,PHP里面的任何类都可以被继承,被继 ...
- PHP中抽象类与接口的区别
PHP中抽象类与接口的区别 抽象类abstract 概念 定义为抽象的类不能被实例化.任何一个类,如果有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的类. 继承一个抽象类的时候,子类必须定义 ...
- 浅谈我对C#中抽象类与接口的理解
C#中的抽象类与接口有些相似,初学者很容易混淆,今天就让我来谈谈对二者的理解. 首先我们得明确二者的含义,分述如下: 如果一个类不与具体的事物相联系,而只是表达一种抽象的概念,仅仅是作为其派生类的一个 ...
- PHP中抽象类,接口定义
这里先介绍接口,因为在我最近看的好几本php工具书中都没有提到抽象类. 本人也觉得,在理解了接口后抽象类也非常好理解. 例子代码随便写了一下.例子代码是很ok的,测试过了不会报错,懒得看代码的筒靴们看 ...
- 转载:详细解析Java中抽象类和接口的区别
在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力.abstract class和int ...
- Java中抽象类和接口的区别
转载自:http://dev.yesky.com/436/7581936.shtml 在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种 ...
随机推荐
- 如何在程序里模拟在cmd里用管理员权限运行一条指令
转自csdn的yangw150,zhao4zhong1 转自http://www.cnblogs.com/del/archive/2008/02/13/1068229.html http://blog ...
- HOW TO BE SINGLE 最后那段的摘录
我一直在思考我们不得不单身的时间这个时间我们需要擅长一个人独处但是有多少独处的状态是我们想要拥有的呢难道不是件很危险的事情吗当你适应状态并且如鱼得水的时候所以当你安定下来 你就会与某人擦肩而过吗 有些 ...
- 简单的线性分类——MATLAB,python3实现
看李政轩老师讲的Kernel,讲的非常好!前面有几道作业题,用MATLAB简单做了下,不知道对不对,错误之处还请指出. 题目是这样的. 一.MATLAB版本: clear; clc % 生成train ...
- MySQL 数据库实现远程连接
1,刚开始我使用的是Navicat for MySQL工具连接远程的mysql的数据库. 报错了.报错信息是 Error 1130: Host '192.168.1.80' is not allowe ...
- 使用POSIX正则库匹配一行中多个结果
正则匹配与正则表达式是什么东西我就不说了,在这里说下POSIX这个c语言正则库在对字符串进行正则匹配时取出多个结果的问题. 首先简单说明下POSIX正则库的几个函数和使用方法 第一个函数:int re ...
- tensorflow4
参考:tensorflow_manual_cn.pdf 一.图像的四维张量和参数的四维张量貌似不同: 二.流程回顾 1.数据准备 2.Page 63 三.状态可视化 四.保存检查点(保存参数) 五.评 ...
- Mongodb在NUMA机器上的优化
10gen在mongodb的部署指南上,提到了在NUMA机器上,mongodb可能会出现问题,参见:http://docs.mongodb.org/manual/administration/prod ...
- python数据结构与算法——图的广度优先和深度优先的算法
根据维基百科的伪代码实现: 广度优先BFS: 使用队列,集合 标记初始结点已被发现,放入队列 每次循环从队列弹出一个结点 将该节点的所有相连结点放入队列,并标记已被发现 通过队列,将迷宫路口所有的门打 ...
- web安全之sql注入联合查询
联合查询的条件: 有显示位.当然要有注入点!! 提前需要了解的函数: union可合并两个或多个select语句的结果集,前提是两个select必有相同列.且各列的数据类型也相同 distinct 去 ...
- 《Android深度探索》(卷1)HAL与驱动开发读后感
第1章:安卓系统移植与驱动开发概述 这一章主要概括的介绍了安卓驱动开发和系统移植的主要内容,对安卓与Linux驱动做了一个总体的介绍.通过对第一章的学习,使我对Linux驱动开发有了一个感性的认识.在 ...