Unity3D/C#

C# 강좌 Day-13 (class, struct)

일등하이 2021. 8. 15. 18:12
반응형

https://youtu.be/PBVEWcqggiQ?list=PLTFRwWXfOIYBmr3fK17E0VhKPyYrGy75z 

클래스 

참조형식의 사용자 정의타입 

모든 참조형식의 기본값은 null이다 

데이터, 기능을 정의 할수 있다

객체를 만들기 위한 파일 (설계도면)

붕어빵틀(클래스), 붕어빵(객체)로 비유 

<그림 1-1>

https://docs.microsoft.com/ko-kr/dotnet/csharp/fundamentals/types/classes

 

namespace가 있다면 내부에 정의 

클래스 파일 생성 .cs 

클래스 정의 

public class <클래스명> {

// Properties, Methods, Events, etc.

}

접근 제한자 : 외부에서 인스턴스 맴버에 접근 가능하도록 한다 

객체 = 인스턴스 : 클래스로 부터 실체화 (메모리에 할당)을 받은 것 

 

 

접근 제한자

private

클래스 내부에서만 접근이 가능합니다.

public 

모든 곳에서 해당 멤버로 접근이 가능합니다.

internal

같은 어셈블리에서만 public으로 접근이 가능합니다. 

protected

클래스 외부에서 접근할 수 없으나 파생 클래스에서는 접근이 가능합니다.

protected internal 

같은 어셈블리에서만 protected으로 접근이 가능합니다. 



 

생성자 메서드 

class내부에 선언된 특수한 메서드 

반환값이 없고 클래스명과 동일한 메서드 

클래스로부터 인스턴스 생성시 최초 호출된다 

using System;

public class Unit
{
    public Unit()
    {

    }
}

 

 

클래스로 객체(인스턴스)생성하기 

new라는 키워드를 사용해서 객체를 만든다 

using System;

class Program
{
    static void Main(string[] args)
    {
        new Unit();        
    }
}

 

 

생성된 클래스 인스턴스 (객체)는 값이다 

값은 다음과 같이 변수에 할당 할수 있다 

Unit unit = new Unit();

 

 

변수의 값은 Unit클래스의 인스턴스 (객체)이다 

변수를 통해 클래스의 맴버에 접근 가능하다 

즉, 객체의 데이터, 기능을 사용할수 있다 

 

 

Unit클래스에 멤버변수와 멤버메서드정의 

using System;

public class Unit
{
    //맴버 변수
    string name;

    public Unit()
    {
        Console.WriteLine("생성자");
    }

    void Move()
    {
        Console.WriteLine("이동합니다.");
    }
}

 

 

 

외부에서 접근 해보기 

.(dot)연산자 : 인스턴스의 맴버에 접근하는 연산자 

맴버 변수 name과 맴버 메서드 Move의 접근 제한자가 없다

접근 제한자가 없으면 기본 private다

외부에서 접근 불가 

 

 

 

public 접근 제한자를 붙여서 수정해본다 

using System;

public class Unit
{
    //맴버 변수
    public string name;

    public Unit()
    {
        Console.WriteLine("생성자");
    }

    public void Move()
    {
        Console.WriteLine("이동합니다.");
    }
}

인스턴스에 . 연산자를 이용해 멤버에 접근 가능하다 

using System;

class Program
{
    static void Main(string[] args)
    {
        Unit unit = new Unit(); //인스턴스 생성 
        unit.name = "마린";   //멤버 변수에 값 할당 
        unit.Move();    //메서드 호출 
    }
}

 

 

this

현재 인스턴스를 가르키는 키워드

클래스 내부에서 사용가능 

 

Move메서드를 수정해본다 

public void Move()
{
	Console.WriteLine("{0}이 이동합니다.", this.name);
}

 

 

메서드 오버로딩 

같은 이름의 메서드를 여러개 선언할수 있다 

단, 매개변수가 달라야 한다 

