[JAVA]ch5. 객체지향 프로그래밍(1)

황인권·2024년 6월 1일

JAVA

목록 보기
5/15

1. 객체지향 언어

주요특징

  • 코드의 재사용성이 높다.
  • 코드의 관리가 용이하다.
  • 신뢰성이 높은 프로그래밍을 가능하게 한다.

2. 클래스와 객체

  • 클래스랑 '객체를 정의해 놓은 것' 또는 '객체의 설계도 또는 틀'이라고 정의할 수 있다.

    • 클래스의 정의
      클래스란 객체를 정의해 놓은것이다.
    • 클래스의 용도
      클래스는 객체를 생성하는데 사용된다.
  • 프로그래밍에서 객체는 클래스에 정의된 내용대로 메모리에 생성된 것을 뜻한다.

    • 객체의 정의
      실제로 존재하는 것. 사물 또는 개념
    • 객체의 용도
      객체가 가지고 있는 기능과 속성에 따라 다르다.
    • 유형의 객체
      책상, 의자, 자동차, TV와 같은 사물
    • 무형의 객체
      수하공식, 프로그램 에러와 같은 논리나 개념

객체와 인스턴스

  • 객체는 모든 인스턴스를 대표하는 포괄적인 의미를 갖고 있으며, 인스턴스는 어떤 클래스부터 만들어진 것인지를 강조하는 것보다 구체적인 의미를 가지고 있다.

3. 변수와 메서드

class Variables
{
	int iv;				// 인스턴스 변수
  static int cv;		// 클래스 변수(static 변수, 공유 변수)
    
  void method()
  {
	  int lv = 0;		// 지역 변수
  }
}

인스턴스 변수는 인스턴스가 생성될 때마다 생성되므로 인스턴스마다 각기 다른 값을 유지할 수 있지만, 클래스 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로, 항상 공통된 값을 갖는다.

매서드를 사용하는 이유

  • 높은 재사용성
  • 중복된 코드의 제거
  • 프로그램의 구조화

JVM의 메모리 구조

  • 메서드 영역
    • 프로그램 실행 중 어떤 클래스가 사용되면, JVM은 해당 클래스의 클래스파일(*.class)을 읽어서 분석하여 클래스에 대한 정보(클래스 데이터)를 이곳에 저장한다. 이 때, 그 클래스의 클래스 변수도 이 영역에 함께 생성된다.
    • 인스턴스가 생성되는 공간
    • 프로그램 실행 중 생성되는 인스턴스는 모두 이곳에서 생성된다.
  • 호출 스택(call stack)
    • 호출 스택은 메서드의 작업에 필요한 메모리를 제공한다.

호출 스택의 특징

  • 메서드가 호출되면 수행에 필요한 만큼의 메모리를 스택에 할당 받는다.
  • 메서드가 수행을 마치고나면 사용했던 메모리를 반환하고 스택에서 제거된다.
  • 호출스택의 제일 위에 있는 메서드가 현재 실행 중인 메서드이다.
  • 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드이다.

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

  • 자바에서는 메서드를 호출할 때 매개변수로 지정한 값을 메서드의 매개변수에 복사해서 넘겨준다.
  • 매개변수의 타입이 기본형일 때는 기본형 값이 복사되겠지만, 참조형이면 인스턴스의 주소가 복사된다.

클래스 메서드와 인스턴스 메서드

  • 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.
    • 모든 인스턴스에서 같은 값이 유지되어야 하는 변수는 static을 붙여서 클래스 변수로 정의해야 한다.
  • 클래스변수는 인스턴스를 생성하지 않아도 사용할 수 있다.
    • 클래스가 메모리에 올라갈 때 자동적으로 생성되기 때문이다.
  • 클래스 메서드는 인스턴스 변수를 사용할 수 없다.
    • 인스턴스 변수는 인스턴스가 반드시 존재해야만 사용할 수 있는데, 클래스 메서드는 인스턴스 생성없이 호출이 가능하므로 클래스 메서드가 호출되었을 때 인스턴스가 존재하지 않을 수 있다.
  • 메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다.
    • 메서드 호출 시간이 짧아지므로 성능이 향상된다.

