1. 객체지향언어

정평화·2022년 2월 16일
1

1.1 객체지향언어의 역사

요즘은 컴퓨터의 눈부신 발전으로 활용 폭이 넓고 다양해져서 컴퓨터가 사용되지 않는 분야가 없을 정도지만 , 초창기에는 주로 과학실험이나 미사일 발사실험과 같은 모의실험(simulation)을 목적으로 사용되었다. 이 시절의 과학자들은 모의실험을 위해 실제 세계와 유사한 가상 세계를 컴퓨터 속에 구현하고자 노력하였으며 이런한 노력은 객체지향이론을 탄생시켰다.
객체지향이론의 기본 개념은 '실제 세계는 사물(객체)로 이루어져 있으며, 발생하는 모든사건들은 사물간의 사호작용이다.' 라는 것이다. 실제 사물의 속성과 기능을 분석한 다음, 데이터(변수)와 함수로 정의함으로써 실제 세계를 컴퓨터 속에 옮겨 놓은 것과 같인 가상세계를 구현하고 이 가상세계를 컴퓨터 속에 옮겨 놓은 것과 같은 가상세계를 구현하고 이 가상세계에서 모의 실험을 함으로써 많은 시간과 비용을 절약할 수 있었다. 객체지향이론은 상속,캡슐화,추상화 개념을 중심으로 점차 구체적으로 발전되었으며 1960년대 중반에 객체지향이론을 프로그래밍언어에 적용한 시뮬라(Simula)라는 최초의 객체지향언저가 탄생하였다.
그 당시에는 FORTRAN이나 COBOL과 같은 절차적 언어들이 주류를 이루었으며, 객체지향언어는 널리 사용되지 못하고 있었다. 1980년대 중반에 c++을 비롯하여 여러 객체지향언어가 발표되면서 객체지향언어가 본격적으로 개발자들의 관심을 끌기 시작하였지만 여전히 사용자층이 넓지 못했다.
그러나 프로그램의 규모가 점점 커지고 사용자들의 요구가 빠르게 변화해가는 사용자들의 요구가 빠르게 변화해가는 상황을 절차적 언어로는 극복하기 어렵다는 한계를 느끼고 객체지향언어를 이용한 개발방법론이 대안으로 떠오르게 되면서 조금씩 입지를 넓혀가고 있었다.
자바가 1955년에 발표되고 1990년 대 인터넷의 발전과 함께 크게 유행하면서 객체지향언어는 이제 프로그래밍언어의 주류로 자리 잡았다.

1.2 객제지향언어

객체지향언어는 기존의 프로그래밍언어와 다른 전혀 새로운 것이 아니라, 기존의 프로그래밍 언어에 몇 가지 새로운 규칙을 추가한 보다 발전된 형태의 것이다. 이런한 규칙들을 이용해서 코드 간에 서로 관계를 맺어 줌으로써 보다 유기적으로 프로그램을 구성하는 것이 가능해졌다. 기존의 프로그래밍 언어에 익숙한 사람이라면 자바의 객체지향적인 부분만 새로 배우면 된다. 다만 절차적 언어에 익숙한 프로그래밍 습관을 객체지향적으로 바꾸도록 노력해야할 것이다. 객체지향언어의 주요특징은 다음과 같다.

1. 코드의 재사용성이 좋다.

새로운 코드를 작성할 때 기존의 코드를 이용하여 쉽게 작성할 수 있다.

2. 코드의 관리가 용이하다.

코드간의 관계를 이용해서 적은 노력으로 쉽게 코드를 변경 할 수 있다.

3. 신뢰성이높은 프로그래밍을 가능하게 한다.

  제어자와 메서드를 이용해서 데이터를 보호하고 올바른 값을 유지하도록 하며, 
  코드의 중복을 제거하여 코드의 불일치로 인한 오동작을 방지할 수 있다.

객체지향언어의 가장 큰 장점은 '코드의 재사용성이 높고 유지보수가 용이하다.'라는 것이다. 이런한 객체지향언어의 장점은 프로그램의 개발과 유지보수에 드는 시간과 비용을 획기적으로 개선하였다. 앞으로 상속,다형성과 같은 객체지향개념을 학습할 때 재사용성과 유지보수 그리고 중복된 코드의 제거, 이 세 가지 관점에서 보면 보다 쉽게 이해할 수 있을 것이다.
객체지향 프로그램밍은 프로그래머에게 거지적 관점에서 설계할 수 있는 능력을 요구하기 때문에 객체지향개념을 이해했다 하더라도 자바의 개체지향적 장점들을 충분히 활용한 프로그램을 작성하기란 쉽지 않을 것이다.
너무 객체지향개념에 얽매여서 고민하기 보다는 일단 프로그램을 기능적으로 완성한 다음 어떻게 하면 보다 객체지향적으로 코드를 개선할 수 있을지를 고민하여 점차 개선해 나가는 것이 좋다.
이런한 들이 축적되어야 프로그램을 개체지향적으로 설계할 수 있는 능력이 길러지는 것이지 처음부터 이론을 많이 안다고 해서 좋은 설계를 할 수 있는 것이 아니다.

