Programming/Java \ Spring

🔥자바스터디🔥 자바의 정석 CH6 객체지향 프로그래밍(클래스, 메소드, 오버로딩, 생성자)

 

1. 객체지향언어

       - 객체지향이론 개념 : 실제 세계는 사물(객체)로 이루어져 있으며, 발생하는 모든 사건들은 사물간의 상호작용이다.

 

1.1 객체지향언어

    <특징>

     - 코드의 재사용성이 높다. (기존코드를 이용하여 쉽게 작성)

     - 코드의 관리가 용이하다. (코드간의 관계를 이용해서 쉽게 변경가능 - 유지보수)

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

       (제어자와 메소드를 이용해서 데이터를 보호 및 올바른 값을 유지하도록 하며,

        코드의 중복을 제거하여 코드의 불일치로 인한 오동작을 방지할 수 있다. )

 

2. 클래스와 객체

 

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

 

      클래스의 정의 : 객체를 정의해 놓은것

      클래스의 용도 : 객체를 생성하는데 사용

      객체의 정의 : 클래스에 정의된 내용대로 메모리에 생성된 것

      객체의 용도 : 객체가 가지고 있는 기능(메소드)과 속성(필드)에 따라 다름

 

2.2 객체와 인스턴스

 

      - 클래스로부터 객체를 만드는 과정을 클래스의 인스턴스화

      - 클래스로부터 만들어진 객체를 그 클래스의 인스턴스

 

2.4 인스턴스의 생성과 사용

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

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

t.channer;               // TV인스턴스의 필드 호출
t.channerlDown();        // TV인스턴스의 메소드 호출

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

- 같은 클래스로부터 생성된 인스턴스는 각각의 속성(필드)값을 유지할 수 있으며, 각 인스턴스의 메소드의 내용은 동일하다.

- 하나의 인스턴스를 여러개의 참조변수가 가리키는 것은 가능하나, 하나의 참조변수가 여러 인스턴스를 가리키는 것을 불가능하다.

 

2.5 객체 배열

 

    - 인스턴스 배열은 참조변수들을 하나로 묶은 참조변수 배열이다. (배열안에 객체의 주소가 저장 / 초기화값 null)

 

2.6 클래스의 또 다른 정의

 

    1) 클래스 : 데이터와 함수의 결합 (필드와 메소드로 구성된 것을 의미)

    2) 클래스 : 사용자 정의 타입

         - 사용자 정의 타입(클래스) : 자료형 외에 사용자가 서로 관련된 변수를 묶어 하나의 타입으로 새로 추가하는 것

 

3. 변수와 메소드

 

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

 필드를 제외한 나머지 변수는 모두 지역변수,

 필드 중 static이 붙은 것은 클래스 변수, 붙지 않은 것은 인스턴스 변수이다.

 

(자세한 내용은 CLICK 하세요)

 

3.3 메소드

 

< 메소드를 사용하는 이유 >

   1. 높은 재사용성

   2. 중복된 코드의 제거

      (전체소스코드의 길이가 짧아지고, 변경사항 발생시 수정해야될 코드의 양이 줄어든다.)

   3. 프로그램의 구조화

      - 작업단위로 나눠서 여러개의 메소드에 담아 프로그램의 구조를 단순화 시킨다.

 

3.4 메소드의 선언과 구현

메소드 선언부 - 메소드 이름, 매개변수(파라미터) 선언, 반환타입으로 구성

          1. 매개변수 선언 : 메소드 수행시 필요한 값들을 제공받기 위한 것이며,

                                  필요한 만큼 변수의 타입을 생략하지 않고 쉼표로 구분하여 선언한다.

                                  (입력받을 값이 없으면 선언하지 않아도 된다.)

          2. 메소드의 이름 : 메소드의 기능을 쉽게 알수 있도록 네이밍한다.

          3. 반환타입 : 메소드 수행 결과값의 타입을 적는다. 반환값이 없는경우 void를 기재한다.

 

메소드 구현부 - {} 안에 메소드 호출시 수행된 문장들을 적는다.

          1. retun문 : void 가 아닐 경우 'return 반환값;'이 반드시 포함되어야 한다. (반환값은 오직 하나만 반환한다.)

                         반환값을 호출한 메소드 내로 전달하기 때문에 반환타입과 일치하거나 자동 형변환이 가능한 것이어야 한다.

          2. 지역변수 : 서로 다른 메소드에서 같은 이름의 변수를 선언할수 있다.

 

