学童のためのEOPです。

 

========================================================================================================================

このトピックでは、OOPの 使い方について、おおまかな例を挙げていきます。

初心者のプログラマーからの質問も歓迎します。本当にOOPを理解したい人。

"賢い人 "は、私が間違ったことをしていると思うなら、自分でスレッドを立ち上げて、そこでちゃんとやってください。誰もあなたを必要としていません。

また、OOPの必要性、無用性についての議論もここでは関係ない。

========================================================================================================================


1 座標平面上の点を使って何かをしているとします。

仮に10個しかないとします。

メモリに保存する方法はさまざまです。

こんな感じ。

double x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7, x8, y8, x9, y9, x10, y10;

あるいはこんな感じ。

double pointsX[10];
double pointsY[10];

あるいはこんな感じ。

double points[10][2];

でも、この方法の方がずっと便利なんです。

struct POINT
{
  double x;
  double y;
};

POINT points[10];

新しいデータ型は、平面上の点です。

私たちは、一点を独立した存在として扱っています。

例として、点間の距離を計算する関数を書いてみます。

POINT p1, p2;

double D = Distance( p1, p2 );

double Distance( const POINT& p1, const POINT& p2 )
{
  double dx = p1.x - p2.x;
  double dy = p1.y - p2.y;
  return sqrt( dx * dx + dy * dy );
}

このように、OOPはタスク言語でプログラミングする能力を与えてくれる。


私たちは続けます...

 

2.ポリモルフィズム

例えばこんなコードがあったとします。

int iA = 1;
int iB = 3;

double dA = 4.5;
double dB = 3.14;

string sA = "abcd";
string sB = "efgh";

int iC = iA + iB;

double dC = dA + dB;

string sC = sA + sB;

この3つの場合、プラス記号の背後には3種類の加算機能がある。

これをポリモーフィズムという。

OOPでは、この動作を他のデータにも拡張することができます。

例えば、行列のクラスがあります。ファイルmatrix.mqhに格納されています。

すると、こんなコードが書けるようになります。

#include <matrix.mqh>

matrix< double > mA( 2, 2 );
mA[0][0] = 1.0;
mA[0][1] = 2.0;
mA[1][0] = 3.0;
mA[1][1] = 4.0;

matrix< double > mB( 2, 2 );
mB[0][0] = 5.0;
mB[0][1] = 6.0;
mB[1][0] = 7.0;
mB[1][1] = 8.0;

matrix< double > mC = mA + mB;

ここでは、OOPによって、プログラムの異なる部分に責任を分担させることができます。

行列クラスを書くとき、私たちはそれがどのように使われるかを考えません。

しかし、いざ書いてデバッグしてみると、行列の足し算や掛け算のルールなど考えずに、いろいろな作業に使ってしまうのです。

と*をつけただけです。


続きはこちら ...

 

3.バーチャル機能

幾何学的図形を表すクラスをいくつか書いたとします。

これらはすべて1つの基本クラスShapeを継承しています。

class Shape
{
public:
  Shape();

  virtual void Draw() = 0;
};

class Circle : public Shape
{
public:
  Circle();

  virtual void Draw();
};

class Rectangle : public Shape
{
public:
  Rectangle();

  virtual void Draw();
};

class Star : public Shape
{
public:
  Star();

  virtual void Draw();
};

ベースクラスへのポインタの配列を宣言すれば、これらの形状をすべて1つの配列にまとめることができる。

Shape* shapes[10];

Init()関数で、この配列を埋めています。

void Init()
{
  for( int i = 0; i < 10; i++ )
  {
    switch( i % 3 ){
      case 0:
        shapes[i] = new Circle();
        break;
      case 1:
        shapes[i] = new Rectangle();
        break;
      case 2:
        shapes[i] = new Star();
        break;
    }
  }
}

OnPaint()関数は、すべての図形を表示する必要があるときに呼び出されます。