2. 클래스와 객체

2.1 클래스와 객체의 정의와 용도

클래스란 '객체를 정응해놓은 것.' 또는 클래스는 '객체의 설계도 또는 틀'이라고 정의할 수 있다. 클래스는 객체를 생성하는데 사용되며, 객체는 클래스에 정의된 대로 생성된다.
클래스의 정의 클래스란 객체를 정의해 놓은 것이다.
클래스의 용도 클래스는 객체를 생성하는데 상용된다.

객체의 사전적인 정의는 , '실제로 존재하는 것' 이다. 우리가 주변에서 볼 수 있는 책상, 의자, 자동차와 같은 사물들이 곧 객체이다. 객체지향이론에서는 사물과 같은 유형적인 것뿐만 아니라, 개념이나 논리와 같은 무형적인 것들도 객체로 간주한다.
프로그래밍에서는 개체는 클래스에 저으이된 내용대로 메모리에 생성된 것을 뜻한다.

     **객체의 정의**  실제로 존재하는것, 사물 또는 개념
     **객체의 용도**  객체가 가지고 있는 기능과 속성에 따라 다름

     **유형의 객체**  책상,의자,자동차,TV와 같은 사물
     **무형의 객체**  수학공식, 프로그램 에러와 같은 논리나 개념텍스트

클래스와 객체의 관계를 우리가 살고 있는 실생활에서 예를 들면, 제품 설께도와 제품과의 관계라고 할 수 있다. 예를 들면, TV설계도(클래스)는 TV라는 제품(객체)을 정의한 것이며, TV(객체)를 만드는데 사용된다.
또한 클래스는 단지 객체를 생성하는데 사용될 뿐 , 객체 그 자체는 아니다. 우리가 원하는 기능의 객체를 사용하기 위해서는 먼저 클래스로부터 객체를 생성하는 과정이 선행되어야 한다.
우리가 TV를 보기 위해서는 , TV(객체)가 필요한 것이지 TV설계도(클래스)가 필요한 것은 아니며, TV설계도(클래스)는 단지 TV라는 제품(객체)을 만드는 데만 사용될 뿐이다.
그리고 TV설계도를 통해 TV가 만들어진 후에야 사용할 수 있다. 프로그래밍에서는 먼저 클래스를 작성한 다음, 클래스로부터 객체를 생성하여 사용한다.

|참고| 객체를 사용한다는 것은 객체가 가지고 있는 속성과 기능을 사용한다는 뜻이다.
                                  클래스      |      객체
               
                                제품 설계도          제품
                                TV 설계도            TV
                                붕어빵 기계          붕어빵 
표 6-1 클래스와 객체의 예

클래스를 정의하고 클래스를 통해 객체를 생성하는 이유는 설계도를 통해서 제품을 만드는 이유와 같다. 하나의 설계도만 잘 만들어 놓은면 제품을 만드는 일이 쉬워진다. 제품을 만들 때마다 매번 고민할 필요없이 설계도로만 만들면 되기 때문이다.
설계도 없이 제품을 만든다고 생각해보라. 복잡한 제품일수록 설계도 없이 제품을 만든다는 것은 상상할 수도 없을 것이다.
이와 마찬가지로 클래스를 한번만 잘 만들어 놓기만 하면, 매번 객체를 생성할 때마다 어떻게 객체를 만들어야 할지도 고민하지 않아도 된다. 그냥 클래스로부터 객체를 생성해서 사용하기만 하면 되는 것이다.
이와 마찬가지로 클래스를 한번만 잘 만들어 놓기만 하면, 매법 객체를 생성할 때마다 어떻게 객체를 만들어야 할지를 고민하지 않아도 된다. 그냥 클래스로부터 객체를 생성해서 사용하기만 하면 되는 것이다.
JDK(Java Development Kit)에서는 프로그래밍을 위해 많은 수의 유용한 클래스(Java API)를 기본적으로 제공하고 있으며, 우리는 이클래스들을 이용해서 원하는 기능의 프로그램을 보다 쉽게 작성할 수 있다.

2.2 객체와 인스터스

클래스로부터 객체를 만드는 과정을 클래스의 인스턴스화(instantiate)라고 하며, 어떤 클래스로부터 만들어진 객체를 그 클래스의 인스턴스(instance)라고 한다.

