Java

객체지향 프로그래밍(OOP, Object-Oriented Programming)

화요밍 2022. 5. 19. 17:42
728x90
반응형
객체지향 프로그래밍(OOP)이란?
사물의 속성과 기능을 데이터(변수)와 함수로 정의하여 생성한 객체들의 상호작용으로 프로그램 로직을 구성하는 프로그래밍 패러다임입니다.
프로그램을 명령어의 목록으로 보는 시각에서 벗어나서 실제 세계의 사물간 상호작용을 컴퓨터 속에 옮겨 넣고자 구현되었습니다.

 

* 절차적 프로그래밍(PP, Procedural Programming)

절차적 프로그래밍은 단순히 순차적인 명령 수행이 아니라 루틴, 서브루틴, 메소드, 함수 등을 이용한 프로그래밍 패러다임입니다.

 

 

  • 객체지향언어의 장점

1. 코드의 재사용성이 높고 유지보수가 용이합니다.

상속, 다형성의 특징을 이용해서 새로운 코드를 작성할 때나 기존 코드를 변경할 때 기존 코드를 활용하므로 시간과 비용면에서 효율적입니다.

 

2. 신뢰성이 높은 프로그래밍이 가능합니다.

제어자와 메서드를 이용해서 데이터를 보호하고 올바른 값을 유지하도록 하고, 코드의 중복을 제거해 코드의 불일치로 인한 오류를 방지할 수 있습니다.


1. 관련 용어 정리

  • 클래스 Class

클래스란 객체를 정의해 놓은 것으로, 객체의 설계도 또는 틀이라고 말할 수 있습니다.

클래스는 객체를 생성하는데 사용됩니다.

 

* 클래스와 구조체

구조체는 자료형의 종류에 상관없이 서로 관계가 깊은 변수들을 하나로 묶어서 저장할 수 있는 공간을 말합니다.

클래스는 변수와 함수를 하나의 클래스에 정의하여 서로 관계가 깊은 변수와 함수를 함께 다룰 수 있습니다.

 

  • 객체 Object

객체는 클래스에 정의된 내용대로 메모리에 생성된 것을 말합니다.

객체는 다수의 속성(멤버변수)과 기능(메서드)을 가집니다.

 

  • 멤버 Member

객체가 가지고 있는 속성과 기능을 그 객체의 멤버라고 합니다.

멤버 변수는 인스턴스 변수와 클래스 변수를 통칭하는 말입니다.

 

* 자바에서의 표현

  1. 속성 Property -> 멤버변수 Variable
  2. 기능 Function -> 메서드 Method

 

  • 인스턴스 Instance

클래스로부터 객체를 만드는 과정을 클래스의 인스턴스화라고 하며, 클래스로부터 만들어진 객체를 인스턴스라고 합니다.

예를 들어, Tv 클래스로부터 만들어진 객체 t를 Tv 클래스의 인스턴스라고 합니다.

//Tv 클래스 타입의 참조변수 t선언 -> 메모리에 참조변수 t를 위한 공간 마련
Tv t;

//Tv 클래스의 인스턴스 생성 -> 메모리의 빈 공간에 인스턴스 생성, 변수 t를 통해 Tv 인스턴스에 접근
t = new Tv();

연산자 new에 의해 Tv 클래스의 인스턴스가 메모리의 빈 공간에 생성됩니다.

 

* 올바른 표현

  1. t는 객체이다.
  2. t는 TV 클래스의 인스턴스이다.

2. 변수

class Variable {
    int instance_val;        //인스턴스 변수
    static int class_val;    //클래스 변수(static 변수, 공유 변수)
    
    void method() {
    	int local_val = 0;   //지역 변수
    }
}
변수 선언 위치 생성 시기
클래스 변수 클래스 영역 클래스가 메모리에 올라갈 때
인스턴스 변수 인스턴스가 생성될 때
지역 변수 이외의 영역
매서드, 생성자, 초기화 블럭 내부 등
변수 선언문이 수행되었을 때

 

  • 클래스 변수 Class Variable

클래스 변수를 선언하는 방법은 인스턴스 변수 앞에 static을 붙이면 됩니다.

