[SKKU DT] 24일차 -유니티 C# 클래스 (생성자, this, static, 상속, 오버라이딩, 구조체)

2023. 11. 30. 18:19SKKU DT

728x90
반응형

클래스 기본 예제

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

namespace BasicClass
{
    public class BasicClass : MonoBehaviour
    {
        void Start()
        {
            Cat kitty = new Cat();
            kitty.Color = "하얀색";
            kitty.Name = "키티";
            kitty.Meow();
            Debug.Log($"{kitty.Name} : {kitty.Color}");

            Cat nero = new Cat();
            nero.Color = "검은색";
            nero.Name = "네로";
            nero.Meow();
            Debug.Log($"{nero.Name} : {nero.Color}");
        }
    }
    class Cat
    {
        public string Name;
        public string Color;

        public void Meow()
        {
            Debug.Log($"{Name} : 야옹");
        }
    }
}

 

 


 

 

<메서드 구조>

반환값 메서드명 (매개변수)

ex. bool Login (string a)

 

다른 프로젝트에 재활용 할 수 있는지에 따라 클래스를 생성할 수 있다.

 

 


 

 

생성자

메서드의 한 종류. 생성자는 클래스와 이름이 같고 반환 형식이 없다. 생성자의 임무는 클래스의 객체를 생성하는 것.

생성자는 주로 값을 초기화 하는 목적으로 사용한다.

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

namespace Constructor
{
    class Cat
    {
        //멤버 변수
        public string Name;
        public string Color;

        //두 가지 형태의 생성자 메서드
        //괄호에 아무 것도 넣지 않은 형태
        public Cat()
        {
            Name = "";
            Color = "";
        }
        //두 개의 매개 변수를 받는 형태
        public Cat(string _Name, string _Color)
        {
            Name = _Name;
            Color = _Color;
        }

        ~Cat() //종료자
        {
            Debug.Log($"{Name} : 잘가");
        }

        public void Meow()
        {
            Debug.Log($"{Name} : 야옹");
        }
    }
    public class Constructor : MonoBehaviour
    {
        void Start()
        {
            Cat kitty = new Cat("키티", "하얀색");
            kitty.Meow();
            Debug.Log($"{kitty.Name} : {kitty.Color}");

            Cat nero = new Cat("네로", "검은색");
            nero.Meow();
            Debug.Log($"{nero.Name} {nero.Color}");
        }
    }
}
실행 결과

키티 : 야옹
키티 : 하얀색
네로 : 야옹
네로 : 검은색
네로 : 잘가
키티 : 잘가

 

 

this

this의 의미는 변수가 속해있는 해당 객체를 의미한다. "this.멤버변수"로 쓴다.

"this.name = name;"의 의미 : 멤버변수에 매개변수를 대입한다.

public Person()
{
    name = "";
    age = 0;
}

public Person(string name, int age)
{
    this.name = name; //this의 의미는 변수가 속해있는 해당 객체. "this.멤버변수"로 쓴다
    this.age = age;
}
class Gun
{
    string name; //멤버 변수 name. public이 아니기 때문에 바꿔줄 수 없다. 메소드를 통해서 값을 읽고 쓰는 형태로 많이 쓴다.

    public Gun(string name)
    {
        this.name = name; //this.멤버 변수(name) = 매개변수(name);
    }

    void shoot()
    {
        Debug.Log("Shoot");
    }
}

멤버 변수 name은 public이 아니기 때문에 바꿔줄 수 없다. 메소드를 통해서 값을 읽고 쓰는 형태로 많이 쓴다.

 

 

아래와 같은 메서드로 객체의 멤버 변수를 불러올 수 있다.

public string GetName()
{
    return this.name;
}
public int GetAge()
{
    return this.age;
}

 

 

변수를 전달할 때는 아래와 같은 메서드를 사용한다.

//Person에게 할당할 gun
Gun gun;

public void SetGun(Gun gun)
{
    this.gun = gun;
}

 

 

예시 전체 코드

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

namespace TestObject
{
    class Gun
    {
        string name; //멤버 변수 name. public이 아니기 때문에 바꿔줄 수 없다. 메소드를 통해서 값을 읽고 쓰는 형태로 많이 쓴다.

