跳至内容

Encapsulation and Extensibility of Types

类型的封装和扩展性

面向对象编程是一种平衡的软件编写方法。数据和行为被紧密地结合在一起。这种封装创造了用户定义的数据类型,扩展了语言中的数据类型并与之交互。类型的扩展性为语言增加了用户定义的数据类型,这些类型同样易于使用,包括基本类型

例如,抽象数据类型,如字符串,是对理想、众所周知的行为类型的描述。

字符串用户知道,字符串操作,如连接或打印,具有特定的行为。连接和打印操作被称为方法。

某种抽象数据类型的实现可能有一些限制,例如,字符串的长度可以被限制。这些限制会影响所有对象的行为。同时,内部或私有的实现细节不会直接影响用户所见的对象。例如,字符串通常实现为数组,而该数组的内部基址及其名称对用户来说并不重要。

封装是在提供对用户定义类型的开放接口时隐藏实现细节的能力。在MQL4以及C++中,类和结构定义([class](../../data-types/structures-classes-and-interfaces/#class)和struct)用于封装,并结合使用private、protected和public访问关键字。

public关键字表示对其背后的成员访问是开放的,没有限制。如果没有这个关键字,类成员默认是锁定的。私有成员只能由其类的成员函数访问。

受保护的类函数不仅在其类中,还在其继承类中可供类函数使用。公共类函数可以在类声明范围内的任何函数中使用。保护功能使得可以隐藏部分类实现,从而防止数据结构的意外变化。访问限制或数据隐藏是面向对象编程的特点。

通常,类函数被设为受保护,并使用protected修饰符声明,值的读写是通过使用由public访问修饰符定义的特殊所谓set-and get方法来完成的。

示例:

class CPerson
  {
protected:
   string            m_name;                     // name
public:
   void              SetName(string n){m_name=n;}// sets name
   string            GetName(){return (m_name);} // returns name
  };

这种方法提供了几个优势。首先,通过函数名称我们可以理解它的功能——设置或获取类成员的值。其次,也许将来我们需要更改CPerson类中m_name变量的类型或其任何派生类中的类型。

在这种情况下,我们只需要改变NameSet()和GetName()函数的实现,而CPerson类的对象可以在程序中使用,无需任何代码更改,因为用户甚至不会知道m_name的数据类型已经改变。

示例:

struct Name
  {
   string            first_name;                 // name
   string            last_name;                  // last name
  };

class CPerson
  {
protected:
   Name              m_name;                     // name
public:
   void              SetName(string n);
   string            GetName(){return(m_name.first_name+" "+m_name.last_name);}
private:
   string            GetFirstName(string full_name);
   string            GetLastName(string full_name);
  };

void CPerson::SetName(string n)
  {
   m_name.first_name=GetFirstName(n);
   m_name.last_name=GetLastName(n);
  }

string CPerson::GetFirstName(string full_name)
  {
   int pos=StringFind(full_name," ");
   if(pos>0) StringSetCharacter(full_name,pos,0);
   return(full_name);
  }

string CPerson::GetLastName(string full_name)
  {
   string ret_string;
   int pos=StringFind(full_name," ");
   if(pos>0) ret_string=StringSubstr(full_name,pos+1);
   else      ret_string=full_name;
   return(ret_string);
  }

另请参阅

数据类型

最后更新于