스터디/JAVA

[자바의 정석] 6. 객체지향 프로그래밍 I

멩주 2022. 10. 6. 01:03

1. 객체 지향 언어

  • 객체란?
    • 현실세계의 실제 사물, 개념을 속성과 기능으로 정의한 것.
  • 객체지향 프로그램이란?
    • 객체간의 상호작용을 통해 프로그램 진행
  • 객체지향의 특징 4가지
    • 캡슐화: 객체의 속성과 기능을 묶어 외부로부터 보호하는 것
    • 상속: 공통된 기능을 뽑아 부모 객체를 만들며 기존 클래스를 재사용해 새로운 클래스를 만들어 기능을 확장한다.
    • 다형성: 역할과 구현을 분리해
    • 추상화:
  • 객체지향 언어의 주요 특징
    1. 코드의 재사용성이 높다.
      • 새로운 코드 작성 시 기존의 코드를 이용하여 쉽게 작성할 수 있다.
    2. 코드의 관리가 용이하다. (유지보수)
      • 코드간의 관계를 이용해 코드를 변경할 수 있다.
    3. 신뢰성 높은 프로그래밍을 가능하게 한다.
      • 제어자와 메서드를 사용해 데이터를 보호할 수 있으며 중복 코드를 제거한다.

 

2. 클래스와 객체

  • 클래스란?
    • 객체의 설계도/틀 이라고 할 수 있다. 속성과 기능을 가지고 있으며 객체를 생성할 때 사용한다.
  • 객체와 인스턴스
    • 클래스를 사용해 객체를 만드는 것을 “인스턴스화”라고 한다.
    • 만들어진 객체를 클래스의 인스턴스라고 한다.
  • 객체의 구성 요소
    • 객체는 속성(멤버 변수)과 기능(메서드)로 이루어져 있다.
  • 인스턴스 생성
    • TV t = new TV();
    • 참조변수 t는 생성된 인스턴스의 주소를 가지고 있다.
    • 인스턴스는 참조변수를 통해서만 다룰 수 있으며 참조변수의 타입은 인스턴스 타입과 일치해야 한다!
    • 자신을 참조하는 참조변수가 하나도 없는 인스턴스는 **GC(가비지 컬랙션)**에 의해 삭제된다.

2.5 객체 배열

  • 많은 수의 객체를 다뤄야할 때, 참조변수 배열로 다룰 수 있다.
  • 객체 배열안에 객체의 주소가 저장된다.
  • TV[] tvArr = new TV[3];
    • 이는 객체 배열을 생성할 뿐, 객체를 생성한 것은 아니다. NULL

2.6 클래스

  1. 데이터와 함수의 결합
    • 변수: 하나의 데이터를 저장할 수 있는 공간
    • 배열: 같은 종류의 데이터를 하나의 집합으로 저장할 수 있는 공간
    • 구조체: 다른 종류의 데이터를 하나의 집합으로 저장할 수 있는 공간
    • 클래스: 데이터와 함수의 결합 (구조체 + 메서드)
  2. 사용자 정의 타입
    • 기본형 8개 이외에 사용자가 변수들을 묶어 정의한 것

 

3. 변수와 메서드

  • 위치에 따라
    • 클래스 영역
      • 멤버 변수
        • 클래스 변수: 클래스가 메모리에 올라갔을 경우
        • 인스턴스 변수: 인스턴스 생성 시
    • 메서드 영역
      • 지역변수: 변수 선언문 실행
  1. 클래스 변수
    • 같은 클래스로 만들어진 인스턴스가 공유하는 변수
  2. 인스턴스 변수
    • 각 인스턴스마다 고유한 변수

3.3 메서드

  • 메서드 사용 이유
    1. 재사용성
    2. 중복 코드 제거
    3. 프로그램 구조화