3.5 메소드의 호출

 

인자와 매개변수 - 메소드 호출시 괄호()안에 지정해준 값들을 인자(argument) 또는 인수라 한다.

                          인자의 개수와 순서는 호출된 메소드에 선언된 매개변수(parameter)와 일치해야 한다.

 

메소드의 실행흐름 - 같은 클래스 내의 메소드끼리는 참조변수 없이도 호출 가능하나,

                             static 메소드는 같은 클래스 내의 인스턴스 메소드를 호출할수 없다.

                             (클래스 변수와 인스턴스 변수를 구분한 내용과 일맥상통하다)

 

3.6 return문

 

- 현재 실행중인 메소드를 종료하고 호출한 메소드로 되돌아간다.

  반환값 유무에 관계없이 모든 메소드에 return문이 있어야 하지만,

  반환타입이 void인 경우 컴파일러가 return;을 추가해서 컴파일 에러가 발생하지 않는다.

- if문 내에 return문을 기재할 경우 if문이 실행되지 않을수도 있기 때문에 컴파일 에러가 발생한다.

- return문 내에 반환값이 아닌 수식을 기재해도 해당 수식의 결과값이 반환타입과 같으면 문제되지 않는다.

- 매개변수의 유효성 검사를 통해 먼저 제대로된 결과값을 산출할 수 있는지 확인해야한다.

 

3.7 JVM의 메모리 구조

 

1. 메소드 영역(method area)

     - 프로그램 실행 중 어떤 클래스가 사용되면 JVM은 해당 클래스의 클래스파일(.class)을 읽어 분석 후 클래스 정보를 이곳에 저장한다. 

       클래스 변수도 이영역에 함께 생성된다.

 

2. 힙(heap)

     - 인스턴스가 생성되는 공간

 

3. 호출스택(call stack 또는 execution stack)

     - 메소드의 작업에 필요한 메모리 공간 제공

       메소드가 작업을 수행하는 동안 지역변수(매개변수 포함)들과 연산의 중간결과 등을 저장하는데 사용된다.

       메소드가 작업을 마치면 할당되었던 메모리공간은 반환되어 비워진다.

     - 호출스택 제일 상위에 위치하는 메소드가 현재 실행 중인 메소드이며, 나머지는 대기상태에 있게 된다.

 

** 객체를 생성하지 않고 호출할 수 있으려면 static 을 붙여야한다.

 

3.8 기본형 매개변수와 참조형 매개변수

 

     기본형 매개변수 : 변수의 값을 읽기만 할 수 있다.

     참조형 매개변수 : 인스턴스의 주소를 알수 있기 때문에 변수의 값을 읽고 변경할 수 있다.

 

3.9 참조형 반환타입

 

     - 반환타입이 참조형 이라는 것은 메소드가 객체의 주소를 반환한다는 것을 의미한다.

 

3.10 재귀호출

    

     - 메소드 내부에서 메소드 자신을 다시 호출하는 것

     - 무한 반복을 방지하기 위해 조건문과 함께 사용한다.

     - 논리적 간결함, 단순한 구조 때문에 비효율적이어도 사용되는 경우가 있다.

 

3.11 클래스 메소드(static 메소드)와 인스턴스 메소드

 

     - 인스턴스 메소드는 인스턴스 변수와 관련된 작업을 하는, 즉 메소드의 작업을 수행하는데 인스턴스 변수를 필요로 하는 메소드

     - 인스턴스와 관계없는(인스턴스 변수나 인스턴스 메소드를 사용하지 않는) 메소드를 클래스 메소드(static)로 정의한다.

    

     1) 클래스를 설계할 때, 필드 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.

     2) 클래스변수(static)는 인스턴스를 생성하지 않아도 사용할 수 있따.

     3) 클래스 메소드(static)는 인스턴스 변수를 사용할수 없다.

     4) 메소드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다.

         (메소드 호출시간이 짧아져 성능이 향상된다.)

 