void OnPaint()
{
   for( int i = 0; i < 10; i++ )
   {
      shapes[i].Draw();
   }
}

すべての図形をループして、それぞれの図形に対してDraw()関数を呼び出します。

それぞれの図形に対して、その特定の図形を描く方法を知っている独自の関数を呼び出します。

これが仮想関数の本質です。

もちろん、最後に削除することも忘れないでください。

void OnDeinit()
{
  for( int i = 0; i < 10; i++ ){
    delete shapes[i];
  }
}


続けるには ...

 

いや、彼ら(小学生)には理解できないだろう。特にマトリックスみたいなのはダメですね。なぜ、このようなポリモーフィズムが必要なのか......」と言われるでしょう。ある種のポリモーフィズム?さらに言えば、エムクルスでは、少なくとも10種類のバリエーションがある場合にのみ、その効率性が明らかになるのです。は10種類以上。

おそらく、関数と変数を組み合わせることで、グローバル変数と それにまつわる混乱をなくすことから始めるべきでしょう。

 
Dmitry Fedoseev:

いや、彼ら(小学生)には理解できないだろう。特にマトリックスみたいなのはダメですね。なぜ、このようなポリモーフィズムが必要なのか......」と言われるでしょう。ある種のポリモーフィズム?さらに言えば、エムクルスでは、少なくとも10種類のバリエーションがある場合にのみ、その効率性が明らかになるのです。は10種類以上。

グローバル変数と それにまつわる混乱をなくすために、関数と変数を組み合わせることができるようにすることから始めるべきかもしれません。

だろう ))))

個人的には、このOOPが必要なのかどうか、まだ理解できていません。同じような作業をするのであれば話は別ですが)明らかな利点は見当たりません。そして、このトピックの簡単でわかりやすい紹介は、まだ見つかっていません(あまり探していなかったからかもしれませんが) )))))

 

4. カプセル化

ここでよく耳にするのが"なぜOOPで埋もれたクラスメンバを 作る必要があるのか?すべてをオープンにし、どこでもアクセスできるようにしたい。"

しかし、OOPはすべてのメンバーをクローズドにすることを強制しているわけではありません。何を隠して、何を隠さないかはプログラマーが決めることです。

そして通常、誤ってデータが破損する可能性を減らすために、隠さなければならないものを隠す。

例えば、ボタンがありますが、このボタンは任意の色を設定することができます。

class ColorButton
{
   color myColor;

public:
   ColorButton( color clr ) : myColor( clr ){}

   color GetColor() const
   {
      return myColor;
   }

   void SetColor( color clr )
   {
      myColor = clr;
      Update();
   }

   void Update();
};

変数myColorをオープンにして、簡単な代入でいつでもボタンの色を変更できるようにしたのです。

しかし、この変数を代入しても、すぐにボタンが再描画されるわけではありません。

そこで、変数myColorをprivateにします。そして、色を変えるには、SetColor()関数を呼び出します。

この関数は、変数の代入のほかに、ボタンが再描画されることをシステムに伝える。

この機能では、その他の必要なアクションを置くことができます。

GetColor()関数は、ボタンの色を取得するために使用されます。その呼び出しは、変数への直接参照よりも高くはない。

というのも、コンパイラが簡単に最適化できるからです。

 
Koldun Zloy:

4. カプセル化


この例では、スラングでいうところの、まさにヘテロとセトールということでよろしいでしょうか。

 
Roman:

この例では、スラングでいうところの、まさにheters and setorsということでよろしいでしょうか。

はい、その通りです。

 
エムクルスにはゲッターとセッターはありません。
 
Dmitry Fedoseev:
emcoolにはゲッターとセッターはありません。

これはMQLが決めることではなく、プログラマーが決めることです。彼が望めば、彼らはそうするだろう。

 
Ihor Herasko:

これはMQLが決めることではなく、プログラマーが決めることです。彼が望めば、彼らはそうするだろう。

それを決めるのは、プログラミング言語である。

理由: