ブルーノのC#プログラミング & unity勉強日記

プログラミング素人、ブルーノの自主勉強ノートです。他のプログラミングを勉強したい方の助けになれば幸いです。その他趣味の雑記もしていきたいです

インターフェースの継承

f:id:covory10101101276:20171020111147j:image

みなさんこんにちは🌚

サンシャイン池崎サンドウィッチマン、我が家、ロバートがお笑いではお気に入りのブルーノです。大体狂ったキャラのお笑いが好きなんですね😅

さて今回はインターフェースの継承についてです

 

インターフェースもクラスと同様に継承することができます。この場合、継承したインターフェースをクラスで用いた場合は継承元も全て実装しなければいけません。

f:id:covory10101101276:20171020201840p:plain

f:id:covory10101101276:20171020201902p:plain

f:id:covory10101101276:20171020201905p:plain

IBruno049インターフェイスとIBruno050インターフェイスでデータや合計、平均を実装することを約束させ、Bruno051クラスで実装しています。なおこの時(15行目)に継承元をIBruno050しか書いていませんが、ちゃんとIBruno049も継承されています。なお、この時IBruno049のメンバを実装しなければエラーになります。今回はここまでにしておきます。

 

最近はスマホの普及でアプリの幅もジャンルもたくさん増えてきてびっくりするような興味深いものもたくさん出ています。最近はそういったアプリの構成がどんな風になっているのか考えるのが楽しいです。まだ全然作り方はわかりませんが笑

インターフェースの実装について

f:id:covory10101101276:20171013093226j:image

みなさんこんにちは🌚

秋が来ているはずなのに雨続きでうまく紅葉を楽しめませんブルーノです😓まあ雨が滴る紅葉もキレイですけどね笑

さて今回からはインターフェースについてやって行こうと思います

インターフェースについて

インターフェースとは、前回やった抽象クラスに似ており、その特性をより拡張したものとも言えます。

インターフェースの宣言はinterfaceキーワードを使って行います。

interface インターフェース名

{

    抽象メンバ

    ....

}

抽象メンバとは、前回抽象クラスでやったように何も実装されていないメソッドプロパティインデクサのことを指します。

インターフェースをクラスに実装するには、クラスの継承のように「:」を使ってどのインターフェースを使うかを明示します。派生クラスにインターフェースを実行させたい場合は基本クラスを先に書きます

例)

・class クラス名 : インターフェース

・class 派生クラス名 : 基本クラス名, インターフェース

では実際にやってみます。

f:id:covory10101101276:20171013105840p:imagef:id:covory10101101276:20171013105844p:imagef:id:covory10101101276:20171013105845p:image

全てのメンバを実装し、検証してみました。14行目までのインターフェースで宣言しているのは

・仮装メソッド(show)

・仮想プロパティ(prop)

・仮想インデクサ

と言います。最後のインデクサは142857というある数字にいろんな一桁の整数をかけているのですがこれが面白くて、1~6までの数字をこの数にかけるとどれも「142857」という数字が繰り返しているのです。そして7をかけると999999になります8, 9もなんかそれっぽい数字になるという面白い数なのです🤣今回はここまでにしておきます。

 

プログラミングの中には様々な英単語がキーワードとして出て来ます。英語が得意だとプログラミングも学習しやすいと思います。じゃあ外国人は スラスラできるのかな?周りみんなTOEICやってるからやろうかな〜🤔🤔

 

 

クラスやメソッドの分割定義

f:id:covory10101101276:20171012224418j:plain

みなさんこんにちは🌚

YouTubeでSASUKEの動画を見つけてみてたら時間が経つのも忘れて見入ってしまいましたブルーノです😃昔はよくやってた気もしますが最近は全然見かけなくなりましたね。またやってくれればいいのにな〜。さて今回は分割定義についてです。

分割定義について

C#ではクラスやメソッドの頭にpartialキーワードをつけることで定義を分割することができます。例で表すとこんな感じです。

例)partialクラス

partial class Bruno

{

    int x;

}

partia class Bruno

{

    x = 7;

}

 

 

これでそれぞれの中括弧{ }の中には一つの要素しかありませんが2つ目のx = 7はちゃんと一つ目のint xに格納されています。

例)partialメソッド

partial class Bruno

{

    public static void Main()

    {

        Bruno b = new Bruno();

        b.Show();

    }

    partial void Show();

}

partial class Bruno

{

    partial void Show() {

    Console.WriteLine("いえーい");

    }

}

 