        public Gun(string name)
        {
            this.name = name; //this.멤버 변수(name) = 매개변수(name);
        }

        public string GetName()
        {
            return this.name;
        }
        public void Shoot()
        {
            Debug.Log("Shoot");
        }
    }
    class Person
    {
        //멤버 변수만 있는 클래스
        string name;
        int age;
        
        //Person에게 할당할 gun
        Gun gun;

        public void SetGun(Gun gun)
        {
            this.gun = gun;
        }
        
        //공격
        public void Attack()
        {
            if(this.gun != null)
            {
                this.gun.Shoot();
            }
        }
        
        public Person()
        {
            name = "";
            age = 0;
        }

        public Person(string name, int age)
        {
            this.name = name; //this의 의미는 변수가 속해있는 해당 객체. "this.멤버변수"로 쓴다
            this.age = age;
        }

        public string GetName()
        {
            return this.name;
        }
        public int GetAge()
        {
            return this.age;
        }
        //Talk 메서드 생성
        public bool Talk(string story)
        {
            Debug.Log($"Talk : {story}");
            return true;
        }
    }
    public class ConstructorTest : MonoBehaviour
    {
        void Start()
        {
            //캐릭터 생성
            Person a = new Person("홍길동", 23);
            bool result = a.Talk("굿모닝");

            //총 할당
            Gun gun = new Gun("K1");
            a.SetGun(gun);
            
            //공격
            a.Attack();
        }
    }
}

 

 


 

 

클래스 예제

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

namespace TestClass
{
    class Cat
    {
        string name;
        int age;
    }

    class CatTown
    {
        public Cat MakeCat() //Cat 객체를 만들어줌
        {
            Cat cat = new Cat();
            return cat;
        }
    }

    public class TestClass : MonoBehaviour
    {
        void Start()
        {
            CatTown catTown = new CatTown();
            Cat cat1 = catTown.MakeCat();
            cat1 = null; //cat1은 살아있지만 가리키는 객체는 없어졌으므로 이후 가비지 콜렉터가 메모리를 지운다.
            Cat cat2 = catTown.MakeCat();
            Cat cat3 = catTown.MakeCat();
        }
    }
}

 

 

 

static

public static void Test()
{
    Debug.Log($"Test");
}

static으로 선언된 함수는 "Person person1 = new Person();" 과 같은 객체 선언 없이 사용할 수 있다.

Person.Test();

 

static 전체 예시

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

namespace TestCsharp
{
    class Person
    {
        public static int count; //정적 변수

        string name;
        int age;

        public Person()
        {
            count++;
            this.name = "";
            this.age = 0;
        }

        public Person(string name, int age = 0)
        {
            count++;
            this.name = name;
            this.age = age;
        }

        public void Talk(string content)
        {
            Debug.Log($"{name} : {content}");
        }

        public static void Test() //정적 함수
        {
            Debug.Log($"Test");
        }
    }
    public class TestClass2 : MonoBehaviour
    {
        void Start()
        {
            Person person1 = new Person();
            Person person2 = new Person("홍길동, 23");
            Person person3 = new Person("김길동");

            person1.Talk("안녕하세요"); //": 안녕하세요" 출력
            person2.Talk("안녕하세요"); //"홍길동 : 안녕하세요" 출력
            person3.Talk("안녕하세요"); //"김길동 : 안녕하세요" 출력

            Person.Test(); //객체 선언을 하지 않아도 함수를 사용할 수 있다.
            
            //Person.count = 0;
            Debug.Log($"전체 Person 객체의 수 : {Person.count}");
        }
    }
}

 

 


 

 

객체 복사 DeepCopy

using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using UnityEngine;

namespace TestCsharp
{
    class Person
    {
        string name;
        int age;

        public Person()
        {
            this.name = ""; //기본 생성자
            this.age = 0;
        }

        public Person(string name, int age = 0) //매개 변수 중 앞에 변수만 기본 값을 줄 수는 없다. 뒤 변수만 기본값 넣기는 가능.
        {
            this.name = name;
            this.age = age;
        }

        public void Talk(string content)
        {
            Debug.Log($"{name} : {content}");
        }

