[Java의 정석] 6장 객체지향 프로그래밍

이정규·2022년 1월 28일
0

Java의 정석

목록 보기
5/7

객체지향언어

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

객체지향언어의 특징

상속, 다향성과 같은 개념들로 인해 생기는 장점들이다.

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

처음부터 객체지향에 얽매이기 보다는 기능적으로 완성한 후에 차근차근 객체지향적으로 발전시키는게 좋다.

클래스, 객체, 인스턴스

클래스

객체를 정의해놓은 것이다. 실세계에서는 붕어빵 기계이라고 생각하면 된다.

객체

실제로 존재하는 것. 사물 또는 개념이다. 붕어빵이라고 생각하면 된다.

인스턴스

클래스의 인스턴스 == 객체라고 보면 된다.
객체는 모든 클래스의 인스턴스를 대표하는 포괄적인 의미를 갖고 있다.
인스턴스는 어떤 클래스로부터 만들어진 것인지에 대한 구체적인 의미를 갖고 있다.

붕어빵은 붕어빵 기계의 인스턴스이다. 붕어빵은 객체이다. (O)
붕어빵은 붕어빵 기계의 객체이다. 붕어빵은 인스턴스이다. (X)

객체의 구성요소

속성(Attribute)

객체를 나타내는 특성들이다. 변수에 해당된다.

기능(method)

객체가 하는 기능들이다. 메서드(함수)에 해당된다.

데이터 저장형태의 발전 과정

변수

하나의 데이터를 저장할 수 있는 공간

배열

같은 종류의 여러 데이터를 하나의 집합으로 저장할 수 있는 공간

구조체

서로 관련된 여러 데이터를 종류에 관계없이 하나의 집합으로 저장할 수 있는 공간

클래스

데이터와 함수의 결합 (구조체 + 함수)

변수와 메서드

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

변수

클래스 영역

인스턴스 변수

  • 인스턴스가 생성되었을 때 생긴다.
  • 인스턴스마다 서로 다른 값을 가질 경우에 사용한다.
  • 반드시 인스턴스를 생성해야만 접근이 가능하다.

클래스 변수

  • 클래스가 메모리에 올라갈 때 생긴다.
  • 모든 인스턴스가 공통적인 값을 유지해야하는 경우 사용한다.
  • 인스턴스를 생성하지 않고도 접근이 가능하다.

클래스 이외에 영역(메서드, 생성자, 초기화 블럭 내부)

  • 변수 선언문이 수행되었을 때 생긴다.
  • 블랙 내에서만 사용 가능하다.

메서드

인스턴스 메서드

  • 인스턴스가 생성되어야만 사용할 수 있다.
  • static 변수에 접근이 가능하다.

클래스 메서드

  • 인스턴스가 생성되지 않아도 접근이 가능하다. ex) Variables.method(1)
  • 인스턴스 메서드나 인스턴스 변수에는 접근이 불가능하다.
    => 생성 시점이 보장되지가 않기 때문이다. 클래스는 있지만 해당 클래스의 인스턴스는 없을 수도 있다.
  • 메서드내에서 인스턴스 변수를 사용하지 않는다면 static을 붙이는 것을 고려한다.
    => 메서드 호출시간이 짧아진다. 인스턴스메서드는 호출되어야 할 메서드를 찾는 과정이 추가적으로 필요하다.

JVM의 메모리 구조

메서드 영역

  • 클래스파일(*.class)을 읽어서 분석하여 클래스에 대한 정보를 이곳에 저장한다.
  • 클래스 변수도 함께 생성된다.

  • 인스턴스가 생성되는 공간이다.
  • 인스턴스 변수들이 생성된다.

호출스택(Call Stack or Execution Stack)

  • 메서드의 작업에 필요한 메모리 공간을 제공한다.

생성자

  • 생성자의 이름은 클래스의 이름과 같아야 한다.
  • 생성자는 리턴 값이 없다.
  • 클래스에는 항상 하나 이상의 생성자가 존재해야한다.
  • 모든 클래스에는 기본적으로 기본 생성자가 존재한다.
Class Car {
    String color;
    String gearType;
    int door;
    
    Car() {
    	this("white", "auto", 4);
    }
    
    Car(String color) {
    	this(color, "auto", 4);
    }
    
    Car(String color, String gearType, int door) {
    	this.color = color;
        this.gearType = gearType;
        this.door = door;
    }
}

다음과 같이 오버로딩을 통해 생성자를 여러개 생성할 수 있다.

변수의 초기화

class InitTest {
    int x;
    int y = x;
    
    void method() {
    	int j;
        int j = i;
    }
}

멤버 변수(인스턴스 변수, 클래스 변수)는 자동으로 자료형에 맞는 기본값으로 초기화가 된다.
지역 변수는 사용하기 전에 반드시 초기화를 해야 한다.

멤버 변수의 초기화 방법

명시적 초기화

class Car {
    int door = 4;
    Engine e = new Engine();
    
    ...
}

생성자

class Car {
    int door = 4;
    Engine e = new Engine();
    
    Car (int door, Engine e) {
    	this.door = door;
        this.e = e
    }
    ...
}

초기화 블럭

class Car {
    static int cv = 3;
    int iv = 2;
    static {
    	// static 초기화 블럭
        cv = 2
    }
    {
    	// 인스턴스 초기화 블럭
        iv = 1
    }
    ...
}

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

클래스 변수

클래스가 처음 로딩될 때 단 한번 초기화 된다.
기본값 -> 명시적초기화 -> 클래스 초기화 블록

인스턴스 변수

인스턴스가 생성될 때마다 각 인스턴스별로 초기화가 이루어진다.
기본값 -> 명시적초기화 -> 인스턴스 초기화 블록 -> 생성자

profile
강한 백엔드 개발자가 되기 위한 여정

0개의 댓글