해당 클래스의 모든 인스턴스가 클래스 변수를 공유합니다.

만약, 한 인스턴스가 클래스 변수를 변경하면 해당 클래스의 다른 인스턴스들도 바뀐 클래스 변수 값을 참조하게 됩니다.

클래스 변수는 인스턴스를 생성하지 않고도 바로 사용할 수 있습니다.
'Variable.class_val'와 같이 '클래스명.클래스변수명'으로 사용하면 됩니다.

클래스 변수는 클래스가 메모리에 로딩될 때 생성되고 프로그램이 종료될 때까지 유지됩니다.

앞에 public을 붙이면 같은 프로그램 내에서 어디서나 접근 가능한 전역 변수(Global Variable)의 성격을 갖게 됩니다.

 

  • 인스턴스 변수 Instance Variable

클래스 영역에 선언되고 클래스의 인스턴스를 생성할 때 만들어집니다.

인스턴스는 독립적인 공간을 가지기 때문에 각각의 인스턴스가 서로 다른 인스턴스 변수를 가질 수 있습니다.

즉, 인스턴스마다 고유한 변수값을 가져야하는 속성이 필요할 때 인스턴스 변수로 선언합니다.

 

  • 지역 변수 Local Vriable

지역 변수는 매서드 내에 선언되고 해당 메서드 내에서만 사용 가능하며, 메서드가 종료되면 소멸되어 사용할 수 없습니다.

생성자와 초기화 블럭 내에 선언된 변수도 지역 변수입니다.

 

 

변수의 초기화

멤버변수의 초기화 방법에는 명시적 초기화, 생성자, 초기화 블럭 세 가지가 있습니다.

 

  • 명시적 초기화 Explicit Initialization

변수를 선언과 동시에 초기화 하는 것을 명시적 초기화라고 합니다.

간단한 초기화의 경우에는 명시적 초기화를 진행합니다.

하지만 복잡한 초기화의 경우 초기화 블럭이나 생성자를 이용해야 합니다.

 

  • 생성자 Constructor

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

클래스 내에 선언되며 생성자의 이름은 클래스 이름과 같아야하며, 리턴값이 없습니다.

 

  • 초기화 블럭 Initialization Block
  1. 클래스 초기화 블럭: 클래스변수의 복잡한 초기화에 사용됩니다. 클래스 내에 블럭 static {}을 만들고 그 안에 초기화 코드를 작성하면 됩니다. 클래스가 메모리(메서드 영역)에 처음 로딩될 때 한 번만 수행됩니다.
  2. 인스턴스 초기화 블럭: 인스턴스변수의 복잡한 초기화에 사용되며, 주로 모든 생성자에서 공통으로 수행되어야 하는 초기화에 사용합니다. 클래스 내에 블럭 {}을 만들고 그 안에 초기화 코드를 작성하면 됩니다. 인스턴스가 생성될 때마다 수행됩니다.

 

  • 클래스 변수의 초기화 순서: 기본값(default) -> 명시적초기화 -> 클래스 초기화 블럭
  • 인스턴스 변수의 초기화 순서: 기본값(default) -> 명시적초기화 -> 인스턴스 초기화 블럭 -> 생성자
class InitTest {
    //명시적 초기화
    static int class_val = 1;
    int instance_val = 1;
    
    //클래스 초기화 블럭
    static {
    	class_val = 2;
    }
    
    //인스턴스 초기화 블럭
    {
    	instance_val = 2;
    }
    
    //생성자
    InitTest() {
    	instance_val = 3;
    }
}
InitTest test = new InitTest();

  1. class_val이 메모리의 메서드 영역에 생성되고, int형의 기본값인 0이 class_val에 저장됩니다.
  2. 명시적 초기화에 의해 class_val에 1이 저장됩니다.
  3. 클래스 초기화 블럭이 수행되어 class_val에 2가 저장됩니다.
  4. InitTest 클래스의 인스턴스가 생성되면서 instanse_val이 메모리(heap)에 생성되고, int형의 기본값인 0이 instanse_val에 저장됩니다.
  5. 명시적 초기화에 의해 instance_val에 1이 저장됩니다.
  6. 인스턴스 초기화 블럭이 수행되어 instance_val에 2가 저장됩니다.
  7. 생성자가 수행되어 instance_val에 3이 저장됩니다.