パーシャルメソッドも同様別の括弧内で定義することでそれ以外の括弧内で同様の要素を使用することができます。しかし注意しなければならないことがあり、partialメソッドの戻り値はvoidで、アクセス修飾子はprivate出なければなりません。また、パーシャルメソッドの宣言と定義はそのパーシャルクラス内でなければなりません。つまりパーシャルメソッドを使いたい場合は必然的にパーシャルメソッドも使うことになります。

このパーシャルクラスたちは、個人のみで使うプログラムの場合はあまり意味がありません。しかしプロジェクトによっては複数人、もしリリースするならカスタマーを含め大量の人が目にする場合があります。そんな時、あるクラスの中に追記できるようにしたいが既存のプログラムは残しておきたい、もしくは見た目が複雑で邪魔だという時に、見えないところでこのパーシャルクラスを作り実装しておくそうです。partialキーワードがついている場合は必ずしも全てがその括弧内に収まっているとは限らないのです。今回はここまでにしておきます。

 

最近インド映画の「きっとうまくいく」をみました。インド映画特有のノリとテンポの良さが詰め込まれていて観ていて元気が湧いてきました😋これぐらい前向きに毎日を生きていきたいです笑

abstract(抽象)クラス

f:id:covory10101101276:20171011083719j:plain

みなさんこんにちは🌚

朝は空気が澄んでいてとてもランニングしやすいです。起きるのは大変ですがちょっと早起きして外にくりだしてみると案外気持ちいいですよ笑

さて今回はのちにやるインターフェースというものに似ている抽象クラスについてまとめます。

抽象クラスについて

今までは基本クラスである程度設計図を作り、派生クラスで少し変更を加える形ばかりを取っていましたが、基本クラスでなんの具体的なデータも入れずとりあえずの雛形だけ作って、派生クラスでその実装を行いたい場合も出てきます。そんな時は基本クラス内でabstractキーワードを使うことで抽象メソッドを作ることができます。そして抽象メソッドを含むクラスを抽象クラスと言います。

抽象クラスと抽象メソッドの例)

abstract class クラス名

{

    abstract 返すデータ型 メソッド名(パラメータリスト);

}

ちなみに派生クラスではこの抽象メソッドの中身を全て実装する必要があります。

f:id:covory10101101276:20171012110800p:imagef:id:covory10101101276:20171012110804p:imagef:id:covory10101101276:20171012110807p:image

長い文を書いてしまいましたが、要点は3〜11行目で、設けた抽象クラスを実装し、3つの数の最大公約数を求めるクラスを作ってみました。だいぶ無駄が多いプログラムだと思うのでどなたかご指摘お願いいたします😅😅今回はここまでにしておきます

 

この先にやるインターフェースという概念にとても似ているこの抽象クラス。これらの違いについても明確にして行こうと思います🙂🙃

 

クラスの多層階層とコンストラクタの継承

f:id:covory10101101276:20171010222543j:plain

みなさんこんにちは🌚

FF15を振り返るとやっぱりグラフィックや音楽・演出などが素晴らしいです。モチーフとなったベネツィアの写真を見ると思ってたよりオルティシエでした笑

いつか死ぬ前に一度は訪れてみたいです 

 

さて今回はクラスの多層階層についてまとめていこうと思います。その名の通り多層に渡って継承をするのですがここまで継承をわかっている人ならなんとなくどんな感じになるか察しているんじゃないかなとも思います🙄

多層階層について

基本クラスから派生させた派生クラスを基本クラスとして、さらに派生させることもできます。

f:id:covory10101101276:20171011050907p:plain

f:id:covory10101101276:20171011050912p:plain

Bruno039クラスで各基本クラスと派生クラスのインスタンスを生成しています。最初のb1 = b2 の代入は予想通りshowクラスがオーバーライドされています。次のb1 = b3の代入はいきなり基本クラスに派生の派生であるBruno039クラスのインスタンスを代入していますが結果はみてわかるようにちゃんと間のBruno038クラスも継承されています。では次に、コンストラクタを景初した場合の処理についてまとめます。

 

コンストラクタの継承について

コンストラクタクラスと同じ名前を持つメソッドのことを指し、そのクラスの中で一番最初に実行され主にそのクラスの初期化に使われるものでしたね。このコンストラクタは先ほどのように継承されるとどうなるのでしょうか

f:id:covory10101101276:20171011055615p:plain

f:id:covory10101101276:20171011055619p:plain

継承されるたびにその派生クラスのコンストラクタが呼び出されていることが確認できますね。今回は少し短いですがここまでにします。

 

