アクセスランキング C# クラスと継承 - スポンサー広告挫折した人のためのC#講座

直列つなぎ。 -とある発達障害者の記録

知識と知識を繋ぐためのblog。 広汎性発達と診断されました。ぜんぜん役に立ってないけど。月収13万円(うち手取り11万)、家賃4万円で生活するひつじ人間。モウマンタイ。

  

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

 スポンサー広告

   

C# クラスと継承

ブログパーツ
  今回で第3回目です。
  そろそろ実践に入っていこうかなと思うけど面倒だったりして。
  この項の習得時間は30分です(かなり多分 @-ᴥ-@)


 コードと記述修正
    18.1/1

 前回の記事

  
 提供元:はてなブログカードのような美しい外部リンクをクリック一発で作成する方法
 


  さて、今回はクラスについて解説したいと思います。
 
  連載 C#入門 第3回 クラスとオブジェクト

 上位の検索では上記のような記事が多数ヒットする事でしょう。 自分はCUIベース(黒いコンソール画面が出るもの)のサンプルや説明に馴染めず、GUI系のサンプルの方が分かり易くて好きなのですが。
 しかしながら、CUIは実装の手間が掛からず(buttonやイベント登録の必要がない)、処理順を追っていくという観点ではとても分かり易いものです。CUIにも慣れておくといいと思います。


 むしろ、まずは実行してみて動作を自分なりに解釈し、それから説明を読む方が良いと思います。あまりにも冗長なので。



クラスとは

 
  Visual Studioを使用するときは、クラスはデフォルトで自動的に生成されています。
 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
}
}
         
   
 
 
public partial class Form1 : Form
アクセス修飾子
partial(部分クラス) class クラス名 : 継承するクラス名
 となっています。
 publicは、どこからでもアクセス出来るという事を示します。



 その内部
public Form1()
        {     }
 はコンストラクタと呼ばれるメソッドです。コンストラクタは初期化処理に用いられ、コードブロック内部のInitializeComponentメソッドを呼ぶことで、各種コントロールのメモリ確保・配置を行っています。 コンストラクタが実行されるのは、アプリの実行毎に一度限りです。
 ここでユーザー定義のイベントを登録する事もよく行われます。



 つまり、デフォルトではForm1クラスが生成されているという訳です。

 もちろん、ユーザーが独自に定義したクラスを作成する事もできます。



クラスを作成しよう 

 よくサンプルで用いられるのは学校のクラスですね。何年何組の○○さん ○○歳などとクラスを定義し、クラス内部のメンバー呼び出す方法です。

 ここでは、もう少し分かり易く直感的な例を挙げたいと思います。

