Archive

0905 FackCraft

피곤핑 2019. 9. 5. 16:51

visualstudio code 설치~~~~

 - IDE가 아니라 Text 편집기임! 그렇지만 거의 만능 IDE처럼 쓰여지고 있음!

오른쪽 하단의 인스톨 누르기

 +) .Net core를 깔아야 c#을 프로그래밍 할 수 있는데 우선 .NET core 3.0의 설명이 선행되야 하기때문에 다음시간에 하도록 하겠음!

 (dotnet blog ㄱ ㅏ거의 최신 소식들을 올리고 있음!!!! 이런걸 잘 보기... )

 

 ~~~ 보류합시다 

 

다시 visual studio 2019로갑시다


property를 잘 압시다 - 얘는 괄호없이 마치 멤버변수처럼 보임

public int HP
{
    get
    {
    }
    set
    {
    }
}
int hp = m.HP; -> getter로 들어감
m.HP = 3; -> setter로 들어감

** auto property - 컴파일러가 이상한 이름으로 자동으로 만들어줌 그래서 auto - 안쓸 이유가 전혀 없음

// auto property
public int HP2 {get;set;}
m.HP2 = m.HP2 + 1;

 

<단축키>

ctor + tab -> 생성자 만들기

prop + tab -> 프로퍼티 만들기


[타입 추론 기능]

- (나중에 타입을 정확히 표기할 수 없는 익명타입기능이 있는데 이때 쓰임)

Dictionary<int, List<string> dict = new Dictionary<int, List<string>>();

여기서 우리는 타입을 추론 할 수있기 때문에 Dictionary라는 타입을 굳이 쓰지않고, 

var dict = new Dictionary<int, List<string>>();

이런식으로 var로 쓸 수있음! 


스태틱 함수에는 스태틱 멤버만 접근 가능

 - TakeRandomDamageForMarine 함수를 static으로 만들다 보니 Random객체도 static으로 선언해주는데 헷갈리지 않도록 _random으로 변수명을 바꿔줌

static Random _random = new Random(); // 멤버변수일때는 _를 붙여서 헷갈리지않도록

static void TakeRandomDamageForMarine(Marine marine)
{
    int davage = _random.Nex(1,6);
    
    while(damage > 0)
    {
        damage--;
        marine.HP--;
    }
    
    Console.WriteLine(marine.ToText());
}

사실 이때, marine이든 firebat이든 무엇이 들어오는지만 정해주면 함수의 내용은 변하지 않기때문에 이를 또 추상클래스로 만들어주는 논리로직을 짜야함! (아래와 같은상황!!)

static void Main(string[] args)
        {
            Marine m1 = new Marine();
            Firebat f1 = new Firebat();

            TakeRandomDamageForMarine(m1);
            TakeRandomDamageForFirebat(f1);
        }

        static void TakeRandomDamageForMarine(Marine marine)
        {
            int damage = _random.Next(1, 6);

            while (damage > 0)
            {
                damage--;
                marine.HP--;
            }

            Console.WriteLine(marine.ToText());
        }

        static void TakeRandomDamageForFirebat(Firebat firebat)
        {
            int damage = _random.Next(1, 6);

            while (damage > 0)
            {
                damage--;
                firebat.HP--;
            }

            Console.WriteLine(firebat.ToText());
        }

위에 코드를 객체지향적으로 바꿔보자

firebat + marine = unit

 

객체지향의 대원칙 - 부모자리에 자식을 대입할 수 있음!

 객체지향을 왜? - 추상화시키기위해 - 왜? - 코드중복성이 줄어드니까 - 복잡도가 감소

 

is-a -> 상속

 ex) Marine is an Unit.

 

has-a -> 합성

 ex) Marine has a Gun.

class Gun {}

class Marine : Unit {
    public Gun _gun;
}

 

Unit.cs

namespace FakeCraft
{
    class Unit
    {
        public int HP { get; set; }
    }
}

