⑴ 캡슐화 ⑵ 인자 전달 ⑶ 상속 ⑷ 다형성
class Base //부모
{
}
clalss Derived: Base //Base를 부모로 하는 자식
{
}
자식은 부모의 개체 부분을 포함하여 생성한다.
- 자식은 부모의 메서드를 사용할 수 있다.
class Man
{
public void Walk()
{
Console.WriteLine("걷다.");
}
}
class Student: Man
{
public void Study()
{
Console.WriteLine("공부하다.");
}
}
class Program
{
static void Main(string [] args)
{
Student student = new Student();
student.Walk(); //부모의 메서드를 사용할 수 있다.
student.Study();
}
}
protected부모 클래스의
private
- 부모에서
private으로 접근 지정된 멤버는 보이지 않는다.- 자신에게 포함된 멤버이지만 접근할 수 없다.
class Man
{
int hp = 100;
public void Walk()
{
Consolle.WriteLine("걷다.");
hp += 2; //private 접근
}
}
cllass Student: Man
{
public void Study()
{
Console.WriteLine("공부하다.");
hp -= 2; //오류!! 접근 불가능하다.
}
}
기반 클래스
protected
protected로 접근 지정을 하게 되면 외부에서는 접근하지 못하지만 자식은 부모에 접근할 수 있다.- 파생된 형식(자식)에서 접근할 수 있게 하려면 부모의 멤버 속성을 통해 접근할 수 있게 해야 한다.
class Man
{
//int hp = 100; private //private 접근이라 필요 없음
protected int Hp
{
get; set;
} = 100;
public void Walk()
{
Console.WriteLine("걷다.");
Hp += 2;
Console.WriteLine(Hp);
}
}
class Student: Man
{
public void Study()
{
Console.WriteLine("공부하다.");
Hp -= 2;
Console.WriteLine(Hp);
}
}
internal class _13_부모protected
{
static void Main(string[] args)
{
Student stu = new Student();
stu.Walk();
stu.Study();
}
}
생성자와 소멸자의 순서
- 최상위 부모가 가장 먼저 생성되고, 하위 자식이 가장 먼저 소멸한다.
class Man
{
public Man()
{
Console.WriteLine("Man 생성자");
}
}
class Student:Man
{
public Student()
{
Console.WriteLine("Student 생성자");
}
}
class Program
{
static void Main(string [] args)
{
Student stu = new Student();
}
}
부모 클래스에 기본 생성자가 없을 때
- 기본 생성자란 매개 변수가 없는 생성자를 말한다.
클래스의 인스턴스를 생성할 때 필드를 기본값으로 초기화하는 역할을 한다.
base 키워드를 사용해 부모 클래스 생성에 필요한 인자를 초기화 할 수 있다.class Man
{
string name;
public Man(string name)
{
this.name = name;
}
}
class Student: Man
{
public Student(string name): base(name)
{
}
}
class Program
{
static void Main(string [] args)
{
Student stu = new Student("홍길동");
}
}
name을 전달 받아 출력하는 문장이 없으므로 코드를 실행시켰을 때 아무것도 출력되지 않는다.class 앞에 sealed 키워드를 명시한다.sealed class Man
{
}
calss Student: Man //오류 발생!!
{
}
업캐스팅이 가능하다.
: 부모의 요소를 자식이 참조할 수 있다.
재정의 할 수 있다.
: 변수를 통해 메서드를 호출했을 때, 구체적인 동작이 다를 수 있다.
static void Main(string [] args)
{
Man man = null;
man = new Stu();
}
is 연산자와 as 연산자
- 업캐스팅 : 자식 객체를 부모 타입으로 변환 (안전하게 가능)
Parent p = new Child();
- 다운캐스팅 : 부모 객체를 자식 타입으로 변환 (안전하지 X)
Child ch = (Child)p;
Parent p = new Child1(); //업캐스팅
Child1 ch1 = (Child1)p; //다운캐스팅
Child2 ch2 = (Child2)p;
is 연산자와 as 연산자를 사용하여 해결할 수 있다.as 연산자p as ChildChild ch = p as Child; //자식 개체 참조 (다운캐스팅)
if(ch != null)
ch.Study();
else
Console.WriteLine("Child 형식 개체가 아닙니다.");
is 연산자p is ChildParent p = new Child(); //업캐스팅
if(p is Child)
{
Child ch = (Child)p;
ch .Study();
}
object obj = 3; //Boxing
if(obj is int)
{
int i = (int)obj;
Console.WriteLine(i.ToString()); //UnBoxing
}
is, as 연산자 정리is 연산자는 객체가 특정 타입인지 참, 거짓을 판단한다.as 연산자는 객체를 형 변환한다. (다운캐스팅)new 키워드base 키워드
new키워드를 이용한 무효화 멤버 사용하기부모 클래스에서 정의된 멤버와 같은 이름의 멤버를
new키워드를 사용해 재사용하면 부모 클래스의 멤버는 무효화된다. (새로 정의하여 사용할 수 있다.)
class Man
{
public void Work()
{
Console.WriteLine("일을 하다.");
}
}
class Student:Man
{
public new void Work()
{
Console.WriteLine("공부를 하다.");
}
}
class Program
{
static void Main(string [] args)
{
Student stu = new Student();
stu.Work();
Man man = stu; //Student 객체를 Man 타입으로 변환(업캐스팅)
man.Work();
}
}
실행 결과 ✔
공부를 하다.
일을 하다.
부모 클래스의 참조로 접근하면 부모 클래스의 멤버가 사용된다.
stu.Work(); "공부를 하다." 출력
자식 클래스의 참조로 접근하면 자식 클래스의 멤버가 사용된다.
man.Work(); "일을 하다." 출력
base키워드를 이용한 무효화 멤버 사용하기
base키워드를 통해 멤버를 호출하면 무효화된 부모 클래스의 멤버를 사용할 수 있다.
class Man
{
public void Work()
{
Console.WriteLine("일을 하다.");
}
}
class Student:Man
{
public new void Work()
{
base.Work(); //무효화된 Man의 Work 메서드를 사용할 수 있다.
Console.WriteLine("공부를 하다.");
}
}
class Program
{
static void Main(string [] args)
{
Student stu = new Student();
stu.Work();
}
}
new, base 키워드 정리new 키워드는 부모의 멤버를 무효화 시켜 자식에서 재설정 하여 사용한다.
base 키워드는 new를 통해 무효화 시킨 부모 멤버를 다시 유효화 시켜 사용한다.
virtualvirtual 키워드를 명시하여 멤버를 선언하면 가상 멤버가 도니다.override부모 클래스에서 정의한 멤버를 자식 클래스에서 재정의 하면 값 형식이 아닌 참조 형식의 멤버가 동작하도록 한다.
class Man
{
public virtual void Work()
{
Console.WriteLine("일을 하다.");
}
}
class Student:Man
{
public override void Work()
{
Console.WriteLine("공부를 하다.");
}
}
class Program
{
static void Main(string [] args)
{
Man man = new Student();
man.Work();
}
}
실행 결과 ✔
공부를 하다.
자식의 Work메서드를 호출하고 싶어서 Man man = new Student();로 업캐스팅 하였다.
abstract 키워드를 사용한다.abstract class Man
{
public Man()
{
}
}
class Program
{
static void Main()
{
Man man = new Man(); //오류 발생!!
}
}
추상 메서드 캡슐화
abstract 키워드를 명시한다.abstract class Man //추상 클래스
{
public abstract void Work(); //추상 메서드
}
class Student:Man
{
public override void Work()
{
Console.WriteLine("공부를 하다.");
}
}
class Program
{
static void Main(string [] args)
{
Man man = new Student();
man.Work(); //자식의 Work() 메서드가 호출된다.
}
}