C#/C# 교과서

[C# 교과서] 42~43. 클래스 기타, 상속으로 클래스 확장하기

서니션 2023. 1. 27. 23:57
728x90
반응형

부분 클래스

  • 클래스를 선언할 때는 partial 키워드를 붙여 CS 파일 여러개로 클래스를 분할하고, 컴파일할 때는 클래스 하나로 컴파일하도록 만들 수 있는 기능이 추가
// Hello 클래스의 첫 번째 파일 : FirstDeveloper.cs
using System;

namespace PartialClassDemo
{
	public partial class Hello
	{
		public void Hi() => Console.WriteLine("FirstDeveloper.cs");
	}
}

// Hello 클래스의 두 번째 파일 : SecondDeveloper.cs
using System;

namespace PartialClassDemo
{
	public partial class Hello
	{
		public void Bye() => Console.WriteLine("SecondDeveloper.cs");
	}
}

// PartialClassDemo.cs
namespace PartialClassDemo
{
	class PartialClassDemo
	{
		static void Main()
		{
			// Hello 클래스의 개체로 서로 다른 파일의 멤버들 호출 가능
			var hello = new Hello();
			hello.Hi();
			hello.Bye();
		}
	}
}
  • 실행하면 FirstDeveloper.cs SecondDeveloper.cs 의 결과가 나옴
  • 이처럼 부분 클래스를 사용하면 CS 파일 하나 또는 하나 이상에서 이름이 동일한 클래스를 만들고 관리 가능

부분 클래스를 사용하여 속성과 메서드 멤버를 나누어 관리

using System;

namespace PartialClass
{
	// 속성 멤버만 제공
	public partial class Person
	{
		public string Name { get; set; }
		public int Age { get; set; }
	}
	
	// 메서드 멤버만 제공
	public partial class Person
	{
		public void Print() => Console.WriteLine($"{Name} : {Age});
	}

	class PartialClass
	{
		static void Main()
		{
			Person person = new Person();

			person.Name = "C#";
			person.Age = 20;
			person.Print();
		}
	}
}

// 실행결과
// C# : 20

정적 클래스

static

  • static 키워드를 붙임
  • static 멤버만 가짐
  • 인스턴스화 될 수 없음
  • 유틸리티 클래스 용도로 사용
  • 팩터리 클래스

싱글톤

프로그램 내에서 인스턴스 개체 하나만 생성하는 클래스를 싱글톤이라고 함. 정적 클래스는 인스턴스화할 수 없으나, 싱글톤은 인스턴스화 함


필드에 public ?

필드는 클래스의 부품 역할을 하는데, 이왕이면 꽁꽁 숨기길 권장하므로 private으로 선언하는 것뿐


불변 형식

public class Circle
{
	public int Radius { get; private set; } = 0;
	public Circle(int Radius) => Radius = radius;
	public Circle MakeNew(int radius) => new Circle(radius);
}

...

// 특정 개체가 가지는 속성을 생성한 후 변경하지 않도록 설정
Circle circle = new Circle(10);

// 속성을 변경하려면 새로운 메서드로 새로운 개체를 만들어 사용
circle = circle.MakeNew(20);

상속

  • 재사용의 핵심 개념, 상속
  • C# 클래스 상속은 단일 상속만 지원
public class 기본클래스이름
{
	// 기본 클래스 멤버 정의
}

public class 파생클래스이름 : 기본클래스이름
{
	// 기본 클래스의 멤버를 포함한 자식 클래스의 멤버 정의
}
  • System.Object 클래스 : 모든 클래스의 부모 클래스, Object 클래스를 상속하는 코드는 생략 가능
  • 기본(base) 클래스 : 다른 클래스의 부모 클래스가 되는 클래스를 기본 클래스
  • 파생(derived) 클래스 : 다른 클래스의 자식 클래스가 되는 클래스를 파생 클래스

부모 클래스와 자식 클래스

using System;

namespace InheritanceDemo
{
	// 부모 클래스 선언
	class Parent
	{
		public void Foo() => Console.WriteLine("부모 클래스");
	}

	// 자식 클래스 선언
	class Child : Parent
	{
		public void Bar() => Console.WriteLine("자식 클래스");
	}

	class InheritanceDemo
	{
		static void Main()
		{
			// 자식 클래스의 인스턴스 생성
			var child = new Child();
			child.Foo();
			child.Bar();
		}
	}
}

// 결과
// 부모 클래스
// 자식 클래스
  • 콜론(:) 기호를 붙여 상속 관계를 설정
  • public, protected 멤버들을 상속해서 사용
  • 따로 선언하지 않고도 자식 클래스의 인스턴스를 생성한 후 부모 클래스의 멤버에 접근 가능

this와 this() 그리고 base와 base()

  • this는 자신
  • this() 자신의 생성자
  • base는 부모 클래스
  • base()는 부모 클래스의 생성자

base 키워드를 사용하여 부모 클래스의 생성자 호출

자식 클래스의 생성자에서 특정한 기능을 구현하지 않고 부모 클래스의 생성자에서 구현할 때는 자식 클래스의 생성자에서 바로 base() 코드를 사용하여 부모 생성자 호출 가능

using System;

namespace ConstructorBase
{
	class Parent
	{
		// 매개변수로 넘어온 값 출력
		public Parent(string msg) => Console.WriteLine(msg);
	}
	class Child : Parent
	{
		// base()를 사용하여 부모 클래스의 생성자 호출
		public Child(string msg) : base(msg) { }
	}
	class ConstructorBase
	{
		static void Main()
		{
			string msg = "전달";
			var child = new Child(msg);
		}
}

// 실행결과
// 전달

봉인 클래스

클래스를 만들었는데, 더 이상 다른 클래스에 상속되지 않게 할 때 사용되는 클래스를 봉인 클래스라고 함, sealed 키워드를 붙여 만든다

sealed class Cat : Animal {}

하면 class MyCat : Cat {} 하고 컴파일 할 때 바로 에러 발생함


추상 클래스

  • abstract
  • 일반적인 클래스들의 부모 역할을 하는 클래스, 즉 공통 기능들을 모아 놓은 클래스 역할
  • 다른 클래스에 상속을 준 후 추가 기능을 하위 클래스에 구현하도록 하는 강제성
  • 추상 클래스의 특징
    • 다른 클래스에 상속할 때 사용하는 클래스
    • 추상 클래스를 사용하여 개체를 만들 수는 없음. 즉, 추상 클래스와 뒤에서 나올 인터페이스는 인스턴스화 할 수 없음
    • 클래스를 설계할 때 부모 클래스 역할을 하면서 강제로 자식 클래스에 특정 멤버 이름을 물려줄 때 사용
    • 프로젝트를 작성할 대 멤버 이름을 맞추고 싶다면 추상 클래스에 먼저 정의한 후 자식 클래스에서 해당 멤버를 구현
    • 추상 클래스는 public 같은 액세스 한정자를 가짐
    • 추상 클래스는 멤버로 필드, 속성, 생성자, 소멸자, 메서드, 이벤트, 인덱서를 가짐

자식 클래스에만 멤버 상속하기

부모 클래스의 특정 멤버 중에서 자식 클래스에만 상속하려면 해당 멤버의 액세스 한정자를 public에서 protected로 설정


기본 클래스의 멤버 숨기기

부모 클래스에 만든 특정 메서드를 자식 클래스에서 새롭게 정의해 사용할 때는 new 키워드로 자식 클래스의 메서드를 정의

class Parent
{ public void Work() => Console.WriteLine("프로그래머"); }

class Child : Parent
{ // 기본 멤버 숨기기
	public new void Work() => Console.WriteLine("프로게이머"); }

var child = new Child(); // 자식 클래스의 인스턴스 생성
child.Work(); // 프로게이머 출
728x90
반응형