基 础-----接口

 
定义接口的语法如下:
 
[attributes] [access-modifier] interface interface-name[:base-list]
{interface-body}
 
接口的目的是定义一些类所应具有的功能。
 
interface IStorable{
 void Read( );
 void Write( object obj );
 int Status { get; set; }
}
 
interface ICompressible
{
 void Compress( );
 void Decompress( );
}
 
继承自接口的类必须实现接口声明的所有方法和属性。
 
接口中的方法不需要加 访问修饰符(access-modifier) ,否则会产生编译错误。接口中的方法隐式的被声明为public,因为接口是一个由其他类所使用的契约(contract)。
 
不能创建接口的实例,只能创建实现了接口的类的实例。实现了接口的类的实例,可以转换为这一接口类型。
 
WARNING:实现接口的类中的方法不可以是静态的(static)。
实现多个接口
public class Document : IStorable, ICompressible
扩展接口
interface ILoggedCompressible : ICompressible
{
    void LogSavedBytes();
}
复合接口
interface IStorableCompressible : IStorable, ILoggedCompressible
{
     void LogOriginalSize();
}
将类的实例转换为接口类型
Public class Document:IStorableCompressible
{
 // implemention
}
 
Document doc = new Document();
IStorable isDoc = doc as IStorable;
IStorableCompressible iscDoc = doc as IStorableCompressible;
 
其中 IStorable isDoc = doc as IStorable也可直接写作 IStorable isDoc = doc
因为编译器知道Document类实现了IStorable接口,并会进行隐式转换。
 
如果不确定某个类是否实现了 IStrorable 接口,可以使用 as ,如果该类没有实现,将返回null。
 
IStrorable icDoc = someClassInstance as IStrorable;
if ( icDoc != null )
{
   icDoc.Read( );
}
else
   Console.WriteLine( "Read not supported" );
访问接口方法
以多态方式使用接口。
 
IStorable isDoc = new Document("Test Document");
icDoc.Read( );
将对象转换成接口类型
很多情况下,并不知道集合中的某个对象是否实现了接口。如果像下面这样使用接口:
 
Document doc = myCollection[0];
 
IStorable isDoc = (IStorable) doc;
isDoc.Read( );
 
ICompressible icDoc = (ICompressible) doc;
icDoc.Compress( );
 
而 Document的声明是这样的:
 
public class Document : IStorable
 
则将抛出异常。
使用 is 操作符
为了判断某个对象是否实现了特定接口,可以使用 is 操作符:
 
expression is type
 
如果 expression 可以转换成 type类型,则上面的表达式返回 true。
 
使用 is 的范例:
 
if (doc is IStorable)
{
 IStorable isDoc = (IStorable)doc;
 isDoc.Read( );
}
使用 as 操作符
也可以使用 as ,当某个对象不能转换为特定接口时,将返回 null。
 
expression as type
 
使用 as 的范例:
 
IStorable isDoc = doc as IStorable;
if (isDoc != null)
{
 isDoc.Read( );
}
 
在类型转换时使用 as 优于使用 is(原因略)
抽象类 vs 接口
很多情况下 抽象类 和 接口可以互相转换,而且区别甚微。
abstract class Storable
{
 abstract public void Read();
 abstract public void Write();
}
 
使用接口的理由:
l         可以继承多个接口,但只能继承一个抽象类
 
使用抽象类的理由:
l         抽象类可以更好的进行版本控制。如果日后修改一个抽象类,只需再往里添加一个虚拟方法,并提供一个默认实现。而对于一个接口,如果添加一个新方法,则只有两种可能:与此接口相关的所有类都必须改写,以实现这个新添加的方法;可以新起一个接口,并让这个接口继承自老接口,如此一来,你将会获得非常多的接口,很难管理。
覆盖接口实现的方法
一个实现了接口的类,可以将实现接口的任何或者全部方法设为虚拟的。这样,继承此类的其他类可以对这些方法进行覆盖。
 
using System;
using System.Collections.Generic;
using System.Text;
 
namespace overridingInterface {
 interface IStorable {
      void Read();
      void Write();
 }
 
 /* 实现IStorable 的简单Document
  * ***************************************/
 public class Document : IStorable {
 
      public Document(string s) {
          Console.WriteLine("Creating document with: {0}", s);
      }
 
      //虚拟方法
      public virtual void Read() {
          Console.WriteLine("Document Read Method for IStorable");
      }
 
      public void Write() {
          Console.WriteLine("Document Write Method for IStorable");
      }
 }
 
 /* 继承自Document 的类
  * ***************************************/
 public class Note : Document {
      public Note(string s): base(s) {
          Console.WriteLine("Creating note with: {0}", s);
      }
 
      // 覆盖Document中的虚拟方法
      public override void Read() {
          Console.WriteLine("Overriding the Read method for Note!");
      }
 
      // 实现一个Note的新Write方法
      public new void Write() {
          Console.WriteLine("Implementing the Write method for Note!");
      }
 }
 
 public class Tester {
 
