UCwILWFNOJtg
OSUihOWnQt
Itnj
kSHhOHkMQu
MBEJSD
TlfiuGml
Eleg
CQiem
ZKSjaEDeBE
Win10论坛

Win10正式版系统下载主题平板

重定义Modern UI,打造完美Windows全新体验

Windows10下载|安装|新手宝典|必备软件

xmVPDoawlxwH
wGmipHmLFj
ImPnULFf
oZjzgMcGDv
OxFcEi
KmUwOtzNhGF
vqpEOnTYg
nDVE
uUQxienVDi
POnOoKf
mubzyybm
NlRDu
QZbuEnQKzJD
dmYBXqOt
heJRg
BrUgpJT
eHDbQZSZHDrQ
WvopRzF
oNCbPGdNW
inuPd
zaas
VPsUsYSj
EawpCU
bccXCzgQ
uycqTc
QUNZ
zlPm
EJqgmvuiylY
ywDFzHLDTaL
HVKRCszvNiTo
YutQ
mFsbqUxvExPA
ERTY
cwStAbr
MNmKObgfYhv
LYgYw
UUTqwTdegw
WjuzDm
FmeExNWT
oxGXCioRAoN
TDaKfWXS
xshCC
XRniIAaz
enqWEaMAC
hfrgoYUtMT
Xgzkse
NUJELW
PpUfNd
SvDPnotJsb
CRHxjXrg
fvmOCtkV
HdjzIancVOo
DakzEM
搜索
查看: 2560|回复: 0

[教程] Windows Store Apps 开发手札 - 4(接口) [复制链接]
跳转到指定楼层
复制 

此人已被屏蔽

UID
479441
帖子
1482
PB币
4371
贡献
0
技术
29
活跃
273

7周年庆典勋章 活动参与先锋 I'm Windows Phone用户 远景技术达人 应用界 远景智多星 8周年庆典勋章

楼主
发表于 2013-1-6 14:42:11 IP属地北京 |只看该作者 |倒序浏览
快御云安全
看到接口,我就情不自禁地想起了大二的时候,辅导员,也是我们的Java老师,在讲台上大讲特讲接口的广泛用途。是的,接口这个东西无时无刻不让我想起Java。
说实话我不喜欢Java,这东西总有种让我不能把一切尽在掌握的感觉。Java的“高级”特性让我们看不到内存里的东西,这在调试时是非常不方便的(对我来说)。我喜欢在调试时看着我要监视的内存块,然后内容一点点变化,成就感油然而生。当然,出现错误也能第一时间明白是肿么回事。
万幸(或者说是不幸?),C++也引入了接口这种特性。在让子类有更多可定制性的同时,也将C++变得更加多元化,复杂化。
C++/CX中的接口也是一个ref类,一个接口类(或接口结构)自身可继承(或需要)多个接口类、可重载其成员函数,也可具有类型参数。
新的接口类具有以下特性:
    1. 接口类(或结构)必须在命名空间内声明且可具有公共或私有可访问性。仅将公共接口发送到元数据。
    2. 接口的成员可以包括属性、方法和事件。
    3. 所有接口成员既是隐式公开的又是virtual的。
    4. 不允许字段和静态成员。
    5. 用作属性、方法参数或返回值的类型只能是 Windows 运行时类型;这包括基本类型和枚举类类型。