急に朝が寒くなったような気がします。もう半袖の人は全然見かけません。ゲーム製作に取り付ける日は来るのだろうか....

 

オーバーライドについて

f:id:covory10101101276:20171002221035j:plain

みなさんこんにちは🌚

講義が忙しすぎて試合とバイトとトリプルブッキングでつらたんのブルーノです。「天使にラブソングを」をみたのですが最高でしたね。洋画のノリは大好きです笑。シスター見習いのシスター・メアリー・ロバート役のWendy Makkenaがとても可愛いですね。

 

さて今回はオーバーライドという言葉についてです。とってもかっこいい響きで以前やったオーバーロードに通じるものがありますがオーバーロードとは別物です。

オーバーライドについて

前回やった継承は基本クラスのメソッドの内容に新たに加えるだけでなく、すでにある内容を書き換えることもできます。これにより、一つのメソッドから複数のバージョンのメソッドを作ることができます。これをオーバーライドと言います。ロックマンエグゼで例えるならバリアブルソードみたいなものです。一つの同じチップで様々なタイプの攻撃ができるようになるみたいなものです。さて、オーバーライドされる元のメソッドを仮想メソッド(virtual method)と言い、オーバーライドされた後のメソッドをオーバーライドメソッド(override method)と言います。オーバーライドメソッドを組む上では以下のような細かいルールがあります。

  • アクセス修飾子は同じでなければならない
  • シグニチャは同じでなければならない
  • 静的メソッドはオーバーライドできない

言われてみればまあそうかと思うかもしれませんが結構忘れやすいので注意しましょう。

さてオーバーライドの方法ですがいたって簡単で、基本クラスのメソッドにvirtualキーワードをつけておき、派生クラスで同じ名前のメソッドの前にoverrideキーワードをつけるだけです。

例)

class Base

{

    public virtual void Main()

    { ... }

}

class Derived : Base

{

     public override void Main()

    { ... }

}

 

今までやってきたノリならば簡単ですね。しかしここで一つの疑問が浮かびます。前回やった「名前の隠蔽」です。同じ名前にすれば基本クラスのメソッドは無視されるというこのルールがある上でオーバーライドとの違いはなんなのでしょうか。ここからが少し理解が難しいところです。

下の画像をみてください

f:id:covory10101101276:20171007051525p:plain

f:id:covory10101101276:20171007051532p:plain

f:id:covory10101101276:20171007051538p:plain

名前の隠蔽を使ったTaroクラスとオーバーライドを使ったMateクラスで検証を行いました。検証の順番が少々ごっちゃですが許してください😂

1つ目の画像がそれぞれの継承について、2つ目が様々な方法で定義した各クラスの継承、3つ目がその結果についてです。主に2つ目の画像をみていただきたいのですがまずp1とp2インスタンスは名前の隠蔽を用いて普通に通常の方法で継承しているので、結果は予想通りです。注目すべきは3つ目と5つ目で、右辺で宣言した変数の型と左辺で生成したインスタンスの参照の型が違っています。結果はどうでしょうか。名前の隠蔽のPersonクラスの方は基本クラスのままの文章を返すのに対し、オーバーライドしたPeopleクラスは継承されたmateクラスの文章を返しています。これはつまり、名前の隠蔽による継承は「コンパイル時に参照する変数の値に応じてメソッドが決定される」のに対し、オーバーライドは「実行時に生成されたオブジェクトの型によりメソッドが決定される」ことを表しています。前者は動かない入れ物である変数により決定するので静的な型によるものとされ、後者は実行時に決定されるため動的メソッドディスパッチと呼ばれます。

”箱”である参照変数ではなく生成したオブジェクトの型通りにメソッドが動くのはオブジェクトの特徴によって振る舞いが決定するということであり、これがオブジェクト指向プログラミングの重要な要素の一つ「多態性」というものです。いちいち変数でなく自分が定義したメソッド通りに実行されて欲しいのは当然で、こういった時のためにオーバーライドは便利です。

プロパティやインデクサのオーバーロード

メソッドだけでなく、プロパティやインデクサもオーバーライドすることができます。

例)

・プロパティ

class Base

{

    public virtual string Prop

    { get, set; }

}

class Derived : Base

{

    public override string Prop    

    { get, set; }

}

 

・インデクサ

class Base

{

    public virtual string this[string index]

    { get, set; }

}

class Derived : Base

{

    public virtual string this[string index]

    { get, set; }

}

具体的にプログラムを組むとこんな感じです

プロパティ

f:id:covory10101101276:20171010110814p:imagef:id:covory10101101276:20171010110819p:imagef:id:covory10101101276:20171010110822p:image

