[Programming] OOP

etc... 2015. 12. 18. 03:48

Object Oriented Programming이다. 참 이것도 학사에서 진작에 잘 배우고 왔었어야 되는 것인데... 괜찮다 그래도 지금 배웠으니 괜찮다. 이전에 말 했듯이 Java를 이용해서 OOP를 설명할 예정이다. 그런데 우선, OOP를 설명하기 위해 왜 OOP가 필요한지부터 설명해보려고 한다.

Programming을 한다는 것은 세상의 무언가를 표현한다는 것이다. 세상의 무언가는 항상 그 무엇이든간에 특징이 있다. 예를 들어, 사람은 이름, 키, 몸무게, 엄마, 아빠, 자식, 등등의 여러가지 정보를 기본적으로 가지고 있다. 과일이라는 것은 색깔, 무게, 맛, 영양소, 생산지역 등등 여러가지가 있다. (이런 것들을 모두 Object라고 하자.) 예를 들어 사람의 정보를 가지고 프로그래밍을 한다고 가정하면, 사람이 가지고 있는 요소들을 쉽게 쉽게 접근 할 수 있어야 된다.

그런데 그것 뿐만이 아니다. Object들간의 관계도 있다. 예를 들어, 부모라는 Object와 Child라는 관계. 호랑이라는 Object와 포유류라는 Object 관계도 있다. 호랑이는 포유류의 모든 요소를 가지고 있을 것이고.. 등등... 


이러한 관계를 표현하기 위해 OOP가 있는 것이다. 여기서 잠깐, OOP를 잘 아는 사람이 이 글을 보면 피식 하고 웃을지도 모른다. 기본적으로 Programmer로서의 직업을 가져본 적이 없는 사람이라, 그 깊이가 많이 부족할 수도 있다. 따라서 여기서 설명하는 모든 것이 OOP의 모든 것이라고 가정하지는 않았으면 좋겠다. 분명히 짚지 않고 넘어간 OOP만의 장점 혹은 단점이 있을 수도 있다. 그런 모든 것은 독자분들의 열정으로 남겨두려한다.


OOP에 대한 설명을 본격적으로 시작해보자. OOP는 우선 Object를 설명하기 위해 Class를 선언한다. Java에서의 모든 것은 Object이다. 즉, 모든 것은 Class로 표현이 되어있다.  아래의 코드는 하나의 점을 표현하기 위한 Class이다.


당연히 x, y값이 존재한다. 위의 코드에서 보면 Class명과 똑같은 Function 하나가 있다. Point(). OOP에서는 이것을 Constructor라고 한다. Constructor는 하나의 Object를 초기화하는 역할을 한다. 이 함수가 없다고 치자. 그리고 아래와 같이 Point Object 하나를 선언했다고 하자.


Point p1;


x와 y가 가지고 있는 값이 뭘까? 없다. Constructor를 이용하여 아래와 같이 Point Object를 선언한다면 x와 y는 0이라는 값으로 선언과 동시에 초기화 된다.


Point p1 = new Point();


여기서 Overloading이라는 개념을 설명해보자. 위의 Constructor에서 왜 0으로만 초기화해야되는 것이지? 가끔은 10, 10으로 초기화되야 될 때도 있다. 그러면 이렇게 해보자.


아래의 함수를 추가해보자.

한 파일에 같은 함수을 가진 함수 Point()와 Point(int x, int y) 둘 다 있다. 이것이 가능한 것이 Overloading 때문이다. 이젠 Point Object를 사용할 사람들은 자기들의 선호에 따라서 Point() 또는 Point(10, 10) 이렇게 선언할 수 있게 되었다.


자 그런데 다른 함수는 선언 못 하나? 할 수 있다. Point Object가 가질 수 있을 만한 함수가 어떤 것이 있을까? getX, getY, moveX, moveY와 같은 함수들이 있을 수 있다. 직관적으로 getX, getY는 x와 y의 값을 return하는 함수이고, moveX와 moveY는 x와 y 값을 움직이는 함수이다. 아래의 함수를 


아 여기서 잠깐. this.x와 x의 차이는 뭘까? this.x는 Point Object의 x를 의미하는 것이다. 반면 그냥 x는 moveX(int x)에서 전달된 파라미터 x를 의미하는 것이다. 이를 구별해주기 위함이다. Point Object도 x를 가지고 있는데 하필이면 moveX의 파라미터가 x네? 그것을 구별해주기 위해서 Point Object의 x는 this라는 것을 붙여준 것이다. 변수만 바꿔주면 Point Object의 x를 그냥 x로 쓸 수 있다.


