티스토리 뷰

 

1. 객체지향언어의 주요 특징


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

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

3. 신뢰성이 높은 프로그래밍을 가능하게 한다.
- 제어자와 메소드를 이용해서 데이터를 보호하고 올바른 값을 유지하도록 하며, 코드의 중복을 제거하여 코드의 
  불일치로 인한 오동작을 방지할 수 있다.

객체지향언어의 가장 큰 장점은 "코드의 재사용성이 높고 유지보수가 용이하다." 는 것이다.

 

 

2. 클래스와 객체


클래스의 정의 : 객체를 정의해 놓은 것, 객체의 설계도 또는 틀
클래스의 용도 : 객체를 생성하는데 사용됨.
(ex TV 설계도(클래스), TV라는 제품(객체) / 붕어빵 틀(클래스), 붕어빵(객체) )

프로그래밍에서의 객체는 클래스에 정의된 내용대로 메모리에 생성된 것을 뜻함.

JDK(Java Development Kit) 에서는 프로그래밍을 위해 많은 수의 유용한 클래스 (Java API)를 기본적으로 제공하고 있으며, 개발자들은 이 클래스들을 이용해서 원하는 기능의 프로그램을 보다 쉽게 작성할 수 있다.

 

 

3. 객체와 인스턴스


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

인스턴스와 객체는 같은 의미이지만, 객체는 모든 인스턴스를 대표하는 포괄적인 의미를 갖고 있으며,
인스턴스는 어떤 클래스로부터 만들어진 것인가를 강조하는 보다 구체적인 의미를 갖고 있다.
(ex 'TV는 객체이다.' , 'TV는 TV 클래스의 인스턴스이다.' )

인스턴스는 참조변수를 통해서만 다룰 수 있으며, 참조변수의 타입은 인스턴스의 타입과 일치해야 한다.

자신을 참조하고 있는 참조변수가 하나도 없는 인스턴스는 더 이상 사용되어질 수 없으므로 '가비지 컬렉터(Garbage Collector)' 에 의해서 자동적으로 메모리에서 제거된다.

참조변수에는 하나의 값(주소) 만이 저장될 수 있으므로 둘 이상의 참조변수가 하나의 인스턴스를 가리키는(참조하는) 것은 가능하지만 하나의 참조변수로 여러 개의 인스턴스를 가리키는 것은 가능하지 않다. 

 

 

4. 객체 배열


객체 역시 배열로 다루는 것이 가능하며 이를 '객체 배열' 이라고 함.
객체 배열 안에 객체가 저장되는 것은 아니고, 객체의 주소가 저장됨.
즉, 객체 배열은 참조변수들을 하나로 묶은 참조변수 배열인 것이다.

모든 배열이 그렇듯이 객체 배열도 같은 타입의 객체만 저장할 수 있다.
하지만 '다형성(polymorphism)'을 이용하면 하나의 배열로 여러 종류의 객체를 저장할 수 있게 된다.

 

예제)

TV[] tvArr = new Tv[3];

위의 코드에서 길이가 3인 객체 배열을 생성하였다.

 

현재 위의 그림과 같은 상황이다. 객체를 다루기 위한 참조 변수(tvArr[0], tvArr[1], tvArr[2]) 들이 만들어 진 것일 뿐, 아직 객체가 저장된 것은 아니다.

(참조 변수의 초기값은 null 이므로 각 참조 변수에는 null값이 저장되어 있음)

 

 

5. 프로그래밍적인 관점에서의 클래스 정의


  • 데이터와 함수의 결합
  • 사용자정의 타입 (user-defined type)

 

 

6. 선언위치에 따른 변수의 종류