클래스 멤버가 인스턴스 멤버를 참조 또는 호출하고자 하는 경우에는 인스턴스를 생성해야 한다.
-> 인스턴스 멤버가 존재하는 시점에 클래스 멤버는 항상 존재하지만, 클래스 멤버가 존재하는 시점에서 인스턴스 멤버가 존재하지 않을 수 있기 때문이다.


4. 오버로딩

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

오버로딩 의 조건

  • 메서드 이름이 같아야 한다.
  • 매개변수의 개수 또는 타입이 달라야 한다.

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

  • 가변인자는 내부적으로 배열을 이용하는 것이다. 그래서 가변인자가 선언된 메서드를 호출할 때마다 배열이 새로 생성된다.
String concatenate(String... str) {...} // 가변인자 사용
String concatenate(String[] str) { ... }
  • 위 두 함수의 차이는 가변인자를 사용한 함수는 인자를 지정해주지 않아도 된다. 하지만 매개변수 타입을 배열로 하면 반드시 인자를 지정해 줘야 한다.
String concatenate(String delim, String... str) { ... }
String concatenate(String... str) { ... }
  • 위의 두 오버라이딩 된 메서드가 구분되지 않아서 에러가 발생한다. 메서드를 호출했을 때 이와 같이 구별되지 못하는 경우가 쉽기 때문에 주의해야 한다.

5. 생성자

생성자의 조건

  • 생성자의 이름은 클래스의 이름과 같아야 한다.
  • 생성자는 리턴 값이 없다.

인스턴스 생성과정

Card c = new Card();
  • 연산자 new에 의해서 메모리(heap)에 Card클래스의 인스턴스가 생성된다.
  • 생성자 Card()가 호출된다.
  • 연산자 new의 결과로 생성된 Card 인스턴스의 주소가 반환되어 참조변수 c에 저장된다.

    연산자 new가 인스턴스를 생성하는 것이지 생성자가 인스턴스를 생성하는 것이 아니다.

기본 생성자

  • 기본 생성자가 컴파일러에 의해서 추가되는 경우는 클래스에 정의된 생성자가 하나도 없을 때 뿐이다.

생성자에서 다른 생성자 호출하기 위한 조건

  • 생성자의 이름으로 클래스 이름 대신 this를 사용한다.
  • 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다.
Car () {
	this("white", "auto", 4);
}

'this'는 참조변수로 인스턴스 자신을 가리킨다.
모든 인스턴스 메서드에서 지역변수로 숨겨진 채로 존재한다.
'this'를 사용할 수 있는 것은 인스턴스 멤버뿐이다.


6. 변수의 초기화

  • 멤버 변수와 배열의 초기화는 초기화하지 않아도 자동적으로 변수의 자료형에 맞는 기본값으로 초기화되기 때문에 선택적이지만 지역변수는 사용하기 전에 반드시 초기화해야 한다.

명시적 초기화

class Car {
	int door = 4;				// 기본형 변수의 초기화
    Engine e = new Engine();	// 참조형 변수의 초기화
}

초기화 블럭

  • 초기화 작업이 복잡하여 명시적 초기화 만으로는 부족한 경우 초기화 블록을 사용한다. 또한 코드의 중복을 제거하기 위해 사용된다.
class InitBlock {
	static {
    	//클래스 초기화 블럭입니다.
    }
    
    {
    	//인스턴스 초기화 블럭입니다.
    }
}

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

  • 클래스 변수의 초기화 시점 :
    클래스가 처음 로딩될 때 단 한번 초기화 된다.
  • 인스턴스 변수의 초기화 시점 :
    인스턴스가 생성될 때마다 각 인스턴스별로 초기화가 이루어진다.
  • 클래스 변수의 초기화 순서 :
    기본값 -> 명시적 초기화 -> 클래스 초기화 블럭
  • 인스턴스 변수의 초기화 순서 :
    기본값 -> 명시적 초기화 -> 인스턴스 초기화 블럭 -> 생성자
profile
inkwon Hwang

0개의 댓글