3.7 JVM 메모리 구조

  • 3가지 주요 영역으로 나뉜다.
    1. Method Area
      • 클래스 데이터
    2. Call stack
      • 메서드 작업에 필요한 메모리 공간 제공
      • 지역변수(매개변수 포함)과 연산의 중간 결과 등을 저장한다.
      • 메서드가 작업을 마치면 메모리 공간은 반환된다.
    3. Heap
      • 인스턴스 변수가 생성되는 공간
      • GC이 활동하는 공간
  • 호출 스택(call stack) 실행 순서
    1. 첫 번째로 호출된 메서드를 위한 공간이 호출 스택에 생성된다.
    2. 메서드 실행 중 다른 메서드를 호출하게 되면 콜스택 맨 위에 두번째 메서드를 위한 공간이 할당되고 두 번째 메서드가 실행된다.
    3. 두 번째로 실행한 메서드가 종료되면 해당 호출스택 메모리가 반환되고 첫 번째 메서드가 이어서 실행된다.
    4. 첫 번째 실행 메서드가 종료되면 이 또한 메모리가 반환된다.
  • 특징
    • 메서드가 호출되면 수행에 필요한 만큼의 메모리를 스택에 할당받는다.
    • 메서드가 수행을 마치면 메모리가 반환되고 스택에서 제거된다.
    • 호출스택은 아래부터 쌓이며 맨 위에 있는 메서드가 실행중인 메서드이다.
    • 아래에 있는 메서드는 위의 메서드를 호출한 메서드이다.

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

  • 기본형(primitive type) 매개변수
    • 기본형 값이 복사
    • 변수의 값을 읽기만 할 수 있다.
    • 메서드 안에서의 값 변경은 원래 값에 영향을 미치지 않는다.
  • 참조형(reference type) 매개변수
    • 인스턴스의 주소가 복사
    • 변수의 값을 읽고 변경할 수 있다.
    • 메서드 안에서의 값 변경이 원래 값에 영향을 미친다.

3.9 참조형 반환 타입

  • 반환타입이 참조형이라는 것은 메서드가 객체의 주소를 반환한다는 것
  • 모든 참조형 타입의 값은 객체의 주소

3.10 재귀호출

  • 메서드 내부에서 메서드 자신을 다시 호출하는 것을 재귀호출이라고 한다.
  • 재귀호출은 조건문이 필수적이다.
  • 반복문과 재귀호출의 차이
    • 반복문은 그저 같은 문장을 반복해 수행한다.
    • 메서드를 호출하는 것은 매개변수 복사, 종료 후 복귀 주소저장 등 추가로 필요한 것이 많기 때문에 수행 시간이 반복문보다 오래 걸린다.
    • 재귀호출에 드는 비용보다 재귀호출이 주는 간결함이 주는 이득이 클 경우 사용해야 한다.
  • call stack에는 메서드와 지역변수들이 차곡차곡 쌓인다. 저장 한계를 넘게 되면 Stack Overflow Error가 발생한다.

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

  • 클래스 메서드는 클래스 변수와 같이 객체를 생성하지 않더라도 {클래스명}.{메서드명}으로 호출이 가능하다.
  • 반면에 인스턴스 메서드는 객체 생성 이후에 호출이 가능하다.
  • 클래스 메서드
    • 인스턴스와 관계없는(인스턴스 변수/메서드를 사용하지 않는) 메서드
  • 인스턴스 메서드
    • 메서드 작업을 수행하는데 인스턴스 변수를 필요로 하는 메서드
  • 특징
    1. 클래스 설계시, 멤버변수 중 모든 인스턴스에 공통으로 사용되는 변수는 static을 붙인다.
    2. 클래스 변수는 인스턴스 생성 없어도 사용 가능하다.
    3. 클래스 메서드는 인스턴스 변수/메서드를 사용할 수 없다.
    4. 메서드 내 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려해라

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

  • 같은 클래스 내의 멤버간에는 인스턴스 생성 없이 호출이 가능하다.
  • 단, 클래스 멤버는 인스턴스 멤버를 참조할 수 없다.
    • 인스턴스 멤버가 존재하는 시점에 클래스 멤버 존재.
    • 클래스 멤버가 존재하는 시점에는 인스턴스 멤버가 존재함을 확정할 수 없다.

 

4. 오버로딩(Overloading)

  • 같은 클래스 내에서 이름이 동일한 메서드를 여러개 선언하는 것

4.2 조건

  1. 메서드 이름 동일
  2. 매개변수의 개수 혹은 타입이 달라야한다.
  3. 반환타입은 오버로딩 구현에 영향을 주지 않는다.
  • 예)
    • void println();
    • void pringln(char[] c);