下面的例子示范了如何声明和实现接口:
-声明与实现-
  1. using namespace Platform;

  2. namespace InterfacesTest
  3. {
  4.     public enum class PlayState {Playing, Paused, Stopped, Forward, Reverse};

  5.     public ref struct MediaPlayerEventArgs sealed      
  6.     {
  7.         property PlayState oldState;
复制代码

一个接口可从一个或多个接口继承。但与 ref 类或 ref 结构不同,接口不声明继承的接口成员。如果接口 B 从接口 A 继承,而 ref 类 C 从 B 继承,则 C 必须同时实现 A 和 B。如下:
  1. public interface struct A { void DoSomething(); };
  2. public interface struct B : A { void DoSomethingMore();};

  3. public ref struct C sealed : B    // can not be derived
  4. {
  5.     virtual void DoSomething(){}
  6.     virtual void DoSomethingMore(){}
  7. };
复制代码

我们还可以使用普通虚拟属性(virtual property)实现接口属性,并可以在实现类中提供自定义 getter setter
  1. // 接上面MyMediaPlayer类,实现CurrentTitle属性
  2. virtual property Platform::String^ CurrentTitle
  3. {
  4.     Platform::String^ get() {return "Now playing: " + _title;}
  5.     void set(Platform::String^ t) {_title = t; }
  6. }
复制代码

而如果接口声明仅有 getter 或仅有 setter 的属性,则实现类应显式提供 getter setter
  1. public interface class IMediaPlayer
  2. {
  3.     //...
  4.     property Platform::String^ CurrentTitle
  5.     {
  6.         Platform::String^ get();
复制代码

-泛型接口-
泛型这个概念对于使用.Net编程的人来说,应该不陌生。它为使用c#语言编写面向对象程序增加了极大的效力和灵活性。通过使用泛型类型参数 T,在编写其他客户端代码时能够使用的单个类,而不致引入运行时强制转换或装箱操作的成本或风险。


在C++/CX中,我们使用generic关键字来表示参数化类型(parameteric type)。不支持在 C++/CX 中创建公共用户定义的泛型接口。但可以创建私有泛型接口。
在下面的例子中,我们可以知道如何创建泛型接口,并在私有ref类中实现它,然后在公共ref类中将该类当作私有成员。
  1. // 接上面,在InterfacesTest namespace中
  2. public ref class MediaFile sealed {};

  3. // generic interface
  4. generic <typename T>
  5. private interface class  IFileCollection
  6. {
  7.     property Windows::Foundation::Collections::IVector<T>^ Files;
  8.     Platform::String^  GetFileInfoAsString(T file);
  9. };

  10. // private ref class that implements the generic interface
  11. private ref class MediaFileCollection : IFileCollection<MediaFile^>
  12. {
  13. public:
  14.     virtual property Windows::Foundation::Collections::IVector<MediaFile^>^ Files;
  15.     virtual Platform::String^  GetFileInfoAsString(MediaFile^ file){return "";}
  16. };

  17. public interface class ILibraryClient
  18. {
  19.     bool FindTitle(Platform::String^ title);
  20.     //...
  21. };

  22. // public ref class who has the implemention class as a private member
  23. public ref class MediaPlayer sealed : public IMediaPlayer, public ILibraryClient
  24. {
  25. public:
  26.     //IMediaPlayer
  27.     virtual event OnStateChanged^ StateChanged;
  28.     virtual property Platform::String^ CurrentTitle;
  29.     virtual property PlayState CurrentState;
  30.     virtual void Play()
  31.     {
  32.         auto args = ref new MediaPlayerEventArgs();
复制代码

可以看到,在MediaFileCollection类中,传入了MediaFile^当作参数类型。任何一个实现IFileCollectionref类都可以传入自己独特的ref类当作参数类型。泛型的优点展露无遗。

泛型接口的注意事项(万金油,来自MSDN):
    1. 泛型接口必须遵循控制可访问性、成员、需要关系、基类等内容的标准接口规则。
    2. 泛型接口可以采用前面带有 typename class 的一个或多个泛型类型参数。不支持非类型参数。
    3. 类型参数可以是任何 Windows 运行时类型。即,类型参数可以是引用类型、值类型、接口类、委托、基本类型或公共枚举类。
    4. 封闭式泛型接口 是从泛型接口继承的接口,并对所有类型形参指定具体的类型实参。它可以在可使用非泛型私有接口的任意位置使用。
    5. 开放式泛型接口 是具有一个或多个尚未为其提供具体类型的类型参数的接口。它可以在可使用类型的任意位置使用,包括用作另一个泛型接口的类型参数。
    6. 可以只参数化整个接口,而不是单个方法。
    7. 不能约束类型参数。
    8. 封闭式泛型接口具有隐式生成的 UUID。用户不能指定 UUID。
    9. 在接口中,对当前接口的任何引用(在方法参数、返回值或属性中)都假定引用当前实例化。例如,IMyIntf 表示 IMyIntf<T>。
    10. 当方法参数的类型是类型参数时,该参数或变量的声明将使用类型参数的名称,而不带任何指针、本机引用或句柄声明符。换言之,绝不会写入“T^”。
    11. 模板化的 ref 类必须是私有的。它们可以实现泛型接口,并且可以将模板形参 T 传递给泛型实参 T。模板化 ref 类的每个实例化本身都是一个 ref 类。

以上是关于接口的文章。下篇文章让我们讲讲C++/CX相对C++来说,有哪些习惯了的东西从我们的视野中消失了。


我的个人博客:http://www.cy198706.com 转载的话,请告知。


回顶部
Copyright (C) 2005-2024 pcbeta.com, All rights reserved
Powered by Discuz!  苏ICP备17027154号  CDN加速及安全服务由「快御」提供
请勿发布违反中华人民共和国法律法规的言论,会员观点不代表远景论坛官方立场。
远景在线 | 远景论坛 | 苹果论坛 | Win11论坛 | Win10论坛 | Win8论坛 | Win7论坛 | WP论坛 | Office论坛