[DEV] study&learn
article thumbnail
JAVA 스터디 1회 차

"6-1"객체 지향 프로그래밍

현실 세계에서 어떤 제품을 만들 때 부품을 먼저 개발하고 이 부품들을 하나씩 조립해서 제품을 완성하듯,
소프트웨어를 개발할 때에도 부품에 해당하는 객체를 먼저 만든다. 그리고 객체를 하나씩 조립해서 완성된 프로그램을 만드는 기법을 객체 지향 프로그래밍(OOP : Object-Oriented Programming)이라고 한다.

 

객체(object) 란?

물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 자신의 속성을 가지고 있으면서 식별 가능한 것을 의미한다.

 

객체는 속성동작으로 구성되어 있다.

자바는 이 속성과 동작을 각각 필드(field)메서드(method)라고 부른다.

 

객체 모델링(object modeling)

현실 세계 객체의 속성과 동작을 추려내어 소프트웨어 객체의 필드와 메서드로 정의하는 과정을 객체 모델링이라고 말 할 수 있다.

 

객체의 상호작용

현실 세계에서 일어나는 모든 현상은 객체와 객체 간의 상호작용으로 이루어져 있다.

소프트웨어에서도 마찬가지이다. 객체들은 각각 독립적으로 존재하고, 다른 객체와 서로 상호작용을 하면서 동작한다.

 

메서드 호출은

  1. 객체에 도트(.) 연산자를 붙이고 메소드 이름을 기술하면 된다. 도트 연산자는 객체의 필드와 메서드에 접근할 때 사용한다.
  2. 매개값은 메서드를 실행하기 위해 필요한 데이터이다.
  3. 리턴값은 메서드가 실행되고 난 후 호출한 곳으로 돌려주는 값이다.
// ex
int result = Calculator.add(10, 20);

 

객체 간의 관계

객체는 개별적으로 사용될 수 있지만, 대부분 다른 객체와 관계를 맺고 잇다.

  1. 집합 관계
    • 집합 관계에 있는 객체는 하나는 부품, 하나는 완성품에 해당한다.
  2. 사용 관계
    • 객체 간의 상호작용을 말한다.
    • 객체는 다른 객체의 메서드를 호출하여 원하는 결과를 얻어낸다.
  3. 상속 관계
    • 상위(부모) 객체를 기반으로 하위(자식) 객체를 생성하는 관계를 말한다.
    • 일반적으로 상위 객체는 종류를 의미하고, 하위 객체는 구체적인 사물에 해당한다.
    • "자동차는 기계의 한 종류이다."

객체 지향 프로그래밍은 만들고자 하는 완성품인 객체를 모델링하고, 집합 관계에 있는 부품 객체와 사용 관계에 있는 객체를 하나씩 설계한 후 조립하는 방식으로 프로그램을 개발하는 기법이다.

 

객체와 클래스

현실의 객체는 갑자기 하늘에서 떨어지는 것이 아니라, 설계도를 바탕으로 만든다.

자바에서는 설계도가 바로 클래스(class)이다. 클래스에는 객체를 생성하기 위한 필드와 메서드가 정의되어 있다. 클래스로부터 만들어진 객체를 해당 클래스의 인스턴스(instance)라고 한다.

하나의 클래스로부터 여러 개의 인스턴스를 만들 수 있는데, 이것은 동일한 설계도로부터 여러 대의 자동차를 만드는 것과 동일하다.

 

OPP의 3단계

  1. 클래스를 설계한다.
  2. 설계된 클래스를 가지고 사용할 객체를 생성한다.
  3. 생성된 객체를 이용한다.

 

main( ) 메서드가 없는 클래스는 객체 생성 과정을 거쳐 사용해야 한다.

 

클래스 선언