3.12 클래스 멤버와 인스턴스 멤버간의 참조와 호출

 

      - 같은 클래스에 속한 멤버들 간에는 별도의 인스턴스를 생성하지 않고도 서로 참조 또는 호출이 가능하다.

       (인스턴스 멤버가 존재하는 시점에 클래스 멤버는 항상 존재하지만,

        클래스 멤버가 존재하는 시점에 인스턴스 멤버가 존재하지 않을 수도 있기 때문에

        클래스 멤버가 인스턴스 멤버를 참조 또는 호출하고자 하는 경우에는 인스턴스를 생성해야한다.)

MemberCall c = new MemberCall();
int result = c.instanceMethod1();

위의 두줄을 다음과 같이 한 줄로 할 수 있다.

int result = new MemberCall().instanceMethod1();

 

4. 오버로딩

4.1 오버로딩이란?

   

    - 한 클래스 내에 같은 이름의 메소드를 여러개 정의하는 것

 

4.2 오버로딩의 조건

 

    1) 메소드 이름이 같아야 한다.

    2) 매개변수의 개수 또는 타입이 달라야 한다.

 

    ** 반환 타입은 오버로딩을 구별하는데 영향을 주지 못한다.

 

4.3 오버로딩의 장점

 

   - 같은 기능을 하는데 다른 이름을 짓는다면 기억하기 어렵고 오류의 가승성이 있다. 

   - 하나의 이름으로 여러개의 메소드를 정의할수 있다.

 

4.4 가변인자와 오버로딩

 

   - 기존에는 메소드의 매개변수 개수가 고정적이었으나 JDK1.5부터 동적으로 지정해줄수 잇게 되었다. (가변인자)

   - 가변인자의 선언 : 타입... 변수명

   - 가변인자 외에 매개변수가 더 있다면 가변인자를 맨 마지막에 선언해야한다.

   - 가변인자는 내부적으로 배열을 이용하기 때문에 가변인자가 선언된 메소드를 호출할 때마다 배열이 새로 생성된다.

     (가변인자 대신 배열로 하게 되면 반드시 인자를 지정해 주어야하지만 가변인자는 지정하지 않아도 된다.)

   - 가변인자를 선언한 메서드를 오버로딩하면, 메소드 호출시 구별되지 못하는 경우가 발생하기 쉽다.

 

5. 생성자

5.1 생성자란?

  

    - 인스턴스 생성시 호출되는 "인스턴스 초기화 메소드" (인스턴스 변수의 초기화)

   

< 생성자의 조건 >

       1) 생성자의 이름은 클래스의 이름과 같아야 한다.

       2) 생성자는 리턴값이 없다.

 

** 생성자도 오버로딩이 가능하다.

 

5.2 기본 생성자

 

     - 모든 클래스에는 반드시 하나 이상의 생성자가 정의되어 있어야한다.

     - 생성자를 명시하지 않을 경우 컴파일러가 자동적으로 기본 생성자를 추가하여 컴파일 한다.

 

5.3 매개변수가 있는 생성자

   

    - 인스턴스 생성과 동시에 원하는 값으로 초기화 할수 있게 된다.

 

클래스이름(){}
클래스이름(매개변수){}

 

5.4 생성자에서 다른 생성자 호출하기 - this(), this

 

    - 생성자의 이름으로 클래스 이름 대신 this를 사용

    - 한 생성자에서 다른 생성자를 호출할 때 반드시 첫줄에서만 호출이 가능하다.

    - this는 참조변수로 인스턴스 자신을 가리킨다. 따라서, static메소드에서는 사용할수 없다.

    - this(), this(매개변수) 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용한다.

 

6. 변수의 초기화

6.1 변수의 초기화

 

      - 변수를 선언하고 처음으로 값을 저장하는 것을 "변수의 초기화"라고 한다.

      - 지역변수는 사용하기 전에 반드시 초기화해야한다.

 

     < 멤버변수의 초기화 방법 >

       1) 명시적 초기화

       2) 생성자

       3) 초기화 블럭 - 인스턴스 초기화 블럭  / 클래스 초기화 블럭

 

6.2 명시적 초기화

 

      - 변수를 선언과 동시에 초기화 하는 것

   

6.3 초기화 블럭

 

      - 단순히 클래스 내에 블럭{} 만들고 그 안에 코드를 작성

      - 클래스 초기화 블럭은 인스턴스 초기화 블럭 앞에 단순히 static을 붙인다.

      - 클래스 초기화 블럭 > 인스턴스 초기화 블럭 > 생성자 순으로 수행된다.