using System;

class Program
{
    static void Main(string[] args)
    {
        Unit unit = new Unit(); //인스턴스 생성 
        unit.name = "마린";   //멤버 변수에 값 할당 
        //unit.Move();    //메서드 호출
        unit.Move(1, 1);
    }
}
using System;

public class Unit
{
    //맴버 변수
    public string name;

    public Unit()
    {
        Console.WriteLine("생성자");
    }

    public void Move()
    {
        Console.WriteLine("{0}이 이동합니다.", this.name);
    }

    public void Move(int x, int y)
    {
        Console.WriteLine("{0}이 ({1},{2})로 이동합니다.", this.name, x, y);
    }
}

 

 

생성자 메서드 오버로딩 

using System;

class Program
{
    static void Main(string[] args)
    {
        Unit unit = new Unit("마린"); //인스턴스 생성 
        //unit.name = "마린";   //멤버 변수에 값 할당 
        //unit.Move();    //메서드 호출
        unit.Move(1, 1);
    }
}
using System;

public class Unit
{
    //맴버 변수
    public string name;

    public Unit()
    {
        Console.WriteLine("생성자");
    }

    public Unit(string name)
    {
        this.name = name;
        Console.WriteLine("{0}이 생성되었습니다.", this.name);
    }

    public void Move()
    {
        Console.WriteLine("{0}이 이동합니다.", this.name);
    }

    public void Move(int x, int y)
    {
        Console.WriteLine("{0}이 ({1},{2})로 이동합니다.", this.name, x, y);
    }
}

 

 

상속

클래스간 관계를 구축하는 방법 

부모 클래스를 상속받은 자식 클래스는 데이터와 기능을 상속 받는다 

자식 클래명 : (콜론)뒤에 부모 클래스이름을 적어준다 

class 부모 클래스
{
	// ...
}
class 자식 클래스 : 부모 클래스
{
	// 부모 클래스의 데이터와 기능 사용가능 
}

 

 

스타크래프트의 질롯은 유닛이다 

모든 유닛은 이름을 가지고있다

이처럼 상속을 받을때 공통점을 찾아내고 추상화 하는것이 일반적이다 

구체화는 구현 클래스 (자식)에서 한다 

using System;

public class Unit
{
    public string name;

    public Unit()
    {
        
    }
}
using System;

public class Zealots : Unit
{
    public Zealots()
    {

    }
}

 

 

 

질롯 인스턴스 만들기 

주의 : new라는 키워드 뒤에 클래스의 인스턴스가 만들어지는것

Unit클래스의 인스턴스가 아님 

using System;

class Program
{
    static void Main(string[] args)
    {
        Zealots zealots = new Zealots();
        zealots.name = "질롯1";
    }
}

 

 

하지만 

생성된 인스턴스의 타입은 다음과 같이 부모 클래스 타입이 될수 있다 

using System;

class Program
{
    static void Main(string[] args)
    {
        Unit zealots = new Zealots();
        zealots.name = "질롯1";
    }
}

 

 

 

업캐스팅 

자식에서 부모로 형변환

using System;

class Program
{
    static void Main(string[] args)
    {
        Zealots zealots = new Zealots();
        zealots.name = "질롯1";

        Unit unit = zealots;
        Console.WriteLine(unit);
        
    }
}

 

 

다운캐스팅 

부모에서 자식으로 형변환 

인스턴스가 무엇이냐에 따라 달라짐 

using System;

class Program
{
    static void Main(string[] args)
    {
        //불가능 
        //Unit unit = new Unit();
        //Zealots zealots = unit as Zealots;
        //Console.WriteLine("->" + zealots);

        //가능 
        Unit unit = new Zealots();
        Zealots zealots = unit as Zealots;
        Console.WriteLine("->" + zealots);

    }
}

 

 

base키워드

부모 멤버에 엑세스 할수 있게 하는 키워드