클래스 이름은 다른 클래스와 식별할 목적으로 사용되므로 자바의 식별자 작성 규칙에 따라 작성해야 한다.

  • 하나 이상의 문자로 이루어져야 한다.
  • 첫 글자에는 숫자가 올 수 없다.
  • '$', '_' 외의 특수 문자는 사용할 수 없다.
  • 자바 키워드는 사용할 수 없다.
  • 통상적으로 클래스 이름이 단일 단어라면 첫 글자를 대문자로, 나머지는 소문자로 작성한다.
  • 서로 다른 단어가 혼합된 경우 각 단어의 첫 글자는 대문자로 작성하는 것이 일반적이다.

클래스 이름을 정했다면 '클래스 이름.java'로 소스파일을 생성해야한다.

소스 파일 이름 역시 대소문자를 구분하므로 반드시 클래스 이름과 대소문자가 같도록 작성한다.

public class 키워드는 클래스를 선언할 때 사용하며 반드시 소문자로 작성한다.

클래스 이름 뒤에는 반드시 중괄호 { } 를 붙여주는데, 클래스 선언과 시작과 끝을 알려준다.

public class Car {

}

class Tire {

}

일반적으로 소스 파일당 하나의 클래스를 선언하지만, 2개 이상의 클래스 선언도 가능하다.

2개 이상의 클래스가 선언된 소스파일을 컴파일하면 바이트 코드 파일(.class)은 클래스를 선언한 개수만큼 생긴다.

결국

 

소스 파일은 클래스 선언을 담고 있는 저장 단위일 뿐, 클래스 자체가 아니다.

 

public 접근 제한자는 파일 이름과 동일한 클래스 선언에만 붙일 수 있다.
가급적이면 소스 파일 하나당 동일한 이름의 클래스 하나를 선언하는 것이 좋다.

 

객체 생성과 클래스 변수

new 클래스();

new 는 클래스로부터 객체를 생성시키는 연산자이다.

new 연산자 뒤에는 생성자가 오는데, 생성자는 클래스() 형태를 가지고 있다.

 

new 연산자로 생성된 객체는 메모리 힙(heap) 영역에 생성된다.

 

new 연산자는 힙 영역에 객체를 생성시킨 후 객체의 번지를 리턴하도록 되어 있다. 이 주소를 참조 타입인 클래스 변수에 저장해두면 변수를 통해 객체를 사용할 수 있다.

클래스 변수 = new 클래스();

 

클래스의 용도

클래스는 두 가지 용도가 있다.

  1. 라이브러리(API)용
  2. 실행용

라이브러리 클래스는 다른 클래스에서 이용할 목적으로 설계된다.

프로그램 전체에서 사용되는 클래스가 100개라면 99개는 라이브러리 클래스이고 단 하나가 실행 클래스이다.

 

실행 클래스는 프로그램의 실행 진입점인 main( ) 메서드를 제공하는 역할을 한다.

 

라이브러리 클래스에 main( ) 메서드를 작성해서 라이브러리인 동시에 실행 클래스로 만들 수도 있다.

 

클래스의 구성 멤버

클래스에는 객체가 가져야 할 구성 멤버가 선언된다.

  1. 필드(filed)
  2. 생성자(constructor)
  3. 메서드(method)
public class ClassName {
// 필드 - 객체의 데이터가 저장되는 곳
int filedname;

// 생성자 - 객체 생성 시 초기화 역할을 담당
ClassName() { --- }

// 메서드 - 객체의 동작에 해당하는 실행 블럭
void methodName() { --- }
}

필드

객체의 고유 데이터, 부품 객체, 상태 정보를 저장하는 곳이다.

선언 형태는 변수와 비슷하지만, 필드를 변수라고 부르지는 않는다.

(그래서 혹자는 클래스 멤버 변수라고 부르기도 한다.)

변수는 생성자와 메서드 내에서만 사용되고 생성자와 메서드가 실행 종료되면 자동으로 소멸한다.

 

하지만 필드는 생성자와 메서드 전체에서 사용되며 객체가 소멸되지 않는 한 객체와 함께 존재한다.

 

생성자

생성자는 new 연산자로 호출되는 특별한 중괄호 { } 블록이다.

 

