390 likes | 645 Views
7 장 상속부터 인터페이스까지. 상속성 다형성과 가상 메서드 abstract 클래스와 인터페이스. 상속성. 상속성이란 상속성 (Inheritance) 이란 , 기존에 정의한 객체가 가지는 특성을 그대로 물려받아 새로운 객체를 정의하는 것 상속이란 두 개의 클래스간의 관계를 정의하는 특성 상속 관계에 있는 클래스를 베이스 클래스와 상속받은 클래스라고 정의 베이스 (base) 클래스 - 이미 정의해놓은 클래스 상속받은 (derived) 클래스 - 기존 클래스를 상속받아서 새로 정의한 클래스
E N D
7장상속부터 인터페이스까지 상속성 다형성과 가상 메서드 abstract 클래스와 인터페이스
상속성 • 상속성이란 • 상속성(Inheritance)이란, 기존에 정의한 객체가 가지는 특성을 그대로 물려받아 새로운 객체를 정의하는 것 • 상속이란 두 개의 클래스간의 관계를 정의하는 특성 • 상속 관계에 있는 클래스를 베이스 클래스와 상속받은 클래스라고 정의 • 베이스(base) 클래스 - 이미 정의해놓은 클래스 • 상속받은(derived) 클래스 - 기존 클래스를 상속받아서 새로 정의한 클래스 • 상속 구현 • 모든 클래스는 베이스 클래스를 가질 수 있으며, 다른 클래스에게 상속될 수 있다
상속성 • 상속 구현 • Class1 클래스를 상속받아 Class2 클래스를 선언한 예 • 상속받은 클래스에서는 마치 베이스 클래스의 모든 멤버를 정의해놓은 것처럼 그대로 가져다 쓸 수 있다
상속성 • 상속 구현 • Point 클래스를 상속받아 Point3D 클래스를 정의한 경우, 상속받은 클래스에서 베이스 클래스 멤버를 자기 멤버인양 쓸 수 있다
상속 클래스예제 • Point 클래스를 정의하고, 이 클래스를 상속받아 Point3D 클래스를 정의해보는 예제 프로젝트 유형 :콘솔 응용 프로그램 프로젝트 이름 :Inherit
상속 클래스예제 • x,y 필드와 SetPoint 메서드, Draw 메서드를 정의하고, Draw 메서드는 x, y 필드 값을 보여주도록 구현 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 클래스는 Point 클래스를 상속받아 정의하고, z 멤버만 하나 더 추가 • Main 메서드에서 Point3D 객체를 생성하고 Draw 메서드를 호출 // Point 클래스 상속 class Point3D : Point { public int z; } 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 키워드예제 • 상속받은 클래스에 생성자를 정의할 때, 베이스 클래스의 생성자를 불러서 값을 초기화 베이스 클래스 생성자를 부를 때 base 키워드를 사용 class Point { public Point( int x, int y ) { } ... } 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 메서드를 호출 • DrawObj 객체 선언한 참조 변수를 통해서 Point 객체의 Draw 메서드를 부른 결과 class Class1 { static void Main(string[] args) { DrawObj obj = new Point( 100, 200 ); obj.Draw(); } }
가상 메서드예제 • DrawObj 클래스에서 virtual 키워드 없애고 다시 예제를 실행
abstract 클래스 • abstract 클래스 • abstract 클래스는 아무런 기능이 없는 객체를 생성해서 쓰는 것을 방지 • abstract 클래스는 객체 그 자체로는 인스턴스 객체를 생성할 수 없으며, 다른 객체가 상속받은 경우에만 가능
abstract 클래스 • abstract 클래스 • abstract 클래스를 생성하려고 하면 컴파일 오류가 발생 • abstract 클래스는 상속받은 다른 클래스를 대신할 때 사용하며, 상속받은 객체를 생성하고 레퍼런스 변수에 넣어두는 용도로 사용 static void Main() { // 단독으로 객체를 생성할 수 없음. DrawObj obj = new DrawObj(); } 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 인터페이스를 다중 상속 받아 정의 • 화면에 그릴 수만 있고, 이동할 수 없는 객체라면 다음과 같이 IDrawObj 인터페이스만 상속받아 정의 class Rectangle : IDrawObj, IMoveObj { public void Draw() // 그리기 { } public void Move() // 이동 { } } class SelectArea : IDrawObj { public void Draw() // 그리기 { } }
마무리 • 마무리 • 상속성과 다형성은 객체 프로그래밍에서 기본이 되는 특성 • 다형성과 인터페이스는 클래스 라이브러리에서 제공되는 클래스를 사용할 때 없어서는 안될 기본 특성 • 인터페이스를 상속받은 클래스에서는 반드시 인터페이스에 나열한 기능을 구현 • 상속성이란 다른 클래스를 상속받아 정의하는 특성 • sealed 클래스는 클래스를 상속받아 쓸 수 없도록 지정할 때 사용 • abstract 클래스나 인터페이스는 다른 클래스에서 상속받아야 쓸 수 있으며 단독으로 사용할 수 없다 { IDrawObj o1 = new Point(100,100); IDrawObj o2 = new Rectangle(100,100,200,200); o1.Draw(); // (100,100) o2.Draw(); // (100,100) ~ (200,200) }