そ(ry
はい、おはようございます。僕です。普段は数ヶ月スパンぐらいでやっている続き物のパート3をやっていきます。
前回記事
inujini.hatenablog.com
誰もこんな記事読んでないだろうとおごりがでているのでタイトルがどんどん省略されていく。次回はタイトルすらつかないかもしれない 。まあいいややっていきましょう。
メンバ隠ぺい
実を言うと隠ぺいと次に出てくるオーバーライドの違いをあんまりわかってなかったりする。隠ぺいの方は臭い物に蓋をするってイメージで理解している。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Humanoid { public void Yell() { Debug.Log("Humanoid version of the Yell() method"); } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Enemy : Humanoid { new public void Yell() { Debug.Log("Enemy version of the Yell() method"); } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Orc : Enemy{ new public void Yell() { Debug.Log("Orc version of the Yell() method"); } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Warband : MonoBehaviour { void Start() { Humanoid human = new Humanoid(); Humanoid enemy = new Enemy(); Humanoid orc = new Orc(); Debug.Log(human.GetType()); // Humanoid Debug.Log(enemy.GetType()); // Enemy Debug.Log(orc.GetType()); // Orc human.Yell(); // Humanoid version of the Yell() method enemy.Yell(); // Humanoid version of the Yell() method orc.Yell(); // Humanoid version of the Yell() method } }
オーバーライド
上書き。オーバーロードと混同しがちだけど、アインズ様がでるほうがオーバーロードですね(違う)。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Fruit { public Fruit() { Debug.Log("1st Fruit Constructor Called"); } public virtual void Chop() { Debug.Log("The fruit has been chopped."); } public virtual void SayHello() { Debug.Log("Hello, I am a fruit."); } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Apple : Fruit { public Apple() { Debug.Log("1st Apple Constructor Called"); } public override void Chop() { base.Chop(); Debug.Log("The apple has been chopped."); } public override void SayHello() { base.SayHello(); Debug.Log("Hello, I am an apple."); } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class FruitSalad : MonoBehaviour { void Start() { Apple myApple = new Apple(); // 1st Fruit Constructor Called // 1st Apple Constructor Called myApple.SayHello(); // Hello, I am a fruit. // Hello, I am an apple. myApple.Chop(); // The fruit has been chopped. // The apple has been chopped. Fruit myFruit = new Apple(); // 1st Fruit Constructor Called // 1st Apple Constructor Called myFruit.SayHello(); // Hello, I am a fruit. // Hello, I am an apple. myFruit.Chop(); // The fruit has been chopped. // The apple has been chopped. } }
C#独特な名前の修飾子が多いのでその挙動についてはあんま理解していなかったりする。
インターフェース
インタフェースについての話。僕の中ではメソッド一覧を確認しやすくするための索引ぐらいのイメージしかない。挨拶インターフェースとかそういうシンプルやつばっかり見てきたせいだからだろうね……。
using System.Collections; using System.Collections.Generic; using UnityEngine; // 「I〇〇able」で命名するのが慣習 public interface IKillable { void Kill(); } public interface IDamageable<T> { void Damage(T damageTaken); }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Avatar : MonoBehaviour, IKillable, IDamageable<float> { public void Kill() { Debug.Log("Kill"); } public void Damage(float damageTaken) { Debug.Log(damageTaken+" Damage"); } // 動作確認用 void Start() { Kill(); // Kill Damage(100f); // 100 Damage } }
拡張メソッド
拡張メソッドを使用すると、新規の派生型の作成、再コンパイル、または元の型の変更を行うことなく既存の型にメソッドを "追加" できます。
using System.Collections; using System.Collections.Generic; using UnityEngine; public static class ExtensionMethods { public static void ResetTransformation(this Transform trans) { trans.position = Vector3.zero; trans.localRotation = Quaternion.identity; trans.localScale = new Vector3(1, 1, 1); } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class SomeClass : MonoBehaviour { void Start() { transform.ResetTransformation(); } }
名前空間
僕の中ではラベルという認識。using なんとか;
ってところでそのありがたさが分かる感じ。namespace SampleNamespace{ }
で囲めば独自のやつを利用できるとのこと。
using UnityEngine; using System.Collections; namespace SampleNamespace { public class SomeClass : MonoBehaviour { void Start () { } } }
リストとディクショナリ
リストとディクショナリについて。Pythonやってからこれをみるとnew
してやらないと使えないのが手間に感じる。
using UnityEngine; using System.Collections; using System; // IComparableインタフェース用 public class BadGuy : IComparable<BadGuy> { public string name; public int power; public BadGuy(string newName, int newPower) { name = newName; power = newPower; } public int CompareTo(BadGuy other) { if (other == null) { return 1; } return power - other.power; } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class SomeClass : MonoBehaviour { void Start() { // リスト Debug.Log("List"); List<BadGuy> badguys = new List<BadGuy>(); badguys.Add(new BadGuy("Harvey", 50)); badguys.Add(new BadGuy("Magneto", 100)); badguys.Add(new BadGuy("Pip", 5)); badguys.Sort(); foreach (BadGuy guy in badguys) { print(guy.name + " " + guy.power); } badguys.Clear(); } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class SomeOtherClass : MonoBehaviour { void Start() { // ディクショナリ Debug.Log("Dictionary"); Dictionary<string, BadGuy> badguys = new Dictionary<string, BadGuy>(); BadGuy bg1 = new BadGuy("Harvey", 50); BadGuy bg2 = new BadGuy("Magneto", 100); badguys.Add("gangster", bg1); badguys.Add("mutant", bg2); BadGuy magneto = badguys["mutant"]; BadGuy temp = null; // ディクショナリへのアクセス例:安全だが時間がかかる // Memo: TryGetValueのキーが存在しない場合は規定値を返す(この場合はnull) if (badguys.TryGetValue("mutant", out temp)) { print(temp.name+" "+temp.power); } else { print(temp); } } }
今回はここまで。そんなわけで次回はコルーチンです。僕の中では完全にアップデート外で動かしたいアニメーションなどがあるときに使う機能という認識になっている……。実際どういうときに使うのが正解なのか……。
つづく