1장 비주얼 C#과 만남

Download Report

Transcript 1장 비주얼 C#과 만남

7장 상속부터 인터페이스까지
상속성
다형성과 가상 메서드
abstract 클래스와 인터페이스
상속성

상속성이란



상속성(Inheritance)이란, 기존에 정의한 객체가 가지는 특성을
그대로 물려받아 새로운 객체를 정의하는 것
상속이란 두 개의 클래스간의 관계를 정의하는 특성
상속 관계에 있는 클래스를 베이스 클래스와 상속받은 클래스라
고 정의



베이스(base) 클래스 - 이미 정의해놓은 클래스
상속받은(derived) 클래스 - 기존 클래스를 상속받아서 새로 정의
한 클래스
상속 구현

모든 클래스는 베이스 클래스를 가질 수 있으며, 다른 클래스에
게 상속될 수 있다
상속성

상속 구현


Class1 클래스를 상속받아 Class2 클래스를 선언한 예
상속받은 클래스에서는 마치 베이스 클래스의 모든 멤버를 정
의해놓은 것처럼 그대로 가져다 쓸 수 있다
상속성

상속 구현

Point 클래스를 상속받아 Point3D 클래스를 정의한 경우, 상속받은
클래스에서 베이스 클래스 멤버를 자기 멤버인양 쓸 수 있다
상속 클래스 예제
①
Point 클래스를 정의하고, 이 클래스를 상속받아 Point3D
클래스를 정의해보는 예제
프로젝트 유형 : 콘솔 응용 프로그램
프로젝트 이름 : Inherit
상속 클래스 예제
② x,y 필드와 SetPoint 메서드, Draw 메서드를 정의하고,
Draw 메서드는 x, y 필드 값을 보여주도록 구현
class Point
{
public int x;
public int y;
// x,y 필드
public void SetPoint( int x, int y ) // SetPoint 메서드
{
this.x = x;
this.y = y;
}
}
public void Draw() // Draw 메서드
{
Console.WriteLine( "({0},{1})", x, y );
}
상속 클래스 예제
③ Point3D 클래스는 Point 클래스를 상속받아 정의하고,
z 멤버만 하나 더 추가
// Point 클래스 상속
class Point3D : Point
{
public int z;
}
④ Main 메서드에서 Point3D 객체를 생성하고 Draw 메서
드를 호출
class Class1
{
static void Main(string[] args)
{
Point3D pt3d = new Point3D(); // Point3D 객체 생성
}
}
pt3d.Draw(); // Point 클래스의 Draw()
상속 클래스 예제
⑤ pt3d를 입력하고, ‘.’을 입력하면, Point3D 객체에서 사
용할 수 있는 멤버 리스트를 보여준다
메서드 재정의 예제
①
상속받은 클래스에서 베이스 클래스의 멤버를 재정의하는
방법을 알아보는 예제
프로젝트 유형 : 콘솔 응용 프로그램
프로젝트 이름 : InheritNew
메서드 재정의 예제
② Point 클래스를 정의하고 Draw 메서드를 정의
class Point
{
public int x; // x,y 필드
public int y;
public void SetPoint( int x, int y ) // SetPoint 메서드
{
this.x = x;
this.y = y;
}
}
public void Draw() // Draw 메서드
{
Console.WriteLine( "({0},{1})", x, y );
}
메서드 재정의 예제
③ Point3D 클래스를 정의하고, SetPoint 메서드와 Draw
메서드를 정의
class Point3D : Point
{
public int z;
public void SetPoint( int x, int y, int z )
{
SetPoint( x, y ); // base class 멤버를 부른다.
this.z = z;
}
}
public new void Draw() // 메서드 재정의, new 키워드
{
Console.WriteLine( "( {0}, {1}, {2} ) ", x, y, z );
}
메서드 재정의 예제
④ Point 클래스와 Point3D 클래스를 생성하고, 각각
Draw 메서드를 호출
class Test
{
static void Main()
{
Point pt = new Point(); // Point 클래스
pt.SetPoint( 10, 20 );
pt.Draw();
}
}
Point3D pt3d = new Point3D(); // Point3D 클래스
pt3d.SetPoint( 100, 200, 300 );
pt3d.Draw();
base 키워드 예제
①
상속받은 클래스에서 베이스 클래스의 멤버를 사용할 때,
base 키워드를 사용해보고 생성자를 정의해보는 예제
프로젝트 유형 : 콘솔 응용 프로그램
프로젝트 이름 : InheritBase
base 키워드 예제
② 상속받은 클래스에서 베이스 클래스의 Draw 메서드를
부르려면 다음과 같이 base 키워드를 이용
class Point
{
public void Draw() // Draw 메서드
{
Console.WriteLine( "Point.Draw()“ );
}
}
class Point3D : Point
{
public new void Draw() // Draw 메서드 재정의
{
base.Draw(); // Point.Draw()
}
}
Console.WriteLine( "Point3D.Draw()“ );
상속받은 클래스
에서 베이스 클래
스에 정의된 멤버
를 사용할 때 base
키워드를 사용
base 키워드 예제
③ 상속받은 클래스에 생성자를 정의할 때, 베이스 클래스
의 생성자를 불러서 값을 초기화
class Point
{
public Point( int x, int y )
{
}
...
}
베이스 클래스 생성
자를 부를 때 base
키워드를 사용
class Point3D : Point
{
public Point3D( int x, int y, int z ) : base( x, y )
{
}
...
}
상속성

sealed 클래스



sealed 클래스는 다른 객체가 이 클래스를 상속받지 못하도록
할 때 사용
더 이상 클래스를 상속받아 쓸 수 없도록 닫아버리는 것
sealed 클래스를 상속받아 클래스를 정의하려고 하면 컴파일 오
류가 발생
public sealed class Base
{
...
}
// sealed 클래스는 상속받을 수 없습니다.
class Derived : Base
{
...
}
상속성

protected 멤버
멤버 접근 제어는 클래스 외부에서 멤버를 사용할 때 적용되는
규칙




{
}
private 멤버는 클래스 외부에서 사용하는 것을 허용하지 않는 멤버
public 멤버는 외부 어디서나 자유롭게 사용하도록 허용한 멤버
protected 멤버는 자신을 상속받은 클래스에게 사용할 수 있도록
권한을 부여
public BaseObj
protected void Move() // protected 멤버
{
}
상속성

protected 멤버


상속받은 클래스는 베이스 클래스의 protected 멤버와 public
멤버를 사용할 수 있다.
protected 멤버는 상속받은 클래스에게 접근 권한을 준 것이기
때문에, 클래스 외부에서는 사용할 수 없는 멤버
가상 메서드

다형성



다형성은 상속 관계를 갖는 클래스에 적용할 수 있는 객체 프로그
래밍의 한 특성으로, 하나의 객체가 여러 가지 특성을 가지는 것을
의미
클래스마다 각각 고유한 기능을 구현하고, 가상 메서드를 통해서
다양한 기능을 호출
가상 메서드를 통해서 Point 클래스에 정의된 Draw 메서드를 호출
DrawObj obj = new Point();
obj.Draw();
가상 메서드

가상 메서드


메서드를 가상 메서드로 만드는 방법은 함수 앞에 virtual 이라고
명시
상속받은 클래스에서 가상 메서드를 다시 정의할 때는 override
키워드를 사용
가상 메서드 예제
①
베이스 클래스에 가상 메서드를 정의하고, 상속받은 클래
스의 메서드를 불러보는 예제
프로젝트 유형 : 콘솔 응용 프로그램
프로젝트 이름 : Virtual
가상 메서드 예제
② DrawObj 클래스에 Draw 가상 메서드를 정의하고,
Point 클래스에는 Draw 메서드를 구현
class DrawObj
{
public virtual void Draw() // 가상 메서드
{
Console.WriteLine( "DrawObj.Draw()");
}
}
class Point : DrawObj
{
public int x; // x, y 필드
public int y;
public Point( int x, int y ) // 생성자
{
this.x = x;
this.y = y;
}
public override void Draw() // 메서드 구현
{
Console.WriteLine( "( x, y ) = ({0},{1})", x, y );
}
}
가상 메서드 예제
③
DrawObj 클래스에 정의된 가상 메서드를 통해서
Point 클래스의 Draw 메서드를 호출
class Class1
{
static void Main(string[] args)
{
DrawObj obj = new Point( 100, 200 );
obj.Draw();
}
}
④ DrawObj 객체 선언한 참조 변수를 통해서 Point 객체
의 Draw 메서드를 부른 결과
가상 메서드 예제
⑤ DrawObj 클래스에서 virtual 키워드 없애고 다시 예제
를 실행
abstract 클래스

abstract 클래스


abstract 클래스는 아무런 기능이 없는 객체를 생성해서 쓰는 것
을 방지
abstract 클래스는 객체 그 자체로는 인스턴스 객체를 생성할 수
없으며, 다른 객체가 상속받은 경우에만 가능
abstract 클래스

abstract 클래스

abstract 클래스를 생성하려고 하면 컴파일 오류가 발생
static void Main()
{
// 단독으로 객체를 생성할 수 없음.
DrawObj obj = new DrawObj();
}

abstract 클래스는 상속받은 다른 클래스를 대신할 때 사용하며,
상속받은 객체를 생성하고 레퍼런스 변수에 넣어두는 용도로 사
용
static void Main()
{
// abstract 클래스
DrawObj obj = new Point( 100, 200 );
}
abstract 클래스

abstract 메서드


DrawObj 객체의 Draw 가상 메서드는 상속받은 클래스에 있는 실
제 Draw 메서드를 부르기 위한 것
abstract 키워드를 붙여서 메서드를 선언만 하는 것이며, 실행 코
드는 구현하지 않는다
abstract class DrawObj
{
// abstract 메서드
public abstract void Draw();
}
상속받은 클래스에서 abstract 메서드를 구현하지 않으면, 컴파일러 오류가 발생
error CS0534: 'Point' does not implement inherited abstract member'DrawObj.Draw()'
abstract 클래스

abstract 클래스 상속
virtual 키워드를 사용하는 대신 abstract 클래스와 메서드를 사용
한예

using System;
abstract class DrawObj // abstract 클래스
{
}
public abstract void Draw(); // abstract 메서드
class Point : DrawObj
{
public override void Draw() // Draw 메서드를 정의하지 않으면 컴파일 오류
{
}
}
Console.WriteLine( "Point.Draw()“ );
class Test
{
static void Main()
{
DrawObj obj = new Point();
obj.Draw(); // Point.Draw 메서드를 부른다.
}
}
인터페이스

인터페이스란

인터페이스(interface)란 상속받은 클래스에서 반드시 구현해 주
어야할 기능을 명시하고 나열할 때 사용
실제 기능은 인터페이스를 상속받은 객체에 구현

인터페이스(interface)는 다음과 같이 선언

인터페이스

인터페이스 구현

abstract 클래스를 인터페이스로 선언한 예
인터페이스 선언은 class 대신 interface라고 표현

인터페이스(interface)는 다음과 같이 선언

// 인터페이스 정의
interface IDrawObj
{
void Draw();
void Move( int sx, int sy );
}
인터페이스 이름은 “I”
알파벳으로 시작하도록
하여, “I"를 넣어줌으로
서 “인터페이스를 상속
받는구나“라는 것을 쉽
게 구분할 수 있도록 하
기 위한 것
인터페이스

인터페이스 구현



인터페이스는 단순히 기능을 나열한 것이며, 실제 기능 구현은 상
속받은 클래스에서 작성
인터페이스를 상속받은 경우, 인터페이스에 명시된 모든 메서드
를 구현해주어야 한다
abstract 클래스와 달리, 인터페이스를 상속받은 경우에는
override 키워드를 쓰지 않는다
class Point : IDrawObj
{
public void Draw()
{
// 그리는 기능 구현
}
public void Move( int x, int y )
{
// 이동 기능 구현
}
}
인터페이스 예제
①
인터페이스를 정의하고, 상속받아 클래스를 정의해보는 예
제
프로젝트 유형 : 콘솔 응용 프로그램
프로젝트 이름 : Interface
인터페이스 예제
② IDrawObj 인터페이스를 추가하고, Draw 메서드와
Move 메서드를 정의
interface IDrawObj
{
void Draw();
void Move( int x, int y );
}
인터페이스 예제
③ IDrawObj 인터페이스를 상속받아 Point 클래스를 정의
class Point : IDrawObj
{
public int x;
public int y;
public Point( int x, int y )
{
this.x = x;
this.y = y;
}
public void Draw() // 그리는 기능 구현
{
Console.WriteLine( "Draw() : ( {0}, {1} ) ", x, y );
}
}
public void Move( int x, int y ) // 이동 기능 구현
{
this.x += x;
this.x += y;
}
인터페이스 예제
④
IDrawObj 인터페이스를 통해서 Point 클래스의 메서드
를 불러보는 예
class Class1
{
static void Main(string[] args)
{
IDrawObj obj = new Point( 100, 200);
obj.Draw(); // ( 100, 200 )
}
}
obj.Move( 100, 100 );
obj.Draw(); // ( 200, 300 )
인터페이스

인터페이스 다중 상속



인터페이스는 다중 상속을 허용
여러 인터페이스를 동시에 다중 상속 받기 위해 두 개의 인터페이
스 interface1, interface2를 상속받아 클래스를 정의한 예
인터페이스 이름 사이에 콤마(,)를 두고 상속받을 인터페이스를
나열
인터페이스

인터페이스 다중 상속

다중 상속을 설명하기 위해 인터페이스를 두 개로 나누어 정의한
예
interface IDrawObj
{
void Draw();
}
interface IMoveObj
{
void Move();
}
인터페이스

인터페이스 다중 상속
Rectangle 객체의 경우 IDrawObj 인터페이스와 IMoveObj 인터
페이스를 다중 상속 받아 정의

class Rectangle : IDrawObj, IMoveObj
{
public void Draw() // 그리기
{
}
}

public void Move() // 이동
{
}
화면에 그릴 수만 있고, 이동할 수 없는 객체라면 다음과 같이
IDrawObj 인터페이스만 상속받아 정의
class SelectArea : IDrawObj
{
public void Draw() // 그리기
{
}
}
마무리

마무리



상속성과 다형성은 객체 프로그래밍에서 기본이 되는 특성
다형성과 인터페이스는 클래스 라이브러리에서 제공되는 클래스
를 사용할 때 없어서는 안될 기본 특성
인터페이스를 상속받은 클래스에서는 반드시 인터페이스에 나열
한 기능을 구현
{
}



IDrawObj o1 = new Point(100,100);
IDrawObj o2 = new Rectangle(100,100,200,200);
o1.Draw(); // (100,100)
o2.Draw(); // (100,100) ~ (200,200)
상속성이란 다른 클래스를 상속받아 정의하는 특성
sealed 클래스는 클래스를 상속받아 쓸 수 없도록 지정할 때 사용
abstract 클래스나 인터페이스는 다른 클래스에서 상속받아야 쓸
수 있으며 단독으로 사용할 수 없다