변수는 클래스변수, 인스턴스변수, 지역변수 모두 세 종류가 있다.
변수의 종류를 결정짓는 중요한 요소는 '변수의 선언된 위치' 이다.
멤버변수를 제외한 나머지 변수들은 모두 지역변수이며, 멤버변수 중 'static'이 붙은 것은 클래스변수,
'static'이 붙지 않은 것은 인스턴스변수 이다.

  • 인스턴스변수(instance variable)
    클래스 영역에서 선언되며, 클래스의 인스턴스를 생성할 때 만들어진다.
    즉, 먼저 인스턴스를 생성해야 인스턴스 변수의 값을 읽어오거나 저장할 수 있다.
    인스턴스마다 고유한 상태를 유지해야하는 속성의 경우, 인스턴스변수로 선언한다.

  • 클래스변수(class variable)
    클래스 변수를 선언하는 방법은 인스턴스변수 앞에 static 키워드를 붙이기만 하면 된다.
    인스턴스마다 독립적인 저장공간을 갖는 인스턴스변수와는 달리, 클래스변수는 모든 인스턴스가 공통된
    저장공간(변수)을 공유하게 된다.

    클래스변수는 인스턴스변수와 달리 인스턴스를 생성하지 않고도 언제라도 바로 사용할 수 있다는 특징이
    있으며, '클래스명.클래스변수' 와 같은 형식으로 접근 가능하다.

    클래스가 메모리에 '로딩(loading)' 될 때 생성되어 프로그램이 종료될 때 까지 유지되며,
    public을 앞에 붙이면 같은 프로그램 내에서 어디서나 접근할 수 있는 '전역변수' 의 성격을 갖는다.

  • 지역변수(local variable)
    메서드 내에 선언되어 메서드 내에서만 사용 가능하며, 메서드가 종료되면 소멸되어 사용할 수 없게 된다.
    for문 또는 while문의 블럭 내에 선언된 지역변수는, 지역변수가 선언된 블럭{} 내에서만 사용가능하며,
    블럭{}을 벗어나면 소멸되어 사용할 수 없게 된다.

 

 

7. 값에 의한 호출 (Call By Value) & 참조에 의한 호출 (Call By Reference)


자바에서는 메서드를 호출할 때 매개변수로 지정한 값을 메서드의 매개변수에 복사해서 넘겨준다.
매개변수 타입이 기본형 (primitive type) 일 때는 기본형 값이 복사되겠지만, 참조형 (reference type) 이면
인스턴스의 주소가 복사된다.
메서드의 매개변수를 기본형으로 선언하면 단순히 저장된 값만 얻지만, 참조형으로 선언하면 값이 저장된 곳의 주소를 알 수 있기 때문에 값을 읽어오는 것은 물론 값을 변경하는 것도 가능하다.

  • 기본형 매개변수 -> 변수의 값을 읽기만 할 수 있다. (read only, call by value)
  • 참조형 매개변수 -> 변수의 값을 읽고 변경할 수 있다. (read & write, call by reference)

 

 

8. 클래스 메서드(static 메서드, 정적 메서드)와 인스턴스 메서드


변수와 마찬가지로, 메서드 앞에 static이 붙어 있으면 클래스 메서드이고 static이 붙어 있지 않으면 인스턴스 메서드이다.
클래스 메서드도 클래스변수처럼 객체를 생성하지 않고도 '클래스명.메서드이름(매개변수)'와 같은 식으로 호출이 가능하다. (반면, 인스턴스 메서드는 반드시 객체를 생성해야만 호출할 수 있다.)

일반적으로, 메서드 중에서 인스턴스와 관계없는 (인스턴스 변수나 인스턴스 메서드를 사용하지 않는) 메서드를 클래스 메서드(static 메서드, 정적 메서드)로 정의한다.

클래스 메서드는 인스턴스변수를 사용할 수 없다. 인스턴스변수는 인스턴스가 반드시 존재해야만 사용할 수 있는데, 클래스 메서드는 인스턴스 생성 없이 호출 가능하므로 클래스 메서드가 호출되었을 때 인스턴스가 존재하지 않을 수 있다. 그래서 클래스 메서드에서 인스턴스변수의 사용을 금지한다.
(반면, 인스턴스변수나 인스턴스메서드에서는 static이 붙은 멤버들을 언제나 사용 가능하다)

