OOP(객체 지향 프로그래밍)
객체 지향 프로그래밍 OOP : Object Oriented Programming
- 상속성
Knight, Mage, Archer 등 여러 가지 클래스를 만들다 보면 다른 클래스이지만 개념상 같은것끼리 묶어서 사용함으로써 필드 및 메서드 선언 등을 줄일 수 있다.
가장 상위계층인 Player라는 부모 클래스를 만들고, 그것을 상속하는 자식클래스로 각 직업클래스를 선언한다.
class Player
{
protected string name;
protected int hp;
}
class Knight : Player
{
hp = 100;
}
- 상속과 생성자
자식 클래스로 객체를 만들면 자식 클래스의 생성자와 부모 클래스의 생성자 모두 호출되며,
부모 클래스 생성자부터 호출된다.
만약 부모 클래스 생성자가 어떤 필드를 인자로 갖고, 자식 클래스 생성자가 그 생성자를 지정해서 호출해야한다면 다음과 같이 자식 클래스 생성자를 작성한다
class Player
{
public int hp;
public Player(int hp)
{
this.hp = hp;
}
}
class Knight : Player
{
Knight() : base(100)
{
}
}
- this 와 base this는 내 클래스 안에 있는 변수에 접근하기 위한 목적을 사용했다. 이처럼 base는 자신의 부모 클래스의 변수에도 접근할 수 있다.
using System;
namespace CSharp
{
class Player
{
public int hp;
public int attack;
public int id;
public Player()
{
Console.WriteLine("Player 생성자 호출!");
}
public Player(int hp)
{
this.hp = hp;
Console.WriteLine("int Player 생성자 호출!");
}
}
class Knight : Player
{
// 필드
public Knight() : base(100)
{
this.hp = 100;
this.attack = 10;
Console.WriteLine("Knight 생성자 호출!");
}
public Knight(int hp) : this() // 내 자신을 호출 시켜 준 후에 이 생성자를 호출해주세요.
{
this.hp = hp;
Console.WriteLine("int 생성자 호출");
}
public Knight(int hp, int attack) : this() // 내 자신을 호출 시켜 준 후에 이 생성자를 호출해주세요.
{
this.hp = hp;
this.attack = attack;
Console.WriteLine("int 생성자 호출");
}
public void Move()
{
Console.WriteLine("Knight Move");
}
public void Attack()
{
Console.WriteLine("Knight attack");
}
public Knight Clone()
{
Knight knight = new Knight();
knight.hp = hp;
knight.attack = attack;
return knight;
}
}
class Mage : Player
{
}
class Archer : Player
{
}
class Program
{
// 객체 지향 프로그래밍
static void Main(string[] args)
{
Knight knight = new Knight();
}
}
}
- 은닉성 보안의 목적 ex ) 자동차를 사면 할 수 있는 기능들 중에는 핸들을 조작하고 페달을 밟고 차문을 열거나하는 기능과 사용자가 직접 조작하진 않지만 자동차가 움직이기 위해서는 필요한 전기장치, 엔진, 기름 등이 있다. 후자의 경우는 사용자가 차를 산다하더라도 직접 조작하도록 외부를 노출시키는 것을 허용한다면 큰 위험이 따르기때문에 철저히 숨기는 것이 중요하다.
결국 보안레벨은 사용자가 함수를 사용할 때 이 함수를 사용하는 것이 위험하냐 아니면 대충 사용해도 되는것이냐에 따라 나누는 판단적인 요소가 들어가있다.
::접근 한정자:: public ; 누구한테나 개방적으로 사용하겠다. 보안 레벨이 가장 낮음
protected ; 외부 클래스에서 접근이 불가능하지만, 상속받은 자식의 클래스에서는 사용이 가능하다.
- private ; 외부에서는 접근할 수 없도록 자신의 클래스 내부에서 정의된 로직안에서만 오직 사용가능하다. 보안레벨이 높음. (디폴트)
private int hp ; public void setHp(hp) { this.hp = hp; } 이렇게 작성하는 이유는 보안상의 문제도 있다지만, break point를 this.hp 에 잡고 디버깅했을 때, 언제 setHp() 함수가 호출되어서 hp가 설정되었는지 확인하기 위함도 있다.
- 다형성 각각 같은 플레이어이지만 직업에 따라 할 수 있는 행동이 다를 수 있다. 전사는 뚜벅이라서 걸어다니지만, 마법사는 마나를 사용해서 순간이동을 사용할 수 있는 것처럼 ‘움직인다’는 행동은 같지만 결과와 과정이 다를 수 있다.
-
hiding 자식 클래스에 new 키워드를 이용해서 부모 클래스에 있는 Move()함수를 가려도 된다는 것을 명시한다. 다형성과는 관계가 없지만 비슷하게 사용할 수는 있다.
-
overriding 부모 클래스에서는 virtual 이라는 키워드로 가상함수를 만들고, 자식클래스에서 override 키워드로 같은 이름의 함수인 Move()를 오버라이딩한다.
class Player { protected int hp; protected int attack; public virtual void Move() { Console.WriteLine("player 이동"); } } class Knight : Player { public override void Move() { Console.WriteLine("Knight 이동"); } }
class Program
{
static void EnterGame(Player player)
{
player.Move();
}
static void Main(string[] args)
{
Knight knight = new Knight();
Mage mage = new Mage();
EnterGame(knight);
}
}
코드의 재사용성 확보. EnterGame(Player player)에서 Knight 인지 mage인지 확인을 하기 위해 각각 Mage mage = (player as Mage); if ( mage != null ) {. . .} Knight night = (player as Knight); if (knight != null ) {. . .} 위처럼 작성하여 코드의 낭비를 줄이고 반복되는 코드를 하나로 합쳐 간단하게 정리할 수 있다.
- base Knight 에서 Move()를 override 해서 사용하긴 하지만, 나중에 Player 클래스의 Move()를 필요로하는 상황에서 부모의 함수를 호출하도록한다. ( 평상 시 더블점프 => 끈기의 숲에서 기본 점프 )
base.Move()
댓글남기기