상속, abstract, interface, sealed, this, base
Abstract(추상) Class
: 미완성 설계도의 느낌
: 추상 클래스는 클래스를 상속받아 그 기능을 이용하고, 확장시키기 위해 사용됨
: IS – A // ~이다
: 상속을 위한 클래스이며, 자체로 인스턴스 생성 불가능하다
: 추상클래스는 1개 이상의 추상함수 또는 1개이상의 가상함수를 갖는다
: 추상함수는 정의만 가능, 가상함수는 구현가능하다
: 상속받을때 추상함수는 반드시 재정(override)의 구현되어야 하며, 가상함수의 재정의는
옵션으로 재정의 하지 않으면 상위 클래스의 가상함수에 구현대로 따른다
: 추상클래스는 많은 클래스의 공통 부분을 묶어 공통클래스 만드는데 사용
Interface(가상)
: 기본설계도의 느낌
: HAS – A // ~을 할 수 있는
: 하나의 클래스가 여러 클래스를 상속받을때(다중상속) abstract 클래스를 쓸수없고,
interface를 사용한다. interface는 함수의 정의만 있으며, 상속받아 사용할때 재정의가
아닌 함수의 정의를 하게된다.
추상클래스 Vs. 인터페이스
추상클래스: 상속 받아서 기능까지 같으며, 여기서 좀더 확장하고 싶을때
인터페이스: 다중상속하며, 다양한 기능 탑재하고 싶을때
예제
using System;
namespace AbInter
{
// 추상클래스 Creature
public abstract class Creature
{
protected int age;
private string name;
public Creature(int age, string name)
{
this.age = age;
this.name = name;
}
public void grow()
{
this.age++;
}
// 추상함수
public abstract void action();
public void display()
{
Console.WriteLine("name: " + this.name + ", age: " + this.age);
}
}
// 인터페이스
public interface Talkable
{
void talk(); // abstract void talk() : c# 8.0 재정의가 아니라 정의
}
// 인터페이스
public interface Programmble
{
void code();
}
// 인터페이스
public interface Ridable
{
void ride();
}
// 인터페이스
public interface Flyable
{
void fly();
}
// Bird 추상 클래스의 Creature 추상클래스 상속
public abstract class Bird : Creature
{
protected string wing = "wings";
// 부모 클래스 생성자
public Bird(int age, string name) : base(age, name)
{}
// 부모클래스의 action 추상 함수 재정의
public override void action()
{
Console.WriteLine("flying, crying");
}
}
// human 추상 클래스의 creature 추상클래스 상속, 인터페이스 talkable 상속
public abstract class Human : Creature, Talkable
{
// 부모 클래스 생성자
public Human(int age, string name) : base(age, name){}
// 부모클래스의 action 추상함수 재정의
public override void action()
{
Console.WriteLine("thinking, understanding");
}
// 인터페이스 정의
public void talk()
{
Console.WriteLine("I am speaking");
}
}
// eagle 일반 클래스의 Bird 추상클래스 상속, flyable 인터페이스 상속
public class Eagle : Bird, Flyable
{
// 부모 클래스 생성자
public Eagle(int age, string name) : base(age, name){}
// 부모클래스의 action 추상함수 재정의 - 추상클래스인 부모에서 그의 추상클래스 부모의 추상함수를 재정의했고, 이걸 다시 재정의 함 (flying, crying) => (I am seeking food)
public override void action()
{
Console.WriteLine("I am seeking food");
}
// 일반 함수
public void fly()
{
Console.WriteLine("I am flying with " + base.wing); // call 부모클래스의 변수
}
}
// john 일반클래스의 human 추상 클래스 상속, programmble, ridable 인터페이스 상속 - 부모클래스에서 talkable 인터페이스도 상속받은상태임
public class John : Human, Programmble, Ridable
{
// 부모 클래스 생성자
public John(int age, string name): base(age, name){}
// 인터페이스 정의
public void code()
{
Console.WriteLine("I am coding");
}
// 인터페이스 정의
public void ride()
{
Console.WriteLine("I am riding");
}
}
public class Program
{
// execute
public static void Main(string[] args)
{
John j = new John(30, "John Smith");
j.display(); // Creature
j.action(); // Human : Creature
j.talk(); // Human : Talkable
j.code(); // John : Programmble
j.ride(); // John : Ridable
j.grow(); // Creature
j.display(); // Creature
Console.WriteLine("==============");
Eagle e = new Eagle(10, "Super eagles");
e.display(); // Creature
e.action(); // Bird : Creature
e.fly(); // Eagle: Flyable
e.grow(); // Creature
e.display(); // Creature
}
}
}
/*
name: John Smith, age: 30
thinking, understanding
I am speaking
I am coding
I am riding
name: John Smith, age: 31
==============
name: Super eagles, age: 10
I am seeking feed
I am flying
name: Super eagles, age: 11
*/
sealed 키워드
- 클래스의 상속을 금지시킨다.
- 사용: seal class Example { … }
- 함수 앞에 쓰이는 경우 클래스 상속과는 관련이 없고, 일반함수에 쓰여서 new 키워드로 상속받을때 함수정의 할때도
영향을 미치지 않는다.
- abstract, virtual 함수가 override를 통해 재정의가 이루어질때 sealed 를 사용하면, 다시 상속될경우 함수는 재정의 할
수 없다.
- abstract void display() { ... } => sealed override void display() { ... } => override void display() { ... } // error 발생
this 키워드
- 자기 자신의 인스턴스를 가리킨다
base 키워드
- 부모 클래스의 변수, 함수를 호출 한다
- 부모 클래스의 생성자를 호출할 수 있으며, 파라미터가 없는경우 생략된다