100% 같은 함수이다. 지금까지의 Point Object는 두 개의 int variable과 한 개의 constructor 그리고 네 개의 함수가 있다. 이렇게 하나로 묶여있는데, 이것을 OOP에서는 encapsulation이라고 한다. 여기서 보면 public, private 등을 알아봐야 된다. 기본적으로 Class에서 모든 변수는 private이다. 개인소유, 즉, 다른 Object에서는 접근할 수 없다는 말이다. Point Object에서는 int x, int y와 같이 선언했는데, 이는 private int x, private int y와 같다. 만일 public int x, public int y와 같이 선언했었다면 뭐가 달라질까? 다른 Object에서 접근이 가능하다. 예를 들어, Point Object의 x와 y가 다른 Object에서 접근이 된다는 것이다.

OOP에서 언급해야 되는 keyword로는 static, final이 있다. static은 Object 간의 공유할 수 있는 무언가를 만들기 위해 있다. 예를 들어, Math라는 Object가 있다고 하자. 여기서 PI는 3.14로 같은데, 모든 Object가 double PI = 3.14 이렇게 가지고 있을 필요가 없다. 하나 가지고 나눠쓰자. 그래서 아래와 같이 static이라는 keyword와 선언을 해주면 된다. 


public static double PI = 3.14;


이제부터 PI는 다른 Object에서 바로 바로 불러서 쓸 수 있다. 프로그래밍을 하다가 갑자기 PI에 3을 곱해야 되는 상황이 왔다. 그러면 바로 Math.PI * 3과 같이 쓸 수 있다. 물론 public으로 선언이 되어있으니까 외부 Object로부터 접근이 가능한 것이다. 그런데 PI 같은 값은 변하면 안 되는 값이다. 그런데 실수로 이것을 변경하면 좋지 않은 상황이 벌어진다... 그래서 그것을 방지하기 위해 final keyword를 붙인다.


public static final double PI = 3.14


이렇게 선언해두면, 실수로 PI = 5.14라고 고치는 코드를 작성할 경우 컴파일할 때 에러가 발생한다. 

자, 여기서 조금 더 OOP 다운 내용으로 넘어가보자. Inheritance에 대해서 알아보자. 예를 들어, Cat 이라는 Object는 Feline(고양이과) Object에 속해야 된다. 아래의 코드를 보자.


자 Feline이라는 상위 Class를 Cat이라는 하위 Class가 상속받고 있다. 이렇게 상속받으면 뭐가 다른가? Cat Object에서 sleep(), eat()함수가 있나? 없다! 그런데 생긴다. Feline Object가 가지고 있기 때문이다. 여기서 Overriding의 개념을 설명해보자. 만일 Cat Object가 뭔가 자기만의 sleep()함수를 가지고 싶다면 어떻게 해야할까? 그냥 같은 이름으로 선언해주면 된다.


이렇게 선언해주면 Cat Object에 있는 sleep()함수가 실행된다. 그런데 만일 여기서 Cat Object가 있음에도 불구하고 Feline Object가 실행되야 하는 경우가 있다면 어떻게 Feline의 sleep()을 호출할 수 있을까? 


super.sleep();


자 Inheritance에서 하나만 더 집고 넘어가자. protected라는 keyword이다. public과 private만 있다면 뭔가 이상한 현상이 생겨난다. 분명 Cat과 Feline은 다른 Object이다 그러면서 동시에 Inheritance 관계에 있다. 그러면 Feline Object에 있는 변수들은 Cat도 가지고 있어야 되는데... 그렇다고 public으로 선언하자니 Cat이 아닌 다른 Object들도 접근하게 되고 private으로 하자니 Cat Object가 접근을 못 하고.. 이럴 때 필요한 것이 protected이다. 이렇게 하면 Cat과 Feline Object를 제외한 다른 Object들은 접근을 못 한다. 그래서 위의 Feline Object에서 name이 protected로 선언되어있다.


마지막으로 polymorphism을 설명하려고 한다. 이 말은... "어떤 함수를 선택하지?"라고 Java가 선택하는 것과 같다. 아까전에 Overloading도 있었는데, 그것도 일종의 polymorphism의 일종이다. 정확히 말하면 static polymorphism이라고 한다. 그런데 이럴 경우에는 Java가 함수를 선택하는 시점이 Compilation 할 때 선택을 한다. 그래서 static이라고 부른다. 보통 OOP에서 polymorphism이라고 하면 dynamic polymorphism을 의미하는데, 이는 run-time에 함수를 결정하는 것을 의미한다. 아래의 코드를 보자.


결과는 아래와 같다.


The Tiger Purrs

The Lion Purrs


뭔가 CatTest에서 Cat tcat = new Tiger(); Cat lcat = new Lion()과 같이 조금 애매하게 선언을 했는데, 이럴 경우, Java는 run-time에 tcat은 Tiger Object, Lion은 Lion Object로 결정한다. 그래서 위와 같은 결과를 준다.



'etc...' 카테고리의 다른 글

[Tensorflow] Multi linear Regreassion  (1) 2016.11.27
[Tensorflow] Basic of Tensorflow  (0) 2016.11.27
[Algorithm] Graph  (0) 2015.12.18
[Algorithm] Sorting Algorithm  (0) 2015.12.17
[Algorithm] Master Theorem and its application  (0) 2015.12.17
Posted by 빛나유
,