[SKKU DT] 24일차 -유니티 C# 클래스 (생성자, this, static, 상속, 오버라이딩, 구조체)
2023. 11. 30. 18:19ㆍSKKU 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
반응형
'SKKU DT' 카테고리의 다른 글
[SKKU DT] 26일차 -유니티 미니 프로젝트(로봇 팔 시뮬레이션) (1) | 2023.12.05 |
---|---|
[SKKU DT] 25일차 -유니티 C# 튜플, 인터페이스, 추상클래스, 프로퍼티, 레코드, 무명 형식, 배열 (1) | 2023.12.01 |
[SKKU DT] 23일차 -유니티 C# 메소드와 매개변수 (0) | 2023.11.29 |
[SKKU DT] 23일차 -유니티 C# 계산기 만들기 (0) | 2023.11.29 |
[SKKU DT] 22일차 -C# 연산자 정리(증감, 조건부, 할당 연산자), 조건문(If, Switch), 반복문 (0) | 2023.11.28 |