예를 들면, Tv클래스로부터 만들어진 객체를 Tv클래스의 인스턴스라고 한다. 결국 인스터스는 객체와 같은 의미이지만, 객체는 모든 인스턴스를 대쵸하는 포괄적인 의미를 갖고 있으며, 인스턴스는 어떤 클래스로부터 만들어진 것인지를 강조하는 보다 구체적인 의미를 갖고 있다.
예를 들면, '책상은 인스턴스다.'라고 하기 보다는 '책사은 객체다.'라는 쪽이 . '책상은 책상클래스의 객체이다.'라고 하기 보다는 '책상은 책상 클래스의 인스턴스다.'라고 하는것이 더 자연스럽다.
인스턴스와 객체는 같은 의미이므로 두 용어의 사용을 엄격히 구분할 필요는 없지만, 위의 예에서 본 것과 같이 문맥에 따라 구별하여 사용하는 것이 좋다.

	              인스턴스화
			클래스 -----------> 인스턴스(객체)

2.3 객체의 구성요소 - 속성과 기능

객체는 속성과 기능, 두 종류의 구성요소로 이루어져 있으며, 일반적으로 객체는 다수의 속성과 다수의 기능을 갖는다. 즉, 객체는 속성과 기능의 집합이라고 할 수 있다. 그리고 객체가 가지고 있는 속성과 기능을 그 객체의 멤버(구성원, member)라 한다.

클래스란 객체를 정의한 것으로 클래스에는 객체의 모든 속성과 기능이 정의되어 있다. 클래스로부터 객체를 생성하면 , 클래스에 정의된 속성과 기능을 가진 객체가 만들어지는 것이다.
속성과 기능은 아래와 같이 같은 뜻의 여러 가지 용어가 있으며, 앞으로 이 중에서도 '속성'보다는 '멤버변수'를 ,'기능'보다는 '메서드'를 주로 사용할 것이다.

속성(property) 멤버변수(member variable), 특성(attribute), 필드(field), 상태(state)
기능(function) 메서드(method), 함수(function), 행위(behavior)

보다 쉽게 이해 할 수 있도록 TV를 예로 들어보자. TV의 속성으로는 전원상태, 크기, 길이, 높이, 색상, 볼륨 , 채널과 같은 것들이 있으며, 기능으로는 켜기, 끄기 볼륨 높이기, 채널 변경하기 등이 있다.

속성 크기, 길이 , 높이 , 색상, 볼륨, 채널등
기능 켜기, 끄기 , 볼륨 높이기, 채널 변경하기 등

객체지향 프로그래밍에서는 속성과 기능을 각각 변수와 메서드를 표현한다.

					속성(property) -> 멤버변수(variable)
					기능(function) -> 메서드(method)
					      채널 - int chanel
 						  채널 높이기 -> channelUp(){...}
      class Tv {
      	  변수
          String color; 	// 색깔
          boolean power; 	//전원상태
          int channel; 	//채넣
		 
          메서드
          void power()	{	power = !power;	}
          void channelUp()	{	channel++;	}
          void channelDown()	{	channel--;	}

      }
|참고| 멤버변수와 메서드를 선언하는데 있어서 순서는 관계없지만 , 일반적으로 메서드보다는 멤버변수를 먼저 선언하고 멤버변수끼리 메서드는 메서드끼리 모아 놓는 것이 일반적이다.

실제 Tv가 갖는 기능과 속성은 이 외에도 더 있지만 , 프로그래밍에 필요한 속성과 기능만을 선택하여 클래스를 작성하면된다.
각 변수의 자료형은 속성의 값에 알맞은 것을 선택해야한다. 전원상태(power)의 경우, on과 off 두가지 값을 가질 수 있으므로 boolean형으로 선언했다.

power()의 'power = !power;' 이 문자에서 power의 값이 true면 false로, false면 true로 변경하는 일을 한다. power의 값에 관계없이 항상 반대의 값으로 변경해주면 되므로 굳이 if문을 사용할 필요가 없다. 참고로 if문을 사용하여 코드를 작성하면 다음과 같다.

                          if (power) //if (power == true)
                              power = false;
                          else 
                              power = true;
                              

2.4 인스턴스의 생성과 사용

Tv클래스를 선언한 것은 Tv설계도를 작성한 것에 불과하므로 , Tv인스턴스를 생성해야제품(Tv)을 사용할 수 있다. 클래스로부터 인스턴스를 생성하는 방법은 여러 가지가 있지만 일반적으로는 다음과 같이 한다.

클래스명 변수명; 			    //클래스의 객체를 참조하기 위한 참조변수를 선언
변수명 = new 클래스명();		//클래스의 객체를 생성 후, 객체의 주소를 참조변수를 저장

Tv= t;						//Tv클래스 타입의 참조변수 t를 선언
t = new Tv();				//Tv인스턴스를 생성한 후, 생성된 Tv인스턴스의 주소를 t에 저장 

                              

