[UnityC#] 객체 지향 프로그래밍

내발은개발내손은개발·2026년 1월 11일

객체지향 프로그래밍

: 현실 세계를 모형으로 모든 것을 객체로 표현하는 프로그래밍 방식

객체

  • 속성과 기능을 가진 실체를 가진 대상
  • 유니티에서 GameObject + Component로 객체를 구성

객체 지향 프로그래밍의 특성

  • 추상화 : 핵심 정보만 공개 (설계의 단순화)
  • 상속 : 코드 재사용, 부모 기능 물려받기 (코드간결,유지보수 용이)
  • 다형성 : 같은 함수, 다양한 동작 실행 (유연한 설계)
  • 캡슐화 : 내부 정보 은닉, 접근 통제 (보안성과 안정성)

오버로딩(Overloading)

: 동일한 함수명의 매개변수를 다르게 설정해서 다른 기능을 구현하는 방법(다형성, 유연성)

	매개변수 타입만 다른 함수 3public void Method(int a){}
    public void Method(float a){}
    public void Method(string a){}
    
    하나로 모든 타입을 받을 수 있는 제너릭을 활용한 함수
    
    public void Method<T>(T a){}
    
    함수명은 같지만 매개변수가 달라 다른 함수가 된다.
    
    private void TargetMovement(Transform target)
    {
    	//target이 앞으로 이동하는 기능
    }
    private void TargetMovement(Transform target, Transform destination)
    {
    	//target이 목적지를 향해 이동하는 기능
    }
    private void TargetMovement(Transform target, Transform destination, float speed)
    {
    	//target이 목적지를 향해 speed의 속도를 가지고 이동하는 기능
    }

캡슐화(Encapsulation)

: 외부에서 직접 접근하는 것을 제한하여 데이터 무결성을 보장하는 방법
-> 속성과 함수를 하나의 클래스로 묶고, 접근을 제한하여 은닉성 부여

접근 제한자

  • public : 모든 외부 접근 허용 (외부 접근 허용 필드, 메서드)
  • private : 클래스 내부에서만 접근 가능 (내부 필드, 내부 로직 전용)
  • protected : 상속받은 클래스까지 접근 가능 (자식 클래스에게만 접근 허용)
public int number; -> 외부 클래스 접근 O, 유니티 접근 O
private int number; -> 외부 클래스 접근 X, 유니티 접근 X -> 내부에서만 접근 가능
protected int number; -> 외부 클래스 접근 X, 유니티 접근 X -> 내부와 자식 클래스에서만 접근 가능

//[] 애티르뷰트 Attribute -> 코드에 대한 부가 정보를 기록하고 읽을 수 있는 기능(컴퓨터가 읽는 주석)
[HideInInspector] public int number; -> 외부 클래스 접근 O, 유니티 접근 X -> 인스펙터에서 수정을 방지
[SerializeField] private int number; -> 외부 클래스 접근 X, 유니티 접근 O
[SerializeField] protected int number; -> 외부 클래스 접근 X, 유니티 접근 O -> 내부와 자식 클래스 접근 O
[field:SerializeField] public int number{get; set;} -> 프로퍼티를 인스펙터에서 보여주는 기능
[System.Serializable]
public class Example
{
	public int num1;
    public int num2;
    private int num3;
}

public class Test : MonoBehaviour
{
	public Example example = new Example();
}
-> [System.Serializable]을 사용함으로써 Test스크립트를 사용하는 오브젝트는 num1,num2가 인스펙터에서 보여진다

프로퍼티(Property) : 캡슐화한 데이터(접근자, 설정자 메소드를 축약)

public class Example
{
	int num = 10;
    public int Num
    {
    	get { return num; }
        set { num = value; } == public void SetNum(int value){num = value;} 컴파일러가 자동으로 매개변수 인식
    }
}

public class Example 
{
	public int Num {get;set;} -> 자동 구현 프로퍼티 : 프로퍼티를 더 축약
}

public class Example -> 프로퍼티를 인스펙터 창에서 보여주도록 설정
{
	[field:SerializeField]
	public int Num {get;set;}
}

직렬화 (Serialization)

: 데이터를 byte 배열로 변환하는 작업(데이터를 직선으로 바꾸는 기능)
-> 게임저장 / 네트워크 연결 시 이용
-> public : 내부적으로 직렬화 과정을 거쳐서 유니티 에디터에서 보이도록 설정한 접근 제한자
-> 인스펙터 창 : 게임 오브젝트의 컴포넌트 필드 값을 확인하거난 변경하면 Unity 에디터가 해당 데이터를 직렬화한 후 인스펙터창에 표시

역직렬화 (Deserialize)

: byte 배열을 데이터로 변환하는 작업(직선 데이터를 원래대로 바꾸는 기능)

상속 (Inheritance)

: 부모 클래스를 자식 클래스가 물려 받아, 부모 클래스의 속성과 기능을 쓸 수 있는 방법
-> 기존 코드 재사용 용이, 확장도 가능

  • 상속받은 변수는 그대로 사용 가능
class Monster
{
	//이동 기능
    //공격 기능
    //사망 기능
}

class Orc : Monster
{
	//오크 스킬 기능
    //오크 고유 기능
}

class Zombie : Monster
{
	//좀비 고유 기능
}

class OrcArcher : Orc
{
	//오크궁수 고유 스킬 (활쏘기)
    //오크궁수 고유 기능
}
Monster <- Orc <- OrcArcher

다형성 (Polymorphism)

: 다른 형태여도 같은 타입이라면 제어가능 -> 유연한 설계 가능

public class Character
{
	public float hp;
    public float damage;
    
    public virtual void Move(){}
    public virtual void Attack(){}   
}

public class Player : Character
{
	public override void Move()
    {
    	Debug.Log("플레이어 이동");
    }
    public override void Attack()
    {
    	Debug.Log("플레이어 공격");
    }
}

Virtual, Abstract, Override

: 상속받은 함수를 변경하는 기능

Virtual - Override

  • 부모 클래스에서 virtual 사용 시, 자식 클래스에서 선택적 재정의(override) 가능
  • base 키워드를 활용하여 기존 기능 + 추가 기능 구현 -> 기능 유연성
  • 기능 확장
public class Monster : MonoBehaviour
{
	public virtual void Attack(){}
    public virtual void Shout(){}
}

public class Goblin : Monster
{
	public override void Attack()
    {
    	base.Attack();
        // + 독 데미지 추가 기능
    }
    public override void Shout()
    {
    	//shout 기능
    }
}

public class OrcMonster
{
	public override void Attack()
    {
    	base.Attack();
        // + 범위 공격 추가 기능
    }
    public override void Shout()
    {
    	//shout 기능
    }
}

Abstract - Override (추상 메소드)

  • 부모 클래스에서 abstract 사용 시, 자식 클래스에서 필수적 재정의(override)
  • 부모 클래스에서 기능 구현 불가 -> base 키워드 사용 불가
  • 구조 설계, 기능 확장
public class Monster : MonoBehaviour
{
	public abstract void Attack(); -> 구현 불가
    public abstract void Shout();
}

public class Goblin : Monster
{
	public override void Attack()
    {
        //독 데미지 공격 기능
    }
    public override void Shout()
    {
    	//shout 기능
    }
}

public class OrcMonster
{
	public override void Attack()
    {
    	base.Attack();
        //범위 공격 기능
    }
    public override void Shout()
    {
    	//shout 기능
    }
}

다중 상속

: 부모 클래스를 여러개 상속받는 것

public class Monster
{
	public virtual void Attack(){}
}

public class Orc : Monster
{
	public override void Attack(){}
}
public class Ogre : Monster
{
	public override void Attack(){}
}

public class CheifOrc : Orc, Ogre --> 오류 발생
{
	public override void Attack(){}
}
  • 죽음의 다이아몬드 구조
    : 하나의 부모 클래스를 두개의 자식 클래스가 상속받고 다시 하나의 자식 클래스가 상속받는 것

인터페이스 (Interface)

: 프로그래밍상 계약 혹은 약속으로 정의(구현해야 하는 기능, 추가 기능, 다형성)

  • 추상 클래스로 대체 가능
  • I붙이고 이름 ex) IAttack, IRun, IMove
  • 인터페이스는 클래스가 아니라 다중 상속 기능이 가능
  • 인스턴스 생성 불가
public interface IAttack
{
	public void Attack();
}
public interface IMove
{
	public void Move();
}

public class Orc : IAttack, IMove -> 다중 상속 가능
{
	public void Attack()
    {
    	Debug.Log("Orc Attack");
    }
    
    public void Move()
    {
    	//움직이는 기능
    }
}

public interface IDamageable
{
	int Hp {get; set;}
    
    void TakeDamage(int dmg);
    void Death();
}

public class Tree
{
	//파괴 불가능한 오브젝트
}

//파괴 가능한 오브젝트들
public class Wall : IDamageable
{
	public void TakeDamage(int amount){}
    public void Death(){}
}
public class Car : IDamageable
{
	public void TakeDamage(int amount){}
    public void Death(){}
}

0개의 댓글