4.4 오버로딩의 장점

  • 메서드명을 통일함으로써 어떤 기능인지 예측할 수 있다.
  • 메서드 이름 절약

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

  • 예)
    • public String concatenate(String … args) {}
      • String과 여러개의 Object가 매개변수로 들어갈 수 있다.
    • concatenate(”a”); // 가능
    • concatenate(”a”, “A”); // 가능
  • 주의점
    • 가변인자는 항상 마지막 매개변수여야 한다.
    • 가변인자를 사용한 메서드는 오버로딩하지 않는 것이 좋다.

 

5. 생성자(Constructor)

  • 인스턴스 생성 시 호출되는 인스턴스 초기화 메서드
  • 조건
    1. 생성자의 이름은 클래스명과 동일해야 한다.
    2. 생성자는 리턴값이 없다.
  • 오버로딩 가능

5.2 기본 생성자

  • 클래스에 생성자가 없는 경우, 컴파일러가 자동으로 기본 생성자(매개변수 없는)를 추가해 컴파일 한다.

5.3 매개변수가 있는 생성자

  • 매개변수를 이용해 인스턴스의 값을 초기화 한다.

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

  • 조건
    • 생성자의 이름으로 클래스이름 다신 this를 사용한다.
    • 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에 호출해야 한다.
  • this
    • 인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어있다.
    • 모든 인스턴스 메서드에 지역변수로 숨겨진 채 존재한다.
  • this(), this(매개변수)
    • 생성자, 같은 클래스의 다른 생성자 호출에 사용한다.

5.5 생성자를 이용한 인스턴스 복사

Car(Car c) {
	color = c.color;
	gearType = c.gearType;
}
  • 생성자를 사용해 인스턴스를 복사할 수 있다.
  • 생성자를 잘 활용하면 보다 간결하고 직관적인, 객체지향적인 코드를 작성할 수 있을 것이다.
  • 인스턴스 생성 시 결정
    1. 클래스 - 어떤 클래스의 인스턴스를 생성할 것인가
    2. 생성자 - 어떤 생성자로 인스턴스를 생성할 것인가

 

6. 변수의 초기화

  • 멤버 변수(클래스, 인스턴스 변수)는 자동으로 변수 자료형에 맞는 기본값으로 초기화 된다. (선택)
  • 지역변수는 사용하기 전 반드시 초기화해야 한다. (필수)
  • 멤버변수의 초기화 방법
    1. 명시적 초기화
    2. 생성자
    3. 초기화 블럭
      1. 인스턴스 초기화 블럭
      2. 클래스 초기화 블럭

6.2 명시적 초기화

  • 변수를 선언과 동시에 초기화
class Car{
	int door = 4;
	Engine e = new Engine();
}

6.3 초기화 블럭

  • 복잡한 초기화 작업이 필요할 경우 사용한다.
  • 클래스 초기화 블럭
  • 인스턴스 초기화 블럭
class InitBook{
	static {/*클래스 초기화 블럭*/}
	{/*인스턴스 초기화 블럭*/}
}
  • 클래스 초기화 블럭은 클래스가 메모리에 처음 로딩될 때 한번만 수행된다.
  • 인스턴스 초기화 블럭은 인스턴스 생성할 때 마다 수행된다.
    • 동콩으로 수행해야 하는 코드
  • 효과
    • 코드 중복을 제거해 코드의 신뢰성 증가 (재사용성)
    • 오류를 줄여준다.

6.4 멤버변수의 초기화 시기와 순서

  • 클래스 변수의 초기화 시점
    • 클래스가 처음 로딩될 때 단 한번 초기화
  • 인스턴스 변수의 초기화 시점
    • 인스턴스가 생성될 때마다 각 인스턴스별로 초기화
  • 클래스 변수의 초기화 순서
    • 기본값 → 명시적 초기화 → 클래스 초기화 블럭
  • 인스턴스 변수의 초기화 순서
    • 기본값 → 명시적 초기화 → 인스턴스 초기화 블럭 → 생성자

<질문>

  •  

1. 객체지향 프로그래밍이란?

더보기

객체란 실제 존재하는 사물이나 개념을 속성과 기능로 구현한 것으로 객체 지향 프로그래밍은 객체의 상호작용을 통해 프로그램을 만드는 것을 뜻합니다.

 

2. 객체지향의 특징과 장점을 말해주세요

더보기