      static void Main() {
          Document theDoc = new Document("** Doc");
          theDoc.Read();
          theDoc.Write();
 
          Console.WriteLine();
 
          IStorable isDoc = theDoc as IStorable;
          if (isDoc != null) {
             isDoc.Read();
              isDoc.Write();
          }
 
          Console.WriteLine("/n*************************************/n");
 
          Document theNote = new Note("** Fist Note");
          theNote.Read(); // 输出为覆盖了的Read() 方法
          theNote.Write();
         
          Console.WriteLine();
         
          IStorable isNote = theNote as IStorable;
          if (isNote != null) {
              isNote.Read(); //输出为覆盖了的Read() 方法
              isNote.Write();
          }
 
          Console.WriteLine("/n*************************************/n");
 
          Note note2 = new Note("** Second Note");
          note2.Read();
         note2.Write();// 输出为使用new 的,重新实现了的Write()方法
 
          Console.WriteLine();
 
          IStorable isNote2 = note2 as IStorable;
          if (isNote2 != null) {
              isNote2.Read();
              isNote2.Write();// 输出为Document 实现的的方法
          }
 
          Console.ReadKey();
      }
 }
}
 
输出为:
Creating document with: ** Doc
Document Read Method for IStorable
Document Write Method for IStorable
 
Document Read Method for IStorable
Document Write Method for IStorable
 
*************************************
 
Creating document with: ** Fist Note
Creating note with: ** Fist Note
Overriding the Read method for Note!
Document Write Method for IStorable
 
Overriding the Read method for Note!
Document Write Method for IStorable
 
*************************************
 
Creating document with: ** Second Note
Creating note with: ** Second Note
Overriding the Read method for Note!
Implementing the Write method for Note!
 
Overriding the Read method for Note!
Document Write Method for IStorable
显式实现接口方法
当一个类实现了两个接口(假设Document 类实现了IStorable和ITalk接口),但是两个接口中有方法名相同时,可以使用下面的语法来显式地实现一个接口:
 
void ITalk.Read()
 
显式实现接口的方法时,不可以加访问修饰符(access modifier),将隐式地声明为public。
 
不能通过类的实例来直接访问显式实现的方法。假设该类还实现了IStorable接口中的Read()的方法,当使用下面的语句时:
 
theDoc.Read( );
 
将会隐式调用IStorable的Read() 方法。
 
如果该类仅实现了ITalk接口,而没有实现IStorable接口,也就不存在方法名冲突的情况,但是却仍使用显示的接口声明,那么当使用 theDoc.Read() 时,将会出现编译错误。
 
'ExplicitImplementation.Document' does not contain a definition for 'Read' F:/MyApp/Test/ExplictImplament.cs 57 11 Test
 
当想使用 ITalk接口的方法时,需要进行一次类型转换,使用下面的语法:
 
ITalk itDoc = theDoc;
itDoc.Read();
成员隐藏
假设有如下两个接口:
 
interface IBase
{
   int P { get; set; }
}
 
interface IDerived : IBase
{
   new int P();
}
 
继承 IDerived的类至少需要进行一个显示实现。
 
class myClass : IDerived
{
   int IBase.P { get {...} }
  
   public int P( ) {...}
}
 
class myClass : IDerived
{
   public int P { get {...} }
  
   int IDerived.P( ) {...}
}
 
class myClass : IDerived
{
   int IBase.P { get {...} }
  
   int IDerived.P( ) {...}
}
实现接口的值类型(Struct)
如果使用值类型实现接口,则应通过值类型的对象访问接口方法,而不要转换成接口,再用接口进行访问,此时会多出一个“复制”了的引用对象,而原来的值对象依然存在,两个对象是各自独立的。
 
myStruct theStruct = new myStruct( );
theStruct.Status = 2;
 
IStorable isTemp = ( IStorable ) theStruct;
Console.WriteLine( "isTemp: {0}", isTemp.Status );
 
isTemp.Status = 4;
Console.WriteLine("theStruct:{0}, isTemp: {1}",theStruct.Status, isTemp.Status );
 
theStruct.Status = 6;
Console.WriteLine( "theStruct: {0}, isTemp: {1}",theStruct.Status, isTemp.Status );
 
输出为:
 
isTemp: 2
theStruct: 2, isTemp: 4
theStruct: 6, isTemp: 4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 JavaScript 编写的简单俄罗斯方块游戏(附源代码) 项目:使用 JavaScript 编写的简单俄罗斯方块游戏(附源代码) 该游戏是一个使用 HTML5 和 JavaScript 开发的简单项目。这款游戏允许玩家策略性地旋转下落的方块以清除关卡。要在此游戏中得分,您必须通过操纵方块来清除线条,使它们填满水平行。当方块掉落时,您必须 根据需要移动 和旋转它们,使它们均匀地排列在底部。 游戏制作 该游戏仅使用 HTML、CSS 和 JavaScript。谈到这款游戏的功能,这款游戏的 PC 控制也很简单。首先,您必须按空格键才能开始游戏。您可以使用箭头键来更改下落方块的位置。您可以在侧栏看到形成的分数和行。 该游戏包含大量的 javascript,用于对游戏的某些部分进行验证。 如何运行该项目? 要运行此游戏,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox, 以获得更好、更优化的游戏体验。要玩游戏,首先,单击 index.html 文件在浏览器中打开游戏。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值