상속시 부모클래스의 생성자가 가장 먼저 호출된다 

다음 자식의 생성자가 호출됨

부모늬 오버로딩된 생성자 메서드를 자식에서 구현하고 자 할때 사용한다 

using System;

public class Unit
{
    public string name;

    public Unit(string name)
    {
        this.name = name;
    }
}
using System;

public class Zealots : Unit
{
    public Zealots(string name): base(name)
    {

    }
}
using System;

class Program
{
    static void Main(string[] args)
    {
        Zealots zealots = new Zealots("질롯1");
        Console.WriteLine("->" + zealots.name);

    }
}

 

 

 

virtual 키워드와 override

부모클래스에서 정의한 메서드를 자식클래스에서 재정의할때 사용

예를 들어 모든 유닛은 공격가능하다 

유닛을 상속받은 마린은 총으로, 파이어벳은 화염방사기로 공격하는것처럼 구현가능 

 

다음은 통합 모델링 언어(UML, 영어: Unified Modeling Language)로 구현한 클래스 다이어그램이다

이것은 소프트웨어 공학에서 사용되는 표준화된 범용 모델링 언어이다.

UML은 소프트웨어 집약 시스템의 시각적 모델을 만들기 위한 도안 표기법을 포함한다.

<uml>

using System;

public class Unit
{
    public string name;

    public Unit(string name)
    {
        this.name = name;
    }

    public virtual void Attack()
    {

    }
}
using System;

public class Marine : Unit
{
    public Marine(string name): base(name)
    {

    }

    public override void Attack()
    {
        //base.Attack();
        Console.WriteLine("총으로 공격합니다.");
    }
}
using System;

public class Firebat : Unit
{
    public Firebat(string name) : base(name)
    {

    }

    public override void Attack()
    {
        //base.Attack();
        Console.WriteLine("화염방사기로 공격합니다.");
    }
}
using System;

class Program
{
    static void Main(string[] args)
    {
        Marine marine = new Marine("마린1");
        Firebat firebat = new Firebat("파이어벳1");

        marine.Attack();
        firebat.Attack();
    }
}

 

 

 

 

 

구조체 

구조체 형식은 struct 키워드를 사용하여 정의한다 

데이터와 관련 기능을 캡슐화할 수 있는 값 형식이다

메소드, 필드, 속성등을 가질 수 있다

구조체에 생성자를 정의할 수 있지만 기본(Default) 생성자를 정의할 수 없다 

new 연산자를 이용하여 struct 객체를 생성할 수 있다 

다른 구조체나 클래스의 기본 구조체(상속하기 위한) 없다 

구조체 형식의 모든 인스턴스 필드가 액세스 가능한 경우, new 연산자 없이 인스턴스화할 수도 있습니다. 이 경우 인스턴스를 처음 사용하기 전에 모든 인스턴스 필드를 초기화해야 합니다

 

클래스와 차이점 

클래스는 참조유형이며 구조체는 값 형식 

구조체는 상속을 지원하지 않음 

구조체는 기본(디폴트) 생성자를 가질 없음 

 

using System;

public struct Coords
{
    public float x;
    public float y;

    public Coords(float x, float y)
    {
        this.x = x;
        this.y = y;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Coords c = new Coords();
        c.x = 10;
        c.y = 5;
        Console.WriteLine(c);
        Console.WriteLine("({0},{1})", c.x, c.y);
    }
}
public static class StructWithoutNew
{
    public struct Coords
    {
        public double x;
        public double y;
    }

    public static void Main()
    {
        Coords p;
        p.x = 3;
        p.y = 4;
        Console.WriteLine($"({p.x}, {p.y})");  // output: (3, 4)
    }
}

 

https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/builtin-types/struct

 

구조체 형식 - C# 참조

C#의 구조체 형식에 관한 자세한 정보

docs.microsoft.com

 

https://see-ro-e.tistory.com/133

반응형