パスワードを忘れた? アカウント作成
15056779 journal
日記

yumeの日記: C#学習 21 6

日記 by yume

スラドで誰かが「なんか作ってればそのうち覚える」と言ってくれたので、実際にConsole AdventureやMedousaGameを作っているわけだが、確かにプログラミングはできるようになってきたと思う。
しかし、実践・独学な過程で知識に致命的な抜けがあるのではないか。たとえば「これもっと早く知っておけばよかった!」っていうものがめちゃくちゃたくさんあるんじゃないか、と不安になってきた。
実際、enumやクラスの継承、メソッドのオーバーライド、変数のアクセサ(get; set;)とかは「やっていくうちに」必要性が理解できて活用できている。
しかし、ざっくりとしか理解できてないもの(interfaceやthrowやtry/catch/finallyとか)は全く活用できていない状態である。

これらの概念をちょっと学習しておこう。これから先、複数人でコードを書くということもありえなくはない、という感じなので、そういうときかっこいいコードがかけるとよい。なんて。

--

interface
インターフェイスとは何か:

Microsoft .NET曰く、
インターフェイスには、非抽象クラスまたは構造体で実装が必要な機能のグループに対する定義が含まれる。
>相変わらずわかりづらい。けど以前ほどではなく「ぼんやりとなんとなく」意味はわかる気がする。

ufcpp.net曰く、
interfaceとは、クラスが実装すべき規約を定めるもの。クラスの設計者とクラスの利用者との仲介を担う。
実際的には、publicな抽象メソッドだけを持つクラスのようなもの。

よーするに、インターフェイスとは:
・多重継承(複数の元から継承すること)できる抽象的な概念
・本来クラスは1つの対象からしか継承できないが、インターフェイスならたくさん継承できる
・インターフェイスには、必要なだけpublicなメソッドの名前を作っておく。
        ・すると、それを継承したクラスは絶対にそのメソッドを書かなきゃならない。
・インターフェイスを継承したクラスのインスタンスを、そのインターフェイス型として受け取ったりできる。

インターフェイスは何に使えるか:
qiita @t2kojima曰く、
・同じメソッドを絶対に含めるけど、中身の具体的な動作が違う複数の具象クラス(HogeA〜HogeC)にinterface IHogeを継承させる。
・具象クラスHogeA〜HogeCは静的クラスIHogeFactoryに生成させる(引数に応じてreturn HogeA〜HogeC など)
・メイン関数では、IHoge hoge = IHogeFactory.Create(hogeを呼び出す条件など)とする
>受け取る型はinterface
・hoge.メソッドで好きなことをしてく。HogeDとかを増やすとしても、HogeDクラスを作ってFactoryをいじるだけでいい。

……うーむ、これは、どっちかというとFactoryクラスが便利だなぁという話な気がするぞ。
実際、これがinterfaceでなくてベースとなる抽象クラスHogeBaseだとしても、一応話は成立する。
interfaceを使う利点としては、メソッドの実装を強制できる点、ということだろうか。
それに、interfaceの方が限定的な機能なのだから、それで事足りるなら当然interfaceを使うべき、ということ?
確かに抽象クラスを継承するよりはややこしくない(interfaceはメソッド実装を強制することしかしないので)。
それに、まだ使い所はピンとこないが、多重継承ができるという話もある。
使えそうなところがあったら、とにかく使ってみよう。

--

throw
Microsoft .NET曰く、
throwはプログラムの実行中に例外が発生したことを通知する。
>通知ってどこへ?

ufcpp.net曰く、
・throwは例外処理に使う。
・例えば負の値を入れちゃいけないのに入ってるときとかにif分岐であれこれすると面倒なので、そういうときSystem.Exception、またはそれから派生するクラスを投げる
>throw new System.Exception("例外だよ〜〜")とかでもいいわけか。

試しにメンバ変数でさっき作ったFactoryクラスにHoge(Syurui.D)を生成させて、Factory側にはDタイプのHogeを生成しようとした場合例外を投げるようにthrow new Exception("REIGAI!!!")ってやると、Unityのデバッグランする前にUnityのコンソールにそれが飛んできた。これはちょっとすごい。

--

try - catch

そんで、tryとcatchそれぞれのブロックを作ると、
try
{
        //やりたいこと
}
catch(Exceptionかその派生)
{
        //例外が飛んできたらここの処理が走る
}
というようなことができるらしい。
try catchを適切に使えば、「どこが正常動作で、どこが例外処理か」を読みやすくなるそうだ。