3. 메서드

  • 클래스 메서드 Class Method

메서드 앞에 static이 붙어 있으면 클래스 메서드입니다.

객체를 생성하지 않고도 '클래스이름.메서드이름(매개변수)'로 호출이 가능합니다. 

인스턴스와 관계없는 메서드를 클래스 메서드로 정의함으로써 메서드 호출시간이 줄어들어 성능을 향상시킬 수 있습니다.

따라서 클래스 메서드는 인스턴스 변수를 사용할 수 없습니다.

즉, 모든 인스턴스에 공통적으로 사용해야하는 메서드에 static을 붙입니다.

 

 

  • 인스턴스 메서드 Instance Method

인스턴스를 생성해야만 호출할 수 있는 메서드입니다.

인스턴스 메서드는 실행 시 호출되어야할 메서드를 찾는 과정이 추가적으로 필요하기 때문에 클래스 메서드 호출에 비해 시간이 더 걸립니다.

인스턴스 변수와 관련된 작업을 하는 메서드를 인스턴스 메서드로 지정합니다.

인스턴스 메서드는 인스턴스 변수뿐만 아니라 static 변수, static 메서드도 사용가능 합니다.

 


4. 생성자 Constructor

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

클래스 내에 선언되며 메서드와 구조가 유사하지만 생성자의 이름은 클래스 이름과 같아야하며, 리턴값이 없다는 점이 다릅니다.

생성자도 오버로딩이 가능하므로 하나의 클래스에 여러 개의 생성자가 존재할 수 있습니다.

 

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

생성자는 단순히 인스턴스 변수들을 초기화하는데 사용되는 특별한 메서드일 뿐입니다.

Card c = new Card();
  1. 연산자 new에 의해서 메모리(heap)에 Card 클래스의 인스턴스가 생성됩니다.
  2. 생성자 Card()가 호출되어 인스턴스 초기화가 일어납니다.
  3. 연산자 new에 의해 생성된 Card 인스턴스의 주소가 반환되고 참조변수 c에 저장됩니다.

 

this

같은 클래스 내 생성자 간에 this(), this(매개변수)를 사용해서 서로 호출이 가능합니다.

한 생성자에서 다른 생성자를 호출 할 떄는 반드시 첫 줄에서만 호출이 가능합니다.

왜냐하면 생성자 내에서 초기화 작업도중 다른 생성자를 호출하게 되면, 호출된 다른 생성자 내에서도 멤버변수들의 값을 초기화하기 때문에 호출하기 이전에 작업한 초기화가 무의미해지기 때문입니다.

 

인스턴스 변수를 생성자 내에서 호출할 떄에는 this라는 참조변수를 활용하면 됩니다.

this는 멤버변수와 지역변수의 이름이 같을 때 구분하기 위해서 사용됩니다.

this에는 인스턴스의 주소가 저장되어 있으며 모든 인스턴스 메서드에 지역변수로 숨겨진 채로 존재합니다.

 

기본 생성자 Default Constructor

기본 생성자는 매개변수도 없고 아무런 내용이 없는 생성자입니다.

컴파일 시에 소스파일의 클래스에 생성자가 하나도 정의되어 있지 않은 경우, 컴파일러가 자동적으로 기본 생성자를 추가하여 컴파일 합니다.

만약 클래스 내에 생성자가 명시되어 있다면, 컴파일러는 기본 생성자를 추가하지 않습니다.

 

 

 


참고

  • 참고 도서: Java의 정석 - 남궁성 지음
728x90
반응형

'Java' 카테고리의 다른 글

super와 this  (0) 2022.05.20
상속 Inheritance  (0) 2022.05.20
오버로딩(Overloading)과 오버라이딩(Overriding)  (0) 2022.05.19
배열 Array  (0) 2022.05.19
Java란?  (0) 2022.05.19