구조체와 클래스
클래스의 구성 요소
접근 제한자
프로퍼티 (Property)
🍊 집을 지키는 경비원이라고 생각하면 쉽게 이해 가능 :
- 직접 집 안(필드)에 들어가지는 못하고, 경비원에게 부탁해 물건을 가져오거나 넣어달라고 요청해야 함.
- 경비원(프로퍼티)은 요청을 처리하고, 필요한 경우 집에 있는 물건(필드)을 수정하거나 가져다줄 수 있음.
프로퍼티를 쓰는 이유
get
만 설정하는 식으로 읽기 전용 프로퍼티로 만들 수 있음. (반대의 경우도 가능)정적 할당과 동적 할당
.NET
사용시 가비지 컬렉터가 자동으로 정리해줌)특징 | 정적 할당 | 동적 할당 |
---|---|---|
크기 | 고정됨 | 유동적 (실행 중에 변경 가능) |
메모리 위치 | 스택(Stack) | 힙(Heap) |
성능 | 빠름 (컴파일 타임에 관리) | 느림 (런타임에 관리) |
메모리 관리 | 자동으로 정리 | 직접 해제하거나 가비지 컬렉터 의존 |
유연성 | 제한적 | 매우 유연함 |
상속의 특징
//부모 클래스
public class Animal
{
public string Name { get; set; }
public int Age { get; set; }
}
//자식 클래스 1
public class Dog : Animal
{
public void Bark()
{
Console.WriteLine($"{Name} is bark");
}
}
//자식 클래스 2
public class Cat : Animal
{
}
static void Main(String[] args)
{
//부모 클래스에 Name이 있기 때문에
//따로 선언하지 않아도 Name 이용 가능
Dog dog = new Dog();
dog.Name = "Bobby";
dog.Age = 3;
dog.Bark();
}
[결과]
Bobby is bark
//부모 클래스
public class Animal
{
public string Name { get; set; }
public int Age { get; set; }
public void Eat()
{
Console.WriteLine("Animal is eating.");
}
}
//자식 클래스 1
public class Dog : Animal
{
//부모 클래스의 메서드 재정의
public void Eat()
{
Console.WriteLine($"{Name} is eating.");
Console.WriteLine($"{Name} looks very happy!");
}
}
//자식 클래스 2
public class Cat : Animal
{
}
static void Main(String[] args)
{
Dog dog = new Dog();
dog.Name = "Bobby";
dog.Age = 3;
dog.Eat(); //Dog에서 재정의한 Eat()이 실행됨
}
[결과]
Bobby is eating.
Bobby looks very happy!
다형성
가상 메서드
, 추상 메서드
, 오버라이드
와 오버로딩
이 있다.가상 메서드를 사용해야 하는 이유
List<Animal> animalList = new List<Animal>();
animalList.Add(new Dog());
animalList.Add(new Cat());
foreach (Animal animalList in list)
{
animalList.Eat();
}
[결과]
Animal is eating.
Animal is eating.
가상 메서드
가 필요하다.가상 메서드(Virtual Method)
virtual
을 붙임으로서 날 상속한 자식들이 재정의 할 수 있는 메서드인 것을 미리 알려줄 수 있음.override
를 붙여줌으로서 내가 이 메서드를 재정의 했음을 알려주어야 함.//부모 클래스
public class Animal
{
public string Name { get; set; }
public int Age { get; set; }
//자식들이 재정의를 할 수도 있다고 virtual로 알려줌
public virtual void Eat()
{
Console.WriteLine("Animal is eating.");
}
}
//자식 클래스 1
public class Dog : Animal
{
//재정의 한 메서드임을 override로 알려줌
public override void Eat()
{
Console.WriteLine($"{Name} is eating.");
Console.WriteLine($"{Name} looks very happy!");
}
}
//자식 클래스 2
public class Cat : Animal
{
}
static void Main(String[] args)
{
List<Animal> animalList = new List<Animal>();
animalList.Add(new Dog());
animalList.Add(new Cat());
foreach (Animal animalList in list)
{
animalList.Eat();
}
}
[결과]
Bobby is eating.
Bobby looks very happy!
Animal is eating.
추상클래스와 메서드 (Abstract Class, Abstract Method)
abstract
키워드를 사용하여 선언되며, 추상 메서드를 포함할 수 있다.가상메서드와 추상메서드의 차이
오버라이딩과 오버로딩
오버라이딩
오버로딩
“ ”
를 통해 문자열을 직접 입력한다던가, +
를 이용해 둘 다 넣는다던가… 모두 오버로딩이 되어있기 때문에 사용할 수 있는 것.제너릭(Generic)
<T>
형태의 키워드를 이용하여 제너릭을 선언.<T>
대신 구체적인 자료형을 넣어준다.class Stack<T>
{
private T[] elements;
private int top;
public Stack()
{
elements = new T[100];
top = 0;
}
public void Push(T item)
{
elements[top++] = item;
}
public T Pop()
{
return elements[--top];
}
}//Stack<T>
static void Main(String[] args)
{
Stack<int> intStack = new Stack<int>();
intStack.Push(1);
intStack.Push(2);
intStack.Push(3);
Console.WriteLine(intStack.Pop());
Stack<string> stringStack = new Stack<string>();
stringStack.Push("하나");
stringStack.Push("둘");
stringStack.Push("셋");
Console.WriteLine(stringStack.Pop());
}//Main
[결과]
3
셋
List<int> numbers = new List<int>();
Dictionary<string, int> scores = new Dictionary<string, int>();
Stack<int> stack1 = new Stack<int>();
Queue<int> queue1 = new Queue<int>();
특징 | ref | out |
---|---|---|
초기화 여부 | 호출 전에 반드시 초기화해야 함 | 호출 전에 초기화할 필요 없음 |
메서드 내 초기화 여부 | 초기화는 선택 사항 | 반드시 초기화해야 함 |
사용 목적 | 값을 수정하고 다시 가져올 때 사용 | 값을 전달받기 위해 사용 |
이름 ‘Console.WriteLine’이(가) 현재 컨텍스트에 없습니다.
abstract
를 이용한 실습 중이었는데, 다음과 같은 오류가 일어남.