생성자의 역할은 객체 생성 시 초기화를 담당한다.

 

필드를 초기화하거나 메서드를 호출해서 객체를 사용할 준비를 한다.

생성자는 메서드와 비슷하게 생겼지만, 클래스 이름으로 되어 있고 리턴 타입이 없다.

 

메서드

메서드는 객체의 동작에 해당하는 중괄호 { } 블록을 말한다.

중괄호 블록은 이름을 가지고 있고, 이것이 메서드 이름이다.

메서드를 호출하게 되면 중괄호 블록에 있는 모든 코드들이 일괄적으로 실행된다.

 

이때 메서드는 필드를 읽고 수정하는 역할도 하지만, 다른 객체를 생성해서 다양한 기능을 수행하기도 한다.

외부(호출한 곳)로부터 매개값을 받아 실행에 이용하고, 실행 후 결과 값을 외부(호출한 곳)로 리턴할 수도 있다.

 

"6-2" 필드

필드(Field)는 객체의 고유 데이터, 객체가 가져야 할 부품, 객체의 현재 상태 데이터를  저장하는 곳이다.

 

필드 선언

필드 선언은 클래스 중괄호 { } 블록 어디서든 존재할 수 있다.

생성자 선언과 메서드 선언의 앞과 뒤 어떤 곳에서든 필드 선언이 가능하다.

하지만!

생성자와 메소드 중괄호 { } 블록 내부에는 선언될 수 없다.

왜??

생성자와 메서드 중괄호 블록 내부에 선언된 것은 모두 로컬 변수가 된다.

 

필드 선언은 변수의 선언 형태와 비슷하다.

그래서 혹자는 클래스 멤버 변수라고 부르기도 한다.

// ex
String company = "현대자동차";

 

타입은 필드에 저장할 데이터의 종류를 결정한다. (기본 타입과 참조 타입 모두 올 수 있다.)

필드의 초기값은 필드 선언 시 주어질 수도 있고 생략될 수도 있다.

초기값이 지정되지 않은 필드는 객체 생성 시 자동으로 기본 초기값으로 설정된다.

분류 타입 초기값
기본 타입 정수 타입 btye
char
short
int
long
0
\u0000 (빈 공백)
0
0
0L
실수 타입 float
double
0.0F
0.0
논리 타입 boolean false
참조 타입 배열
클래스(String 포함)
인터페이스
null

 

필드 사용

필드를 사용한다는 것은 필드값을 읽고 변경하는 작업을 말한다.

  1. 클래스 내부의 생성자나 메소드에서 사용할 경우
    • 단순히 필드 이름으로 읽고 변경하면 된다.
  2. 클래스 외부에서 사용할 경우
    • 우선적으로 클래스로부터 객체를 생성한 뒤 필드를 사용해야한다.
    • 왜?? 필드가 객체에 소속된 데이터이므로 객체가 존재하지 않으면 필드도 존재하지 않기 때문이다.
// Car 클래스

public class car {
	// 필드
    int speed;
    
    // 생성자
   Car() {
   	speed = 0;
   }
   
   // 메서드
  void method(---) {
  	speed = 10;
  }
}
// Person 클래스 (외부 클래스)

public class Person {
	// Car 객체 생성
    Car myCar = new Car();
    
    // 필드 사용
    myCar.speed = 60;
}

 

사용 방법은 변수와 동일하지만,

차이점으로는 변수는 자신이 선언된 생성자 또는 메소드 블록 내부에서만 사용할 수 있는 반면

필드는 생성자와 모든 메서드에서 사용이 가능하다는 점이 있다.

 

외부 클래스에서 해당 클래스의 필드값을 사용하려면, new 연산자를 통해 객체를 우선 생성해야한다.

생성된 객체에 도트(.) 연산자를 이용하여 객체가 가지고 있는 필드나 메서드에 접근할 수 있다.

도트(.) 연산자는 객체 접근 연산자이다.

profile

[DEV] study&learn

@devjuni

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!