이후에 실습예제 6-1 나의 github (https://github.com/azsx92/JavaStudy) 여기에다가 작성할 예정이다.

인스턴스와 참조변수의 관계는 마치 우리가 일상생활에서 사용하는 TV와 TV리모컨의 관계와 같다. TV리모콘(참조변수)을 사용하여 TV(인스턴스)를 다루기 때문이다. 다른 점이 라면, 인스턴스는 오직 참조변수를 통해서만 다를 수가 있는것이다.
그리고 TV를 사용하려면 TV 리모콘을 사용해야하고, 에어콘을 사용하려면 , 에어콘 리모콘을 사용해야하는 것처럼 TV인스턴스를 사용하려면 , Tv클래스 타입의 참조변수기 필요한 것이다.
인스턴스는 참조변수를 통해서만 다를 수 있으며, 참조변수의 타입의 인스턴스의 타입과 일치해야한다.
이후에 실습예제 6-2 ,6-3 나의 github (https://github.com/azsx92/JavaStudy) 여기에다가 작성할 예정이다.

2.5 객체 배열

많은 수의 객체를 다뤄야할 때, 배열로 다루면 펀리할 것이다. 객체 역시 배열로 다루는 것이 가능하며, 이를 '객체밸열'이라고 한다. 그렇다고 객체 배열 안에 저장되는 것은 아니고, 객체의 주소가 저장된다. 사실 객체 배열은 참조변수들을 하나로 묶은 참조변수 배열인 것이다.

실습예제 6-4 나의 github (https://github.com/azsx92/JavaStudy) 여기에다가 작성할 예정이다.

2.6 클래스의 또 다른 정의

클래스는 '객체를 생성하기 위한 틀'이며 '클래스'는 속성과 기능으로 정의되어있다.'고 했다. 이것은 객체지향이론의 관점에서 내린 정의이고, 이번엔 프로그래밍적인 관점에서 클래스의 정의와 의미를 살펴보도록 하자.
변수 --> 배열 --> 구조체 --> 클래스
그림 6-3 데이터 저장개념의 발전과정

  1. 변수 하나의 데이터를 저장할 수 있는 공간
  2. 배열 같은 종류의 여러 데이터를 하나의 집합으로 저장할 수 있는 공간
  3. 구조체 서로 관계없이 하나의 집합으로 저장할 수 있는 공간
  4. 클래스 데이터의 함수의 결합(구조체 + 함수)

하나의 데이터를 저장하기 위해 변수를, 그리고 같은 종류의 데이터를 보다 효율적으로 다루기 위해서 배열이라는 개념을 도입했으며 , 후에는 구조체(structure)가 등장하여 자료형의 종류에 상관없이 서로 관계가 깊은 변수들을 하나로 묶어서 다룰 수 있도록 했다.

그동안 데이터와 함수가 서로 관계가 없는 것처럼 데이터는 데이터끼리, 함수는 함수끼리 따로 다루어져 왔지만, 사실 함수는 주로 데이터를 가지고 작업하기 하기 때문에 많은 경우에 있어서 데이터와 함수는 관계가 깊다.
그래서 자바와 같은 객체지향언어에서는 변수(데이터)와 함수를 하나의 클래스의 정의하여 서로 관계가 깊은 변수와 함수들은 함계 다룰 수 있게 됐다.
서로 관련된 변수들을 정의하고 이들에 대한 작업을 수행하는 함수들을 함계 정의한 것이 바로 클래스이다. C언어에서는 문자열을 문자의 배열로 다루지만, 자바에서는 String이라는 클래스로 문자열을 다룬다. 문자열을 단순히 문자의 배열로 정의하지 않고 클래스로 정의한 이유는 문자열과 문자열을 다루는데 필요한 함수들을 함께 묶기 위해서이다.

pubic final class  String implement java.io.Serializable, Comparble {
	privat  char[] value; 	// 문자열을 저장하기 위한 공간
}
pubic String replace(char oldChar , char newChar) {
	char[] val = value;    //같은 클래스 내의 변수를 사용해서 작업을 한다.
}

위 코드는 String 클래스의 실제 소스의 일부이다. 클래스 내부에 value라는 문자형 배열이 선언되어 있고, 문자열을 다루는 데 필요한 함수들을 함께 정의해 놓았다. 문자열의 일부를 뽑아내는 함수나 문자열의 길이를 알아내는 함수들은 항상 문자열을 작업대상으로 필요로 하기 때문에 문자열과 깊은 관계에 있으므로 함께 정의하였다.
이렇게 하면 변수와 함수가 서로 유기적으로 연결되어 작업이 간단하고 명료해진다.

          
profile
백엔드 개발 성장기

0개의 댓글