객체지향의 특징은 캡슐화, 상속, 다형성, 추상화가 있고 이로인해 코드의 재사용성을 높이고 코드의 관리가 용이해 유지보수가 쉽고 중복을 최소화해 신뢰성있는 프로그램을 만들 수 있습니다.

 

3. 클래스와 객체의 차이를 말해주세요

더보기

클래스는 객체를 만들 수 있는 틀을 의미하고 변수나 메서드를 가지고 있습니다.

클래스를 참조해 실제 객체로 만든 것을 인스턴스라고 합니다.

 

4. 객체와 인스턴스의 차이를 말해주세요

더보기

클래스로부터 객체를 만드는 것을 인스턴스화라고 하며 인스턴스는 실제 메모리에 올라간 객체 각각을 의미합니다.

객체는 모든 인스턴스를 대표한다.

 

5. 객체의 구성요소에 대해 말해주세요

더보기

객체는 속성(멤버변수)과 기능(메소드)으로 이루어져 있습니다.

 

6. 자신을 참조하는 참조변수가 없다면 어떻게 되나요?

더보기

자신을 참조하는 참조변수가 없다면 해당 인스턴스는 더이상 사용할 수 없어져 가비지컬렉터에 의해 삭제됩니다.

 

7. 선언 위치에 따른 변수의 종류에 대해 말해주세요

더보기

변수는 클래스 영역에 만들어지는 것은 클래스 변수, 인스턴스 변수가 있고 메서드 영역에서 만들어지는 지역 변수가 있습니다.

클래스 변수는 클래스가 메모리에 올라갔을 때 생성되며 인스턴스 변수는 인스턴스가 생성되었을 때 생성됩니다.

지역변수는 변수 선언문이 시작되면 생성됩니다.

인스턴스 변수는 각각의 인스턴스마다 고유한 값을 가지고, 클래스 변수는 모든 인스턴스가 공유하는 변수입니다.

 

8. 메서드 사용하는 이유에 대해 말해주세요

더보기

메서드를 사용하면 코드의 재사용성을 높일 수 있고, 중복된 코드를 제거할 수 있으며 프로그램 구조를 단순화할 수 있습니다.

 

9. 재귀호출이란 무엇인가요? 

더보기

재귀호출이란 메서드 내부에서 자기 자신을 호출하는 것입니다.

재귀호출은 무한히 자기 자신을 호출하게 되어 스택 오버플로우가 생길 수 있어 조건문으로 재귀호출을 빠져나올 수 있게 작성해야 합니다. 

 

10. 인스턴스 멤버와 static 멤버의 차이

더보기

static 멤버는 클래스가 메모리에 올라갈 때 생성되며 모든 인스턴스에서 공유됩니다.

인스턴스 멤버는 인스턴스가 생성될 때 생성되며 각각의 인스턴스가 고유한(독립적인) 값을 가집니다.

 

11. 오버로딩과 오버라이딩

더보기

오버로딩은 같은 메서드 이름으로 매개변수의 개수나 타입을 다르게해 여러 메서드를 만드는 것 입니다.

메서드 명을 통일해 메서드의 역할을 예측할 수 있고 메서드 명을 줄일 수 있습니다.

 

오버라이딩은 상위 객체의 메서드를 하위 객체에서 재정의하는 것으로 기능의 확장을 위해 주로 사용됩니다.

 

12. this.과 this 생성자의 차이

더보기

this.은 해당 인스턴스의 변수에 접근하기 위해 사용하며 this 생성자는 생성자 안에서 또다른 생성자를 부르기 위해 사용합니다. 

한 생성자 안에서 다른 생성자를 호출할 때는 반드시 첫줄에서 호출해야 합니다.

 

13. 생성자란 무엇인가요

더보기

인스턴스가 생성될 때 호출되는 인스턴스 초기화 메서드입니다.

 

14. JVM 메모리 구조에 대해 설명해주세요

더보기

JVM 메모리 구조는 크게 메소드 영역, 콜 스택, 힙으로 이루어져 있습니다.

메소드 영역에는 클래스 멤버가 있고 콜 스택에는 실행하는 메서드가 차례대로 적재되어 있으며 가장 위에 있는 메서드가 현재 실행하는 메서드입니다. 힙 영역에는 생성된 인스턴스 멤버가 들어있으며 가비지컬렉터(GC)에 의해 관리됩니다.