Dobon.netですが・・・・
 長方形、多角形、楕円、円弧、扇形を描く 
 乱数を生成する


 上記サイトのコードを参考に
 
 pictureBox1をForm1上に配置してください。
 

  class ランダム多角形を生成するクラス
        {
            Random r;
            int ランダム数1;
            int ランダム数2;
            int ランダム数3;
            int ランダム数4;
            int ランダム数5;


 //今回はアクセス修飾子を付けました。付けない時はprivateになり、メソッドにアクセス出来ません。
            public void ランダム多角形生成(PictureBox pb)
            {             //PictureBox型をメソッド内に流す
                r = new Random();
                //0以上290未満の乱数を整数で返す
             ランダム数1 = r.Next(290);
                ランダム数2 = r.Next(290);
                ランダム数3 = r.Next(290);
                ランダム数4 = r.Next(290);
                ランダム数5 = r.Next(290);

                //描画先とするImageオブジェクトを作成する
                Bitmap canvas = new Bitmap(pb.Width, pb.Height);
                //ImageオブジェクトのGraphicsオブジェクトを作成する
                Graphics g = Graphics.FromImage(canvas);

                //直線で接続する点の配列を作成
                Point[] ps = {new Point(ランダム数1, ランダム数2),
                 new Point(ランダム数2, ランダム数3),
                 new Point(ランダム数3, ランダム数4),
                 new Point(ランダム数4, ランダム数5) };
                //多角形を描画する
                g.DrawPolygon(Pens.Black, ps);

                //リソースを解放する
                g.Dispose();

                //PictureBox1に表示する
                pb.Image = canvas;
           
            }
   //クラス呼び出し
        private void button1_Click(object sender, EventArgs e)
        {
            ランダム多角形を生成するクラス randam_rectangle = new ランダム多角形を生成するクラス();



            randam_rectangle.ランダム多角形生成(pictureBox1);

        }
 
 実行結果
  randam多角形実行結果
  


 自分好みのゲームっぽいサンプルになったと思います。
 ファイルを読み込んだり、リストビューを開いたりといったより実践的なアプリ開発も簡単に出来るようになりますよ。

 

 クラスの定義はこのように何ら難しいものではなく、自動的にForm1でやっている事をユーザー自らが手打ちで行っていくものです。


 クラス名を決める → メンバー変数を定義する → 具体的なメソッドを書いていく 
 という流れですね。


 今回のメソッド定義  public void ランダム多角形生成(PictureBox pb) では、アクセス修飾子 publicの指定により、他のクラスForm1から呼び出せるようにしています。


 アクセス修飾子を省略すると、自動的にprivateになります。実際にvisual Studioでアクセスできない事を確認してみてください。


 もちろん、Form1クラスにアプリ全ての処理を詰め込むなんて事も可能ですが、クラスを定義する事でより保守管理しやすいアプリ製作が可能です。
 
 ○○するクラス を定義して役割分担をするというイメージが近いでしょう。





既存のクラスを継承して拡張しよう

 先ほどのコードを継承して、機能を追加します。
    


   コードは動画のものより多少修正してあります。

       
        static Graphics g;
        static Bitmap canvas;
         //フィールド変数としてクラス間で共有

        class ランダム多角形を生成するクラス
        {
            Random r;
            int ランダム数1;
            int ランダム数2;
            int ランダム数3;
            int ランダム数4;
            int ランダム数5;

          
            //配列の戻り値を出すようにして、派生クラス側で利用できるようにしました。
            public Point[] ランダム多角形生成(PictureBox pb)
            {             //PictureBox型をメソッド内に流す
                r = new Random();
                //0以上290未満の乱数を整数で返す
                ランダム数1 = r.Next(290);
                ランダム数2 = r.Next(290);
                ランダム数3 = r.Next(290);
                ランダム数4 = r.Next(290);
                ランダム数5 = r.Next(290);

              
                //直線で接続する点の配列を作成
                Point[] ps = {new Point(ランダム数1, ランダム数2),
                 new Point(ランダム数2, ランダム数3),
                 new Point(ランダム数3, ランダム数4),
                 new Point(ランダム数4, ランダム数5) };


                //PictureBox1に表示する
                pb.Image = canvas;
                return ps;
            }
        }

        class ランダム多角形に色を塗るクラス : ランダム多角形を生成するクラス
        {
            public void 多角形塗りつぶし(PictureBox pb)
            {               
               canvas = new Bitmap(pb.Width, pb.Height);
g = Graphics.FromImage(canvas);
                //インスタンス化は派生クラス側で行う



                g.FillPolygon(Brushes.BlueViolet, ランダム多角形生成(pb));
                   //Point座標を戻り値として取得して渡す
        g.DrawPolygon(Pens.Red, ランダム多角形生成(pb));


                g.Dispose();
        //解放のタイミングによってはgがnullになってerrorを返してしまう
//入れないとスタックオーバーフロー例外。
            }

  private void button1_Click(object sender, EventArgs e)
{
   //クラス呼び出し

     var randam_rectangle = new ランダム多角形に色を塗るクラス();
  //varを付けると型名を自動的に割り当ててくれます(型推論)
 
randam_rectangle.多角形塗りつぶし(pictureBox1);

}

 
 ・・・・正直いってかなり実装に手間取ってしまいました。3時間ぐらい。
色々試しましたが、継承ではインスタンス※1までは渡せないようです。
 


※1 インスタンスについてはこちら オブジェクト、クラス、インスタンスの言葉の意味


 個人的にはかなり直感的になったのではないかと思います。 



 派生クラスのメソッド(多角形塗りつぶし)
      ↓
 基底クラスのメソッド(ランダム多角形生成)

 の順に実行されます。

 

 失敗しても記録を付けよう

 プログラミングは慣れないうちは失敗が付き物です。未だに慣れてないけど。
 
 この件では、インスタンスが渡せないからじゃあどうしようかって事で、フィールド変数を出したり、構造体を定義してみたり(複雑になりすぎた)、参照渡しをしてみたり、タプル(エラー吐いた)を使ってみたりしました。インスタンスは持ち越せないので、いずれも意味がなかったようです。
 
 インスタンスを戻り値として返すという事も出来るようです。
 
 それと、g = Graphics.FromImage(canvas);を実行してNullReferenceExceptionだったときに、どれがNullの変数なのか分からないという事がありました。

 
   デバッガ変数ウィンドウに表示される内容を変更する
 

 こういう事はしっかり記録に残した方が、同じ失敗を繰り返さずに済みます。 


  
 電球これもやってみよう!
  第13章 ボタンを継承してみる 
 このコードを実行するには、defaultのForm1.csとProgram.csを削除して、「新しい項目」からClass1.cssを作成 → コピペ入力すればOKです(削除しなくても出来る)。原理的にはこれまでの項の知識で十分出来ますが、Application.Run(mf);で明示的に指定してあげないと、Form1がそのまま開いてしまいます。
 


 お役に立てれば幸いです。
 ・・・日本語は分かり易いけどIMEの切り替えが面倒。

 この記事がお役に立ちましたら、どうか寄付をお願いします。
  

関連記事
スポンサーサイト

 挫折した人のためのC#講座

 C#

     

-   0   Comments

Leave a comment

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。