無属性のロングソードのデータを入れたBruno029クラスから派生させたBruno030クラス(火属性)とBruno031クラス(氷属性)をそれぞれオーバーライドさせています。なおどちらの属性のソードもソード系統であるのは変わらないのでKeitouクラスはconstキーワードで変更できないようにしています。ロックマンエグゼでは各属性ソードチップにはお世話になりました

 

インデクサ

f:id:covory10101101276:20171010180512p:imagef:id:covory10101101276:20171010180515p:imagef:id:covory10101101276:20171010180521p:imagef:id:covory10101101276:20171010180523p:image

オーバーライドさせたインデクサの方は偶数個めのインデクサにのみ入れることができるので奇数は弾かれます。今回はここまでにしておきます

 

オーバーライドを使うことですでにあるクラスを様々なタイプに使い分けることができ、とても便利になります。ずいぶん時間がかかりましたがこの記事をまとめている間とても有意義で楽しかったです。

 

 

継承の基本、下準備について

みなさんこんにちは🌚

欲しいPS4ソフトが多過ぎて後期の単位が不安なブルーノです。ようやくPS4の時代がきました。金がなくなってゆく....

 

さて今回は継承の基本についてやっていきたいと思います。

継承について

C#の非常に重要な概念であるクラスの中でもとても重要な要素である継承。その名の通りその性質を引き継ぐことができる機能のことです。どういうことか、まずは下の画像を見てみましょう

f:id:covory10101101276:20170925120643p:plain

f:id:covory10101101276:20170925120649p:plain

まず、3行めから10行めはBruno026クラスですがこれは基本クラス(Base Class)と言います。そしてすぐ下の12から19行めのBruno027クラスの名前の横に「 : Bruno026」とありますがこれはBruno026から派生したということを表し、このBruno027クラスを派生クラス(Derived Class)と言います。そしてBruno028クラスではこれらのクラスをインスタンス化し色々と実験しています。まず25行めで派生クラスであるBruno027クラスをインスタンス化していますが、26,28行めでわかるように基本クラスであるBruno026クラスの中身を用いています。つまり、派生クラスは基本クラスのpublicなメンバを全て引き継ぐことができるのです。privateなクラスは呼び出せないので注意してください。そしてもう一つ注意するのが30,31,32行めでわかるように基本クラスはたとえその前に派生クラスが作られてもなくなったり、変わったりするわけではないということです。

先ほど派生クラスはprivateを引き継げないと言いましたが、では基本クラスの引き継ぐ要素はすべてpublicにすればいいのかというとそれも少し問題があり、publicメンバはその他のクラスからも影響を受ける場合があるのです。この場合は、protectedアクセス修飾子を使います。protected修飾子を頭につけたメンバは、派生クラスからはアクセスできますが、他のクラスからはアクセスできなくなります。なので、メンバを安全にしつつ、派生クラスを作りたい場合はこのprotected修飾子を使いましょう。

では最後に名前の隠蔽について説明しておきます。またかっこいい名前の用語が出てきました。基本クラスと派生クラスに同じ名前のメンバを持たせたい時、派生クラスの方のメンバにnewキーワードをつけることで、同じ名前のメンバを持つことができます。このメンバを呼び出した時、基本クラスのメンバは無視されます。これを名前の隠蔽と言います。逆に無視された基本メンバを呼び出したい時は、baseキーワードをつけて呼び出します

では今回の大まかなまとめをします。今回の結果をまとめると

  • クラスの横に「 : 」をつけることでその基本クラスの要素を引き継いだ派生クラスを持つことができる
  • 派生クラスを作っても基本クラスはなくならない
  • private修飾子を用いると派生クラスからも見えなくなるので派生クラスから見えつつ他のクラスからは見えないようにしたい場合はprotected修飾子を使う
  • newキーワードを頭につけることで基本クラスのと同じ名前のメンバを持つことができる。その場合基本クラスの同じ名前のメンバは隠蔽され、それを呼び出したい時はbaseキーワードを使う

この4つですね。次回からは、もっと別の要素についてもまとめていきたいと思います。ここから少しずつ複雑になっていくので、ゆっくり噛み締めながら勉強していきたいです。

 

来年あたりは新しいPS4のゲームがたくさん出るようでとても楽しみです!!でも最近のソニーのゲームはみんなで一緒にいてわいわいできるものが全然ない気がします( ´Д`)y━・~~

オンラインで化け物みたいな数同時通信できるものが増えるのは嬉しいですがやっぱり一緒にやりたいです笑