さしあたりUnityの場合、例外は種類によってはゲームが止まってくれるわけだけど、そうでない例外(たとえば経験値がマイナスになるとか?)は考えられる。
そういう例外が発生したときには、そのための特別な処理(経験値をレベルから逆算した正常な値に戻すとか)をしたいわけで、そうしないとレベルが50なのに経験値が0になったりして、次に経験値をえたらレベルが2になっちゃったりするかもしれない。
そういうやばい状況を未然に防ぐために例外を使うんだろう。

--

そういえばC#学習を始めたのはいつごろだったっけな。初めのC#学習日記は8月11日だった。
あれからだいたい5ヶ月は経ったことになるが、日記を少し追うと、当時の自分の知識の乏しさにびっくりする(今もひどいが)。これでよくゲーム作ろうとか思ってたなぁ。

  • by Anonymous Coward on 2021年01月06日 23時24分 (#3954258)

    クラスを覚えたての人だとガンガン継承してしまいがち
    継承が多段になると「結局どれが実行されてんのよ」となってしまい、見通しが悪くなる
    これを起こりにくくするためと言う側面があります
    c++とかだとクラスを複数継承できるので、更に複雑さアップ。枝状に別れたスーパークラスをたどっていくと同じクラスがあったりして同名のメンバ変数があるが、どっちのクラスの変数なのかなど、もうわやになってしまう

    そんなわけでクラスの継承は一個にしたい
    でも機能は複数持たせたい
    そこでクラスは一つだけ継承可、その他はインタフェイスで、って形になってます
    純粋仮想関数だけを持つクラスと本質的には一緒ですね
    # VB6以前では継承できるのはクラスのpublic関数だけ(インタフェイスとして利用できるだけ)、とかいうラジカルな仕様でだいぶブーブー言われてました

    例外処理はエラーハンドリングを楽にするためのもので、
    起きるはずがないようなエラーや滅多に起きないエラーが出たときに一括で無難なエラー処理をさせたりするためのものです
    関数呼び出しのたびに返り値をチェックしてエラーだったら更にエラーを返して終了
    とか言うコードを書かなくて済むのでかなり見通しが良くなります
    finallyは「必ずそこを通る」ので、リソースの開放に使います
    エラーリターン時など処理を途中でやめてreturnする時、必ずファイルを閉じなきゃいけない
    そんなときにfinallyで「ファイルが開いてたら閉じる」ようにしておくとファイルの閉じ忘れが無くなりお得です

    ここに返信
    • by Anonymous Coward

      強制したい機能を分割できること、ですかねぇ。
      オブジェクト解放時に破棄したいリソースを必ず破棄させる → IDisposable
      オブジェクト同士で比較できる → IComparable
      オブジェクトを文字列として表現できる → IFormattable
      抽象クラスの多重継承でも良いのですが、どうせ抽象メソッドだけになるのだし。

      抽象クラスはそれこそオブジェクトやクラスの抽象的表現として使いたい。

      • by Anonymous Coward

        インターフェースはインターフェースでしょ。USBとか車の給油口。
        それを実装しているものがなんのためのものかと何を受け取って何を返すのかを表現するもの。
        だから抽象的には同じだが具体的には違うことを…

        • by Anonymous Coward

          わざわざUSBインターフェースなんぞ使わんでもarduinoでいいんじゃね?って話でしょ。
          あるいはキーボードキットなんかの標準HIDデバイスキット。

  • by Anonymous Coward on 2021年01月07日 3時06分 (#3954322)

    我々が日本語の文章を不自由なく書ける理由は二つある。
    一つは、子供の頃から文章を繰り返し書いてきたから。二つ目は、他人が書いた文章(本)をたくさん読んで来たから。
    上手い文章をたくさん読んで、文章のバリエーションを体得できれば、自分の作文スキルも上達する。

    プログラミングも同じ。教科書ばっかり読むんじゃなくて
    たまには他人が書いたプログラムを読むと新しい学びがある(はず)。

    ここに返信
  • by Anonymous Coward on 2021年01月07日 8時05分 (#3954352)

    throwはgotoです(キッパリ

    ここに返信
typodupeerror

192.168.0.1は、私が使っている IPアドレスですので勝手に使わないでください --- ある通りすがり

読み込み中...