객체(object)
자신 고유의 속성을 가진 물리적, 추상적인 모든 대상을 일컫어 우린 이를 '객체'라고 정의한다. 객체란, 인간이 분명하게 인지하고 구별할 수 있는 물리적인 개념 또는 개념적인 경계를 지닌 것이다. 이는 넓은 의미에서 객체가 지니는 의미이고, 소프트웨어 세계에서의 객체는 보통 구현하고자 하는 대상이며, 속성과 기능을 가지는 프로그램 단위이다.
컴퓨터 공학에서 객체란 변수, 자료 구조, 함수, 메소드, 등을 의미하지만, 자바와 같은 객체지향 프로그래밍에서 객체는 변수, 함수, 자료 구조의 조합이 될 수 있는 개념이다.
객체와 유사한 개념으로 '인스턴스(Instance)'라는 개념이 있는데, 이는 클래스를 통해 구현해야할 대상(객체)가 실제로 구현된 구체적인 실체를 말한다. 크게 객체와 차이점을 보이는 개념은 아니지만, 객체는 인스턴스를 포괄하는 더 넓은 의미를 지닌고, 인스턴스는 해당 객체가 어떤 클래스로부터 생성된 것인지를 강조한다.
자바에서 객체의 생성과정은 다음과 같다.
클래스이름 참조변수이름 = **new** 생성자():
Car tesla = new Car(): // tesla 인스턴스
'new' 키워드를 통해 생성 가능하고, 생성된 객체는 포인트 연산자(.)를 통해 객체에 접근 가능하다. 각 생성된 객체들을 인스턴스라고 하며, 이러한 인스턴스는 여러 개 생성될 수 있다.
클래스(Class)
'클래스'의 정의는 다음과 같이 할 수 있다. 클래스란 객체들을 소프트웨어 내에서 구현하기 위해 만든 설계도이다. 즉, 클래스는 객체를 생성하는데 사용된다. 따라서 클래스 안에는 객체를 생성해내기 위해 필요한 변수와 메소드들이 존재한다.
예를 들면, 아이폰이라는 객체를 생성해낸다고 했을 때, 아이폰 객체가 공통적으로 가지는 색상, 용량 등의 속성과 전화라는 기능을 가지는데, 이러한 공통적인 것들을 기본적으로 객체가 포함하기 위해서 아이폰 클래스를 통해 아이폰 객체를 만들어내는 것이다.
자바에서 사용되는 클래스의 예는 다음과 같다.
public class ClassName { // 클래스
int studentNumber = 10; // #1 필드
public int MethodName{ // #2 메서드
}
ClassName { // #3 생성자
}
class ClassName2 { // #4 inner 클래스
}
}
출처: https://ittrue.tistory.com/117 [IT is True:티스토리]
여기서 필드란 클래스의 속성(변수)들을 의미하며, 메소드는 클래스가 하는 행위를 나타낸다. 메소드를 통해 객체 간의 데이터를 전달 받으며 외부로부터는 값을 받고, 실행 이후의 값을 반환할 수 있다. 생성자는 클래스의 객체를 생성하고 초기화하는 역할을 하며, new 연산자를 통해 호출된다. 이너 클래스는 클래스 내부에 존재하는 또 다른 클래스를 의미한다.
클래스와 객체
클래스를 통해 객체를 생성할 수 있기에, 흔하게 발생할 수 있는 오해 중 하나가 바로 이 둘을 하나의 개념으로 인지하는 것이다. 하지만 분명히 다른 개념이기에, 클래스와 객체의 차이점에 관해서는 분명하게 인지할 필요가 있다.
클래스와 객체의 관계는 제품의 설계도와 제품과의 관계와 유사하다. 설계도 없이 좋은 제품을 생성해낼 수 없는만큼, 클래스는 유용한 객체를 생성하는데 있어서 매우 중요한 틀이다.
객체지향 프로그래밍(Object-Oriented Programming)
객체지향 프로그래밍은 단순히 프로그래밍 자체를 명령어의 집합으로 보는것이 아닌 '객체'들의 모임과 객체들의 '협력'으로 컴퓨터 프로그래밍을 파악하고자 하는 컴퓨터 프로그래밍의 패러다임이다.
필요한 데이터를 추상화시켜 상태(속성)와 행위(메소드)를 지닌 객체를 생성해내, 이 객체들 간의 유기적인 상호작용을 통해 로직을 구성한다.
객체지향 프로그래밍에는 크게 '추상화', '캡슐화', '상속', '다형성'이라는 주요한 4가지 특성이 있다.
'추상'이란 사물이나 표상을 어떤 성질, 공통성, 본질에 착안하여 그것을 추출하여 파악하는 것이다. 즉, 공통성과 본질을 모아 추출하는 것이라고 할 수 있다.
지하철 노선도가 추상화의 대표적인 예이다. 중요한 부분의 강조를 위해 불필요한 세부사항들은 제거하고, 가장 본질적이고 공통적인 부분만을 추출하여 표현하는 것이다. 객체지향 프로그래밍에서 의미하는 추상화는 객체의 공통적인 속성과 기능을 추출하여 정의하는 것이다.

