20.
[C#,닷넷교육]C#클래스,생성자,소멸자(CALSS,Constructor,Finalize),C#/ASP.NET/ADO닷넷/닷넷교육/닷넷강좌학원/닷넷공부/닷넷책/닷넷객체지향교육
------------
<!--[if !supportLists]-->1.
<!--[endif]-->기본 형태
------------
(internal)class MyClass {
...
}
class 앞에 아무것도 쓰지 않으면 기본적으로 클래스는 internal로 정의 된다, 즉 현재 프로젝트의 코드에서만 그
클래스에 접근이 가능(동일한 어셈블리 내에서만 접근가능)하다는 뜻이다. 참고로
public인 경우 다른 프로젝트에서도 접근이 가능하며 클래스인 경우 protected
(같은 클래스와 상속 받은 하위 클래스(파생 클래스)에서 접근이 가능)와
private(같은 클래스 내에서만 접근 가능)은 올 수 없다.(클래스 멤버인 경우 가능)
또한 아래처럼 클래스를 선언 시 public 이면서 abstract/sealed 인 것에 대해 동시에 정의가 가능하다.
public abstract class MyClass
또는 public sealed class MyClass
---------------
2. 상속/인터페이스
---------------
상속의 경우 :(콜론)으로 파생되었음을 표시한다. 여기서 주의 할 점은 C# 클래스는 오직 하나의 기반클래스(Base)만을 허용 한다는
것이다. 그리고 추상클래스를 상속 받은 경우에는 모든 추상멤버들을 모두 구현 해야 된다는
것이다.(파생 클래스 역시 추상 클래스인 경우는 예외임)
그리고 한가지 주의 할 점은 파생된 클래스(자식 클래스)가 기반 클래스보다 더 공개적일 수 없다는 것이다.
[다음의 경우는 유효]
public class
MyBase { .. }
internal
class MyDerieved : MyBase { … }
[다음의 경우는 컴파일 되지 않는다.]
internal
class MyBase { … }
public class
MyDerieved : MyBase { … }
만약 기반클래스(Base Class)를 써주지 않으면
암시적으로 System.Object(C#에서의 별칭은
object)를 상속하게 된다. 궁극적으로 모든 클래스들은
System.Object에 뿌리를 두게 되는 것이다.
클래스가 지원하는 인터페이스(Interface) 역시 콜론(:) 을 통해 지정된다. 기반클래스와 인터페이스가 모두 존재하는
클래스라면 반드시 기반 클래스를 먼저 쓰고 쉼표 다음에 인터페이스 이름을 써 준다. 기반클래스는 없고
인터페이스만 있다면 콜론 바로 다음에 인터페이스 이름을 써 주면 된다.
public class MyClass : MyBase, IMyInterface
{
public class MyClass: ICompare {
아래는 잘못된 경우이다.
public class MyClass: IMyInterface, MyBase
{
어떤 인터페이스를 지원(구현)하는 클래스는 그 인터페이스의 모든 멤버들을 구현 해야 한다. 만일
아무 할 일도 없는 멤버라면 비어있는 것이라도 만들어야 한다.
인터페이스를 정의하는 방식은 interface라는 키워드를 사용
한다는 점을 제외하면 클래스 정의와 거의 동일하다. 즉 아래와 같은 형태이다.
interface IMyInterface {
물론 public, internal 한정자 들은 클래스를 정의 할
때와 동일한 의미를 가진다.
또한 abstract 와
sealed는 쓰이지 않는다. 원래 인터페이스는 구현을 담지 않으므로 abstract는 의미가 없으며 , 상속되지 않으면 의미가
없으므로 sealed도 사용되지 않는다.
인터페이스는 인스턴스화 할 수 없으며 다중상속이 가능하다.(이점은
클래스와 다르다.)
public interface MyInterface:
IMyBaseInterface1, IMyBaseInterface2 {
[아래의 예제를 따라 해 보자.]
<!--[if !supportLists]-->1.
<!--[endif]-->Visual Studio .Net을 통해
새로운 콘솔 응용 프로그램을 만들자.
<!--[if !supportLists]-->2.
<!--[endif]-->아래와 같이 빈 클래스와 메인을 만들자.
using System;
namespace Exam1
{
public abstract class
MyBase
{
}
internal class MyClass: MyBase
{
}
public interface IMyBaseInterface
{
}
internal interface IMyBaseInterface2
{
}
internal interface IMyInterface: IMyBaseInterface,
IMyBaseInterface2
{
}
internal sealed class
MyComplexClass: MyClass, IMyInterface
{
}
/// <summary>
/// Class1에
대한 요약 설명입니다.
/// </summary>
class
Class1
{
/// <summary>
/// 해당
응용 프로그램의 주 진입점입니다.
/// </summary>
[STAThread]
static void Main(string[]
args)
{
//
// TODO:
여기에
응용 프로그램을 시작하는 코드를 추가합니다.
//
MyComplexClass obj = new MyComplexClass();
Console.WriteLine(obj);
//ToString() 메서드는 System.Object로부터 상속된 메소드들중 하나로서 개체의 클래스 이름을 하나의 string으로 돌려준다.
Console.WriteLine(obj.ToString());
}
}
}
------------------
<!--[if !supportLists]-->3.
<!--[endif]-->생성자와 소멸자
------------------
C#에서 클래스를 정의 할 때 생성자와 소멸자를 정의하지 않아도
되는 경우가 있다. 기반 클래스 System.Object가
기본 구현을 해 주기 때문이다. 그러나 좀 더 세밀한 초기화나 해제가 필요하다면 생성자(Constructor)와 소멸자(Deconstructor)를 직접
정의 해야 한다.
여기서 생성자란 클래스와 동일한 이름을 가지는 메소드 이다.
class MyClass {
public MyClass() {
}
}
위의 예에서와 같이 생성자는 클래스와 동일한 이름을 가지며 매개변수를 받지 않는다. 이러한 생성자를 기본 생성자(Default
Constructor)라고 한다. 접근성이 public
이므로 외부에서 이 생성자를 이용하여 클래스의 객체를 생성 할 수 있다. 전용
생성자(private constructor)인 경우에는 외부에서 이 클래스의 객체를 생성 할 수
없음을 의미한다. 매개변수를 가진 생성자도 정의 할 수 있는데 이를 비 기본 생성자라고 한다.
class MyClass {
public MyClass (){…}
public MyClass(int i) {..
}
}
또한 한 클래스가 가질 수 있는 생성자의 수에는 제한이 없다.
소멸자(Deconstructor)는 약간 다른 모양을 한다. .NET에서 쓰이는 (System.Object가 제공하는) 소멸자는 Finalize 이지만 소멸자를 선언 할 때는 이
명칭을 사용하는 것이 아니라 아래와 같이 선언한다.
class MyClass {
~MyClass() { … }
}
소멸자는 가비지 컬렉션이 발생할 때 수행되며 주로 자원들의 해제를 담당 한다.
소멸자가 호출된 후에는 암시적으로 기반 클래스들의 소멸자가 호출되어 궁극적으로 상속 구조의 최상위에 있는 System.Object의 Finalize가 호출된다.
파생된 클래스가 인스턴스화 되기 위해서는 먼저 기반클래스가 먼저 인스턴스화 되어야 한다. 그러다 보면 결국 System.Object까지 올라가게
된다. 따라서 어떤 클래스를 인스턴스화 한다고 할 때 가장 먼저
System.Object.Object() 가 제일 먼저 호출된다.
[아래의 예문을 통해 생성자의 호출 순서를 이해하자.]
public class MyBaseClass {
public MyBaseClass()
{…}
public MyBaseClass(int i)
{…}
}
public class MyClass: MyBaseClass
{
public MyClass() {…}
public MyClass(int i)
{…}
public MyClass(int I, int j)
{…}
}
만약 아래와 같이 한다면
# MyClass m = new MyClass();
<!--[if !supportLists]-->-
<!--[endif]-->실행순서 :
System.Object.Object(), MyBaseClass.MyBaseClass(), MyClass.MyClass()
MyClass m = new MyClass(5);
<!--[if !supportLists]-->-
<!--[endif]-->실행순서 :
System.Object.Object(), MyBaseClass.MyBaseClass(int i), MyClass.MyClass(int
i)
//아래의 경우 상위 클래스에는 인자가 두 개인 것이 없으므로 기본
생성자가 호출 됨
MyClass m = new MyClass(5, 6);
<!--[if !supportLists]-->-
<!--[endif]-->- 실행순서 : System.Object.Object(), MyBaseClass.MyBaseClass(),
MyClass.MyClass(int i, int j)
질문 ? 만약 다음과 같은 생성자가 수행 되게 할려면 어떻게
할까?
<!--[if !supportLists]-->a.
<!--[endif]-->System.Object.Object()
<!--[if !supportLists]-->b.
<!--[endif]-->MyBaseClass.MyBaseClass(int
i)
<!--[if !supportLists]-->c.
<!--[endif]-->MyClass.MyClass(int I, int
j)
MyClass의 MyClass(int I, int j) 생성자를 수정하면
된다.
즉 아래와
같이 하면 된다.
public class MyClass: MyBaseClass
{
public MyClass() {…}
public MyClass(int i)
{…} //이때
base(i)에는 숫자 리터럴도 가능하다.
public MyClass(int I, int j) :
base(i) {…}
}
물론 base 키워드 이외에 자기 자신의 다른 생성자를 부르기
위한 this도 있다. 만약
MyClass와 그 상위 클래스가 다음과 같다면...
public class MyBaseClass {
public MyBaseClass()
{…}
public MyBaseClass(int i)
{…}
}
public class MyClass: MyBaseClass
{
public MyClass() : this(5,
6){…}
public MyClass(int i)
{…}
public MyClass(int I, int j) :
base(i) {…}
}
MyClass m = new MyClass()
실행 순서는 다음과 같다.
System.Object.Object(), MyBaseClass
.MyBaseClass(int i), MyClass .MyClass(int I, int j), MyClass.
MyClass()
[실습]
아래 클래스를 설계하고 구현 하시오.
Polygon이란?
-A regular polygon is one in which all the
sides have the same length and all of the interior angles are equal. For
example, a square is a regular polygon.
- Polygon class에서 제공되어야 하는 method.
area(), which returns the area of the
polygon;
perimeter(), which returns the distance
around the polygon;
- Polygon class를 설계하라. 추상화 시킬 필요가 있는 함수는 추상화 하고 하위 클래스에서 구현하도록 하자.
- Polygon class를 상속해서 triangle 과square클래스를 설계하고 main함수를 통해 객체를 생성하고 Test해 보라.
- Polymorphism이 제공해 주는 이점에 대해 생각해
보라.
댓글 없음:
댓글 쓰기