        public Person DeepCopy()
        {
            Person person = new Person();
            person.name = this.name;
            person.age = this.age;
            return person;
        }
    }
    public class TestClass2 : MonoBehaviour
    {
        void Start()
        {
            Person person1 = new Person();

            Person person2 = person1; //객체가 복사되지는 않는다. 하나의 객체로 유지 중. person2에서 변경하면 person1에도 적용됨

            Person person3 = person1.DeepCopy(); //객체가 복사되었다.
        }
    }
}

 

 


 

 

생성자의 표시 방법

public Person(string name)
{
    this.name = name;
    this.age = 0;
    this.height = 0;
}

=

public Person(string name) : this(name, 0, 0)
{

}

=

public Person(string name) : this(name, 0, 0) { }

위의 모든 표현 방법이 같다.

 

 


 

 

클래스 상속

class Weapon //부모 클래스 생성
{
    private string name;

    public Weapon(string name)
    {
        this.name = name;
    }
}
class Sword : Weapon
{
    public Sword(string name) //지워도 되는 생성자
    {
        this.name = name;
    }

    public void Stab()
    {
        Debug.Log("Stab!!");
    }
}

자식의 생성자는 지워도 된다.

 

 

아래와 같이 표현될 수 있다.

class Weapon //부모 클래스 생성
{
    private string name;

    public Weapon(string name)
    {
        this.name = name;
    }
}
class Sword : Weapon
{
    public Sword(string name) : base(name) { }
    public void Stab()
    {
        Debug.Log("Stab!!");
    }
}
class Gun : Weapon
{
    public Gun(string name) : base(name) { }
    public void Shoot()
    {
        Debug.Log($"Shoot!!");
    }
}

 

 


 

 

클래스 상속 2

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

namespace CoffeSample
{
    class Espresso
    {
        public string name;

        public void Drink()
        {
            Debug.Log("Drink!!");
        }
    }

    class Americano : Espresso
    {
        public int water;
    }
    class Latte : Espresso
    {
        public int milk;
    }
    public class CoffeSample : MonoBehaviour
    {
        void Start()
        {
            Espresso espresso = new Espresso();
            espresso.name = "케냐AA";
            espresso.Drink();

            Americano americano = new Americano();
            americano.name = "케냐AA";
            americano.water = 200;
            americano.Drink();

            Latte latte = new Latte();
            latte.name = "케냐AA";
            latte.milk = 200;
            latte.Drink();
        }
    }
}

 

 

상속 예시2

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

namespace CoffeSample
{
    class Espresso
    {
        public string name;

        public void Drink()
        {
            Debug.Log("Drink!!");
        }
    }

    class Americano : Espresso
    {
        public int water;
    }
    class Latte : Espresso
    {
        public int milk;
    }
    public class CoffeSample : MonoBehaviour
    {
        void Start()
        {
            Espresso espresso = new Espresso();
            Americano americano = new Americano();
            Latte latte = new Latte();

            //Espresso라는 변수 타입에 할당 할 수 있다.
            Espresso a1 = americano; //Espresso의 변수 a1에 할당되는 순간 americano의 water는 없어진다.
            //a1.water = 200; 접근이 안된다.
            Espresso a2 = latte;
            Espresso a3 = espresso;
        }
    }
}

 

 

 

상속 예시3

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

namespace CoffeSample
{
    class Espresso
    {
        public string name;

        public void Drink()
        {
            Debug.Log("Drink!!");
        }
    }

    class Americano : Espresso
    {
        public int water;

        public void Drink()
        {
            Debug.Log("아! 진하다! 진하야 안녕");
        }
    }
    class Latte : Espresso
    {
        public int milk;

        public void Drink()
        {
            Debug.Log("아! 고소해! 법정에서 보자구");
        }
    }

    class Person
    {
        public Espresso coffee;
        
        public void Drink()
        {
            if(coffee != null)
            {
                coffee.Drink();
            }
        }
    }
    public class CoffeSample : MonoBehaviour
    {
        void Start()
        {
            Person person = new Person();

            Americano americano = new Americano();
            americano.Drink();

            Latte latte = new Latte();
            latte.Drink();

            Espresso espresso = americano;
            espresso.Drink();

            Americano americano2 = espresso as Americano;
            americano2.Drink();
        }
    }
}

 

 


 

 

