前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MQL5从入门到精通【第六章】面向对象编程(二)

MQL5从入门到精通【第六章】面向对象编程(二)

作者头像
程序员小助手
发布2020-04-08 11:20:28
8140
发布2020-04-08 11:20:28
举报
文章被收录于专栏:程序员小助手

# 构造器

使用类实例化一个对象的时候,构造器会自动执行。构造器用于对象内部变量的初始化。

如果不显式声明构造器,系统会自动创建一个默认的构造器初始化变量。这个默认的构造器并不可见。

在上一章中声明的 CIndicator 类中,我们手动创建了构造器,名字依然是 CIndicator()。也就是说,我们的构造器必须与类名相同。

构造器无需指定返回类型。返回类型始终是void。且访问级别是public。

精简的CIndicator构造器如下:

代码语言:javascript
复制
class CIndicator
{
    public:
        CIndicator();
    // ...
};

下面例子中,我们显式声明构造器,作用仅仅是将main[]数组作为序列值存储。

代码语言:javascript
复制
CIndicator::CIndicator(void)
{
    ArraySetAsSeries(main,true);
}

请记住,不需要构造器,就无需创建,系统都为我们准备好了。

利用构造器,还可以做一些复杂的事情,比如参数化其他构造器,初始化众多列表。有了构造器,也就有对应的析构器。当对象销毁的时候调用。更多应用您可以在MQL5参考手册内阅读查看。

# 派生类 Derived Classes

面向对象还有一个非常有用的特性就是继承。面向兑现公众,我们可以使用一个类作为模板,创建另一个类。继承类会继承父类的所有方法与属性。(当然,private声明的属性和方法除外,不允许继承)。我们可以在继承类内添加方法,和属性。

我们举例说明这种继承关系和特性。

代码语言:javascript
复制
class CiMA : public CIndicator
{
    public:
        int Init(string pSymbol,ENUM_TIMEFRAMES pTimeframe, int pMAPeriod,
        int pMAShift,ENUM_MA_METHOD pMAMethod, ENUM_APPLIED_PRICE pMAPrice);
};

CiMA类继承了CIndicator类,并声明了新的方法,Init(), pMAShift()。

public方法声明此两个方法,是公开可访问,并可被继承的。

下面我们实现Init方法:

代码语言:javascript
复制
int CiMA::Init(string pSymbol, ENUM_TIMEFRAMES pTimeframe, int pMAPeriod,
int pMAShift, ENUM_MA_METHOD pMAMethod, ENUM_APPLIED_PRICE pMAPrice)
{
    handle = iMA(pSymbol,pTimeframe,pMAPeriod,pMAShift,pMAMethod,pMAPrice);
    return(handle);
}

Init方法所接收参数较多,注意参数的数据类型。方法返回值是int型。

# 虚拟方法 Virtual Functions

有时,我们需要在继承类中修改一个方法,或者想要在傅雷中定义方法,但是又担心影响到继承类的接口。这时,我们需要“虚拟方法”。

以Car为例。Class Car有一个方法,ChangGear()。然而,ShiftGear实现过程中,有手动方式和自动方式,实现方法完全不同。这时我们可以将ShiftGear()声明为虚拟方法。然后,实现的细节,在继承类内具体写。就很好地解决了这个问题。

举例说明:

代码语言:javascript
复制
class Car
{
    public:
        virtual int ShiftGears(int gear) { return(gear); }
};

一定记得,virtual关键字。

下面是具体的,在继承类中的ShiftGear()实现:

代码语言:javascript
复制
class ManualCar : public Car
{
    public:
        int ShiftGears(int gear);
};

大家看到了,重写ShiftGear方法,变得很简单。接收的参数和返回值,必须与父类相同,且方法名也完全一致。

如果继承类中有方法名与父类完全相同,那么父类的该方法会被覆盖。这种在集成类内重写父类方法的特性,称为“多态”!

还是拿上面的CiMA类举例。我们修改一下,将CIndicator的Init接口声明为虚拟类,并在继承类内实现。

代码语言:javascript
复制
class CIndicator
{
    protected:
        int handle;
    public:
        virtual int Init() { return(handle); }
};

那么,都不用修改CiMA,其已经可以使用Init方法。而如果是已写好的类,那么也不用变动,因为方法名相同,自动覆盖。

# 对象 Object

上面我们定义了一个移动平均值指示器CiMA。下面,我们创建一些该类的实例对象。

代码语言:javascript
复制
CiMA objMa;

执行实例化对象时,类的构造器自动执行。CiMA继承自CIndicator,那么CIndicator的构造器,也会被CiMA继承。objMa是CiMA的实例,实例化的时候自动执行CiMA->CIndicator->Constrator,就是这样一个过程。也就是下面这段:

代码语言:javascript
复制
CIndicator::CIndicator(void)
{
    ArraySetAsSeries(main,true);
}

对象一旦创建,我们就可以访问其公共成员。使用点(.)操作符。首先,我们调用该指示器的初始化方法:

代码语言:javascript
复制
objMa.Init(_Symbol, 0, MAPeriod, 0, MAMethod, MAPrice);

看上述代码,Init方法是在CiMA内实现,调用iMA方法返回移动平均值,并赋值给CiMA的保护变量handle。

我们还声明了一个保护属性main[],存储指示器数据。保护属性不可访问,使用公有方法Main()进行操作。

代码语言:javascript
复制
Print(objMa.Main())

如果有需要,我们在程序内还可以创建许许多多对象。只要实例化的时候,使用不同的名字就可以了。这种面相对象的方法,节省时间,避免了大量重复的代码,使程序看起来更为简洁有效,在处理大量复杂的交易任务时,非常有用。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员小助手 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • # 构造器
  • # 派生类 Derived Classes
  • # 虚拟方法 Virtual Functions
  • # 对象 Object
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档