위의 사진에서, 자동차와 오토바이는 전진과 후진이라는 공통점을 지닌다. 이를 자바 문법적인 측면에서 설명하면, 자동차와 오토바이라는 '하위 클래스'가 있고, 이 하위 클래스들의 공통적인 기능(메소드)만 추출하여 이동수단이라는 '상위 클래스'에 정의하였다.
자바에서 추상화는 '추상 클래스(abstract class)'와 '인터페이스(Interface)'로 구현해낼 수 있다.
public interface Vehicle{ // 자동차와 오토바이의 공통기능을 이동수단 인터페이스에 정의
public abstract void start()
void moveFoward();
void moveBackward();
}
이런식으로 인터페이스를 통해 객체가 수행해야 하는 핵심적인 역할만을 규정해두고, 실제적인 구현은 각각의 객체들을 통해 이루어진다.
캡슐화란 말 그대로 서로 연관된 속성과 기능들을 하나의 캡슐(capsule)로 만들어 데이터를 외부로부터 보호하는 것이다. 캡슐화를 하는 이유는 크게 두 가지이다.

이 사진과 같이 외부로부터 클래스의 속성과 기능들은 보호하고, 필요한 부분만 노출시켜 각 객체 고유의 독립성과 책임 영역을 안전하게 지키고자 한다.
자바에서 캡슐화를 구현하기 위한 방법은 먼저 public, default, protected, private과 같은'접근 제어자'를 활용하는 방법이 있다. 오른쪽으로 갈수록 더 좁은 접근 범위를 가진다.

캡슐화를 구현하는 또 다른 방법은 'getter/setter 메소드'를 이용하는 것이다.

다음과 같이 private으로 설정된(동일 클래스 내에서만 접근 허용) 속성값들을 getter와 setter로 선택적으로 외부에 접근 허용할 속성을 정의해준다.
'상속'이란, 기존의 클래스를 재활용하여 새로운 클래스를 작성하는 자바의 문법 요소이다.
상속은 클래스 간 공유될 수 있는 속성과 기능들을 상위 클래스로 추상화시켜 상위 클래스를 상속받은 하위 클래스들이 모두 상위 클래스의 속성과 기능을 다 간편하게 사용할 수 있도록 한다. 이러한 측면에서 이는 추상화의 연장선이라고 할 수 있는 부분이다.
상속은 클래스간 공유하는 속성과 기능을 반복적으로 정의할 필요 없이 재사용할 수 있어 반복적인 코드를 최소화하고, 공유하는 속성과 기능에 간편하게 접근할 수 있게 해준다.

public class Car extends Vehicle { // Car class가 vehicle class를 상속받음
void openWindow(){
}
public class MotorBike extends Vehicle{
@Override
void moveFoward() { //메소드 오버라이딩 -> 기능 재정의
}
public void stunt(){
}
}
다음과 같이 extends 키워드를 활용해 하위 클래스에서 기능과 속성들을 반복적으로 정의할 필요 없이 하위 클래스를 정의할 수 있다.
다형성은 객체 지향 프로그래밍에서 가장 중요한 특징이라고 할 수 있는 개념으로, 어떤 객체의 속성이나 기능이 상황에 따라 여러 가지 형태를 가질 수 있는 성질을 의미한다.
객체지향 언어에서 객체는 속성이 기능이나 그 맥락에 따라 다른 역할을 수행할 수 있다. 대표적인 예시가 '메소드 오버로딩(method overloading)' 이 있다. 이는 같은 메소드가 상황에 따라 다른 역할을 수행하는 것을 말한다.
바로 위에서 봤던 상속 예제 코드에서, 메소드 오버라이딩을 통해 같은 이름의 메소드가 상황에 따라 다른 역할을 수행하였다. 같은 맥락으로 메소드 오버로딩 또한 이러한 맥락이고 할 수 있다.
또한 객체 지향 프로그래밍에서 다형성이란 한 타입의 참조 변수를 통해 여러 타입의 객체를 참조할 수 있도록 만든것을 의미한다. 즉, 상위 클래스 타입의 참조 변수로 하위 클래스의 객체를 참조할 수 있도록 하는 것이다.