오버라이딩

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

namespace Overriding
{
    class ArmorSuite
    {
        public virtual void Initialize() //메소드를 오버라이딩 하기 위해서는 virtual이 꼭 필요함
        {
            Debug.Log("Armored");
        }
    }

    class IronMan : ArmorSuite
    {
        public override void Initialize() //Initialize() 메소드 오버라이드
        {
            base.Initialize(); //원래 있던 것 불러오기
            Debug.Log("Repulsor Rays Armed");
        }
    }

    class WarMachine : ArmorSuite
    {
        public override void Initialize() //Initialize() 메소드 오버라이드
        {
            base.Initialize(); //원래 있던 것 불러오기
            Debug.Log("Double-Barrel Cannons Armed");
            Debug.Log("Micro-Rocket Launcher Armed");
        }
    }
    public class Overriding : MonoBehaviour
    {
        void Start()
        {
            Debug.Log("Creating ArmorSuite...");
            ArmorSuite ArmorSuite = new ArmorSuite();
            ArmorSuite.Initialize();

            Debug.Log("Creating Ironman...");
            ArmorSuite ironman = new IronMan();
            ironman.Initialize();

            Debug.Log("Creating WarMachine...");
            ArmorSuite warmachine = new WarMachine();
            warmachine.Initialize();
        }
    }
}

 

 


 

 

읽기 전용 필드

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

namespace ReadonlyField
{
    public class ReadonlyFields : MonoBehaviour
    {
        void Start()
        {
            Configuration c = new Configuration(100, 10);
        }
    }

    class Configuration
    {
        private readonly int min; //읽기 전용으로 선언된 변수들은 생성자에서 값을 할당할 수 있다. 이후에 값 변경 불가능.
        private readonly int max;

        public Configuration(int v1, int v2)
        {
            min = v1; //생성자에서 값을 할당
            min = v2;
        }

        public void ChangeMax(int newMax) //값 변경이 불가능하다.
        {
            max = newMax; //Error
        }
    }
}

 

 


 

 

확장 메서드

using E0602;
using MyExtension;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

namespace MyExtension
{
    public static class IntegerExtension
    {
        public static int Square(this int myInt)
        {
            return myInt * myInt;
        }

        public static int Power(this int myInt, int exponent)
        {
            int result = myInt;
            for(int i = 1; i < exponent; i++)
            {
                result = result * myInt;
            }
            return result;
        }
    }
}

namespace ExtensionMethod
{
    public class ExtensionMethod : MonoBehaviour
    {
        private void Start()
        {
            Debug.Log($"3^2 : {3.Square()}");
            Debug.Log($"3^4 : {3.Power(4)}");
            Debug.Log($"3^10 : {2.Power(10)}");
        }
    }
}

 

 


 

 

구조체

데이터들은 주로 구조체 형식으로 만든다.

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

namespace Structure
{
    struct Point3D
    {
        public int x;
        public int y;
        public int z;

        public Point3D(int x, int y, int z)
        {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        public override string ToString()
        {
            return string.Format($"{x}, {y}, {z}");
        }
    }
    public class Structure : MonoBehaviour
    {
        void Start()
        {
            Point3D p3d1;
            p3d1.x = 10;
            p3d1.y = 20;
            p3d1.z = 40;

            Debug.Log(p3d1.ToString()); //출력값 10, 20, 40

            Point3D p3d2 = new Point3D(100, 200, 300);
            Point3D p3d3 = p3d2;
            p3d3.z = 400;

            Debug.Log(p3d2.ToString()); //출력값 100, 200, 300
            Debug.Log(p3d2.ToString()); //출력값 100, 200, 400
        }
    }
}

 

 

읽기 전용 구조체

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

namespace ReadonlyStruct
{
    readonly struct RGBColor
    {
        public readonly byte R;
        public readonly byte G;
        public readonly byte B;

        public RGBColor(byte r, byte g, byte b)
        {
            R = r;
            G = g;
            B = b;
        }
    }

    public class ReadonlyStruct : MonoBehaviour
    {
        void Start()
        {
            RGBColor Red = new RGBColor(255, 0, 0);
            Red.G = 100; //Error 읽기 전용이라 수정 불가능
        }
    }
}
728x90
반응형