Marine.cs

namespace FakeCraft
{
    class Marine : Unit
    {
        public Marine()
        {
            HP = 50;
        }

        public string ToText()
        {
            return $"I am a marine and I hava {HP} HP(s)";
        }
    }
}

 

이제 위와같은 코드에서 ToText()를 유닛으로 올릴것인데 여기서 가상 메소드를 사용할 것임

1. 부모클래스에 virtual을 사용한 가상함수 만든다.

2. 자식클래스에 있는 똑같은 함수의 이름을 override 해줌.!

 

Unit.cs (virtual + return null;)

namespace FakeCraft
{
    class Unit
    {
        public int HP { get; set; }

        public virtual string ToText()
        {
            return null;
        }
    }
}

Marine.cs (override 추가)

namespace FakeCraft
{
    class Marine : Unit
    {
        public Marine()
        {
            HP = 50;
        }

        public override string ToText()
        {
            return $"I am a marine and I hava {HP} HP(s)";
        }
    }
}

* 아래와 같은경우에 둘은 전혀 연관이 없어보임.

부모가 같다는건 연관성이 있는게 아니라 계층관계가 나타나야 연관성이 있다고 보여짐!

Marine m1 = new Marine();
Firebat f1 = new Firebat();

 +) Marine의 리스트, firebat의 리스트를 만들것이 아니라 Unit의 리스트를 만들어야함 -> 추상성

 - 같은 타입의 collection을 만들 수 있음!!! -> 일반화 시켜서 최대한 두루뭉실한 쪽으로 간주하는 법

List<Unit> units = new List<Unit>();
units.Add(new Marine());
units.Add(new Marine());
units.Add(new Firebat());

// for문보다 더 세련된 for-each문을 사용하기
foreach (Unit unit in units)
{
	TakeRandomDamage(units[i]);
}

 

 * 종단점을 찍어보았을때 자식의 ToText() 함수의 리턴값에 값을 찍으면 디버깅했을때 멈추고 출력되는데 

virtual 함수의 리턴값에 점을 찍어보면 아예 멈추지 않고 실행됨을 볼 수 있음!

 -> 그러면 아예 return null; 값이 필요없는게 아닐까? - 호출이되면 안되는코드

 -> 그렇다면, 그럴때 아예 abstract로 추상 메소드로 만들어도됨

public abstract string ToText();

 -> 그리고 Unit 클래스 또한 abstract class가 되어야함!

 -> 그리고 이렇게 되어버리면 Unit u = new Unit(); 가 생성이 되지않게됨! 그전에는 그냥 코드상으로만 가능하게됨


 => 그렇다면 어떤경우가 virtual로 만들었을때 알맞을까? 

// Unit.cs

public void TakeDamege(int damege)
{
    while(damege < 0)
    {
        damege--;
        HP--;
    }
}

 +) 새로운 질럿의 출현!

 * 쉴드가 47이 되어야하는데 지금 부모에게 TakeDamage가 있기때문에 97이 되었음을 볼수있음

-> 이때 가상함수가 필요함

이때,  (+virtual = 기본 구현은 제공하고 있고 필요에 따라서 이를 바꿔줄 수 있음)

 -> 그리고 Zealot에서 TakeDamage를 override하고 여기서 따로 함수를 정의해줌!

 (이때, base 는 부모의 함수를 사용한다는 문법임)

 

 * 기본구현이 있다면 이때는 가상

   하지만 애당초 구현을 가질 수 없을때에는 추상

 

- 이 코드는 상황에따라 안쓸 수도 있고 while 위아래로 들어갈 수도 있음!

base.TakeDamage(damage);

 

파이썬의 경우 virtual이 무조건 자동으로 붙어있고 override가 자동으로 붙어있음

파이썬 decorate을 붙여서 만드는건데 어떤 키워드를 붙여서 할지 ..... 찾아보셈,,,,,,,,,