コミュ障だから明日が僕らをよんだって返事もろくにしなかった

何かを創る人に憧れたからブログをはじめたんだと思うよ

そろそろ僕もちゃんとした(ry Part II

そろそろ(ry

はい、おはようございます。僕です。早速ですが本日は前回の続きをやっていきます。

前回記事
inujini.hatenablog.com
そう、こいつの続きをですね。やはりやるからにはささっと終わらせたいと思うのですよ。


三項演算子

ということで三項演算子です。C#のリファレンス読んでたら条件演算子 ?とも呼ぶらしい。前回めっちゃ使ってるとか言ったけどPython三項演算子だけは実は使いこなせてなかったりするw。

using UnityEngine;
public class TernaryOperator : MonoBehaviour {
	void Start () {
        int health = 10;
        string message;
        // condition ? consequent : alternative
        message = health > 0 ? "Player is Alive" : "Player is Dead";
        // Player is Alive
        Debug.Log(message);
    }
}

書き方はコメントにある通りです。特に言うことはない…。

statics

次はstatic修飾子についてみていきます。静的メンバーの宣言に使用するやつ。newしなくても使えるので気が付くと僕は多様していることが多い……。まあいいや見ていきましょう。

using UnityEngine;
using System.Collections;
public class Enemy
{
    // enemyCount
    public static int enemyCount = 0;

    public Enemy()
    {
        enemyCount++;
    }
}
using UnityEngine;
using System.Collections;
public class Game
{
    void Start () 
    {
        Enemy enemy1 = new Enemy();
        Enemy enemy2 = new Enemy();
        Enemy enemy3 = new Enemy();

        // Enemy.enemyCount
        int x = Enemy.enemyCount;
    }
}

using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour 
{
    // playerCount
    public static int playerCount = 0;

    void Start()
    {
        playerCount++;
    }
}
using UnityEngine;
using System.Collections;

public class PlayerManager : MonoBehaviour 
{
    void Start()
    {
        // Player.playerCount
        int x = Player.playerCount;
    }
}

using UnityEngine;
using System.Collections;

public static class Utilities 
{
    // Add
    public static int Add(int num1, int num2)
    {
        return num1 + num2;
    }
}
using UnityEngine;
using System.Collections;

public class UtilitiesExample : MonoBehaviour 
{
    void Start()
    {
        // Utilities.Add
        int x = Utilities.Add (5, 6);
    }
}

説明のコード多いなと思ったら3例分あったのね。


メソッドオーバーロード

実を言うとクソみたいな名前をつけがちの僕は使わない機能。用語的には一つの変数や演算子に複数の定義をもたせ、文脈によって使い分けるってやつ。以下例だとAdd

using UnityEngine;
using System.Collections;

public class SomeClass
{
    public int Add(int num1, int num2)
    {
        return num1 + num2;
    }

    public string Add(string str1, string str2)
    {
        return str1 + str2;
    }
}
using UnityEngine;
using System.Collections;

public class SomeOtherClass : MonoBehaviour 
{
    void Start () 
    {
        SomeClass myClass = new SomeClass();
        // myClass.Add
        myClass.Add (1, 2);                       // 3
        myClass.Add ("Hello ", "World"); // Hello World
    }
}



ジェネリクス

僕が未だにその便利さを理解できないでいるジェネリクスについて。その便利さを未だに理解できないのでとりあえず書き方だけ覚えておけばいいかというぐらいの気持ちでやっていきます。僕の認識はオーバーロードのごった煮版……。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SomeClass {
    // 'T' は実行時に実際の型に置換
    public T GenericMethod<T>(T param)
    {
        return param;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SomeOtherClass : MonoBehaviour {

    void Start()
    {
        SomeClass myClass = new SomeClass();
        
        // -> T GenericMethod<T>(T param)
        myClass.GenericMethod<int>(5); // 5
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GenericClass<T>
{
    T item;
    public void UpdateItem(T newItem)
    {
        item = newItem;
    }
}
using UnityEngine;
using System.Collections;

public class GenericClassExample : MonoBehaviour
{
    void Start()
    {
        GenericClass<int> myClass = new GenericClass<int>();
        myClass.UpdateItem(5);  // 5
    }
}




継承

僕が稀に思い出したかのように使う機能。用語的には「オブジェクト指向プログラミングの要素のひとつで、既存のクラスの属性を新規に作成したクラスに引き継がせる」だそうです。Unityだと何気なく使っているMonoBehaviourとかがこれに相当するやつですかね……。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Fruit {
    public string color;
    public Fruit()
    {
        color = "orange";
        Debug.Log("1st Fruit Constructor Called");
    }

    public Fruit(string newColor)
    {
        color = newColor;
        Debug.Log("2nd Fruit Constructor Called");
    }

    public void Chop()
    {
        Debug.Log("The " + color + " fruit has been chopped.");
    }

    public void SayHello()
    {
        Debug.Log("Hello, I am a fruit.");
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Apple : Fruit {
    public Apple()
    {
        color = "red";
        Debug.Log("1st Apple Constructor Called");
    }

    public Apple(string newColor) : base(newColor)
    {
        Debug.Log("2nd Apple Constructor Called");
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FruitSalad : MonoBehaviour {

	void Start () {

        Debug.Log("Creating the fruit");
        Fruit myFruit = new Fruit(); // 1st Fruit Constructor Called
        Debug.Log("Creating the apple");

        Apple myApple = new Apple();
        // 1st Fruit Constructor Called
        // 1st Apple Constructor Called

        myFruit.SayHello(); // Hello, I am a fruit.
        myFruit.Chop();     // The oarnge fruit has been chopped.

        myApple.SayHello(); // Hello, I am a fruit.
        myApple.Chop();     // The red fruit has been chopped.

        Debug.Log("Creating the fruit");
        myFruit = new Fruit("yellow");   // 2nd Fruit Constructor Called
        Debug.Log("Creating the apple");
        myApple = new Apple("green");
        // 2nd Fruit Constructor Called
        // 2nd Apple Constructor Called

        myFruit.SayHello(); // Hello, I am a fruit.
        myFruit.Chop();     // The oarnge fruit has been chopped.

        myApple.SayHello(); // Hello, I am a fruit.
        myApple.Chop();     // The green fruit has been chopped.
    }
}

「理解した」とかそういうのはコメント部分の流れで理解したってことにならないかな。


ポリモーフィズム

定義的には以下のようなやつ。僕の中では単なるテクニックの名称でこれが「ポリモーフィズム」なんだってものはこの世に存在しないと思ってる(哲学)。

プログラミング言語の持つ性質の一つで、ある関数やメソッドなどが、引数や返り値の数やデータ型などの異なる複数の実装を持ち、呼び出し時に使い分けるようにできること

んで例だと、アップキャストとダウンキャストでその機能に柔軟性を持たせようとかやってます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Fruit {
    public Fruit()
    {
        Debug.Log("1st Fruit Constructor Called");
    }

    public void Chop()
    {
        Debug.Log("The fruit has been chopped.");
    }

    public 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 new void Chop()
    {
        Debug.Log("The apple has been chopped.");
    }

    public new void SayHello()
    {
        Debug.Log("Hello, I am an apple.");
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FruitSalad : MonoBehaviour {
    void Start()
    {
        Fruit myFruit = new Apple();
        // 1st Fruit Constructor Called
        // 1st Apple Constructor Called
        myFruit.SayHello();           // Hello, I am a fruit.
        myFruit.Chop();               // The fruit has been chopped.

        // ダウンキャスト
        Apple myApple = (Apple)myFruit;

        myApple.SayHello(); // Hello, I am an apple.
        myApple.Chop();     // The apple has been chopped.
    }
}

この例だと、便利機能だと感じるよりも設計事故にしか見えない……。ダウンキャストについてググってみたらあんまりよく思われてないっぽい。まあ、ネットの判断だから世間的に正しいのかは知らないけどもこの嗅覚は大事にしていきたい。




とりあえずここまで。確認用コード書いてたらめっちゃ長くなってしまったので分割します。あと三回ぐらいで終わるかな…。終えたいな。次回はメンバの隠ぺいやっていきます。


つづく。