인스턴스 멤버가 존재하는 시점에 클래스 멤버는 항상 존재하지만, 클래스 멤버가 존재하는 시점에 인스턴스 멤버는 존재하지 않을 수도 있다.

 

 

9. 메서드 오버로딩 (Overloading)


자바에서는 한 클래스 내에 이미 사용하려는 이름과 같은 이름을 가진 메서드가 있더라도
매개변수의 개수 또는 타입이 다르면, 같은 이름을 사용해서 메서드를 정의할 수 있다.

이처럼, 한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것을
'메서드 오버로딩'
혹은 '오버로딩' 이라 한다. 

메서드 오버로딩의 조건
  1. 메서드 이름이 같아야 한다.
  2. 매개변수의 개수 또는 타입이 달라야 한다.

 

 

10. 가변인자(varargs)와 오버로딩


JDK1.5부터 메서드의 매개변수를 동적으로 지정해 줄 수 있게 되었다.
이 기능을 '가변인자(variable arguments)'라고 한다.

가변인자는 '타입... 변수명' 과 같은 형식으로 선언한다.

가변인자 외에도 매개변수가 더 있다면, 가변인자를 매개변수 중에서 가장 마지막에 선언해야 한다.
그렇지 않으면 컴파일 에러가 발생한다.

가변인자를 선언한 메서드를 오버로딩 할 때는 꼭 매개변수가 구분될 수 있는 지 확인하여야 한다.

가변인자를 선언한 메서드를 오버로딩하면, 메서드를 호출했을 때 구별되지 못하는 경우가 발생하기 쉽기 때문에
가능하면 가변인자를 사용한 메서드는 오버로딩하지 않는 것이 좋다.

 

 

11. 생성자


생성자는 인스턴스가 생성될 때 호출되는 '인스턴스 초기화 메서드' 이다.
따라서 인스턴스 변수의 초기화 작업에 주로 사용되며, 
인스턴스 생성 시에 실행되어야 할 작업을 위해서도 사용된다.
연산자 new가 인스턴스를 생성하는 것이지 생성자가 인스턴스를 생성하는 것이 아니다.
생성자는 단순히 인스턴스 변수들의 초기화에 사용되는 조금 특별한 메서드일 뿐이다.

생성자의 조건 
  1. 생성자의 이름은 클래스의 이름과 같아야 한다.
  2. 생성자는 리턴 값이 없다.
기본 생성자(default constructor)
- 컴파일 할 때, 소스파일의 클래스에 생성자가 하나도 정의되어 있지 않은 경우 컴파일러는 자동적으로
  기본 생성자를 자동으로 생성하여 컴파일 한다.
  (컴파일러가 자동적으로 기본 생성자를 추가해주는 경우는 '클래스 내에 생성자가 하나도 없을 때' 뿐이다.)

this & this(), this(매개변수)
  • this 
    인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어 있다.
    모든 인스턴스 메서드에 지역변수로 숨겨진 채로 존재한다.
    클래스 메서드(static 메서드) 에서는 this를 사용할 수 없다.
    (static 메서드는 인스턴스를 생성하지 않고도 호출될 수 있으므로 static 메서드가 호출된 시점에
    인스턴스가 존재하지 않을 수도 있기 때문이다.)
  • this(), this(매개변수)
    생성자, 같은 클래스의 다른 생성자를 호출할 때 사용한다.
    한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다.
    (해당 생성자에서 호출하려는 다른 생성자의 이름 대신에 this를 사용, 생성자명을 그대로 쓰면 에러)

    -> this와 this()는 생김새만 비슷할 뿐 완전히 다른 것이다. this는 '참조변수' 이고, this()는 '생성자' 이다.

 

 

참고자료


남궁 성 지음, Java의 정석 3rd Edition,도우출판.

'프로그래밍 언어 > Java' 카테고리의 다른 글

객체지향 프로그래밍3  (0) 2019.06.06
객체지향 프로그래밍2  (0) 2019.06.04
변수에 대해  (0) 2019.06.02
자바언어의 특징  (0) 2019.06.02
JVM 이란?  (0) 2018.11.06