객체란 실세계 우리 주변의 모든 것(명사형)을 뜻합니다. 예를 들어 TV, 의자, 자동차 등...
객체는 각자 자신만의 고유한 특성(state)과 행동(behavior)을 지니고, 다른 객체들과 서로 상호작용하며 존재합니다.
실세계는 이러한 객체들의 집합이라고도 할 수 있습니다.
객체지향 언어는 위에서 설명한 실세계의 객체들을 프로그램 내에 표현하기 위해 클래스와 객체 개념을 도입하였습니다.
캡슐화란 객체를 캡슐로 싸서 내부를 보호하고 볼 수 없게 하는 것으로, 외부 접근으로부터 내부를 보호하고, 노출되어선 안되는 정보를 은닉합니다.
실세계 객체의 캡슐화 사례 -
[캡슐과 알약], [TV케이스와 TV], [사람의 피부,근육과 장기,뇌]
객체는 캡슐화가 기본 원칙이지만, 외부와의 접속을 위해 몇 부분만 공개 노출합니다.
실세계와 달리 자바에서의 객체는 클래스(class)라는 캡슐을 사용하며, 해당 클래스의 속성은 필드(멤버변수)와 메소드(멤버함수)로 구성됩니다.
이때 멤버변수는 객체의 특성(state)을 나타내고, 멤버함수는 객체의 행동(behavior)을 나타냅니다.
실세계에서 상속은 상위 개체의 속성이 하위개체에 물려져서, 하위개체가 상위개체의 속성을 모두 가지는 관계를 뜻합니다.
자바의 상속은 자식 클래스(sub class)가 부모 클래스(super class)의 속성을 물려받고 기능을 추가하여 확장(extends) 하는 개념입니다.
상속은 슈퍼클래스의 필드와 메소드를 물려받아 코드를 재사용함으로, 코드 작성에 드는 시간과 비용을 줄입니다.
다형성은 같은 이름의 메소드가 클래스 혹은 객체에 따라 다르게 동작하도록 구현되는 것을 말합니다.
상속 관계의 다형성을 보여주는 사례로는 다음 2가지가 있습니다.
- **메소드 오버라이딩(overriding)**<br>
슈퍼클래스에 구현된 메소드를 서브클래스에서 동일한 이름으로 자신의 특징에 맞게 다시 구현하는 것</br>
- **메소드 오버로딩(overloading)**<br>
클래스 내에서 이름이 같지만 서로 다르게 동작하는 메소드를 여러개 만드는 것
인스턴스화(instantiate)는 클래스로부터 객체를 만드는 과정을 의미하며, 이렇게 클래스로부터 만들어진 객체를 인스턴스(instant) 라고 한다.
클래스
➡️ 인스턴스화
➡️ 인스턴스(객체)
객체와 인스턴스는 같은 의미이지만, 엄밀히 따지면 다음과 같은 차이점이 있다. 객체는 모든 인스턴스를 대표하는 포괄적인 의미를 가지고 있으며, 인스턴스는 어떤 클래스로부터 만들어진 객체인지를 강조하는 의미를 갖는다.
이 둘은 같은 의미이므로, 철저하게 구분할 필요는 없지만, 아래와 같이 문맥에 따라 구분하여 사용하는 것이 좋다.
👨🏻💻 OLED_TV는 객체이다.
👩🏻💻OLED_TV는 TV클래스의 인스턴스이다.
일반적으로는, 하나의 소스파일에는 하나의 클래스를 작성한다. 하지만 소스파일 내에 두개 이상의 클래스를 작성하는 것도 가능하다. 하지만 다음과 같은 규칙이 존재한다.
소스파일 내에 public class
가 존재한다면, 해당 소스파일의 이름과 pulic class
의 이름은 같아야 한다.
[Example01.java]
class Tv{
...
}
public class Example01 {
public static void main(String[] args) {
...
}
}
소스파일 내에 public class
가 존재하지 않는다면, 해당 소스파일의 이름은 소스파일 내 어떤 클래스의 이름으로 해도 상관없다.
[Example02.java]
class Car {
...
}
class Tv {
...
}
class Example02 {
public static void main(String[] args) {
...
}
소스파일(.java)과는 달리, 클래스파일(.class)은 클래스 마다 하나씩 만들어지기 때문에, 소스파일 Example02.java
를 컴파일 하면, 다음과 같이 클래스 파일 3개가 생성된다.
Car.class
Tv.class
Example02.class
우리는 객체를 생성할 때 해당 객체의 설계도 역할을 하는 클래스를 선언한 뒤, 이 클래스로부터 인스턴스(객체)를 생성한다.
객체를 생성하는 일반적인 방법은 다음과 같다.
클래스명 변수명; // 클래스로부터 생성된 인스턴스를 참조하는 클래스 타입의 참조변수를 선언한다.
변수명 = new 클래스명(); // new 연산자에 의해 클래스의 인스턴스가 메모리의 빈 공간에 생성되고, 생성된 인스턴스의 주소값이 참조변수에 저장된다.
class Tv {
// Tv 객체의 속성(멤버변수)
String manufacturer;
int price;
int channel;
boolean power;
// Tv 객체의 기능(멤버변수)
void power() { power = !power; }
void channelUp() { channel++; }
void channelDown(){ channel--; }
}
public class Ex06_2 {
public static void main(String[] args){
Tv oled_tv;
oled_tv = new TV();
oled_tv.manufacturer = "LG";
oled_tv.channel = 6;
oled_tv.channelUp();
oled_tv.channelDown();
System.out.println("현재 채널은 + oled_tv.channel + "입니다.");
}
다음은 클래스의 선언과 해당 클래스로부터의 인스턴스 생성과 사용울 다루는 아주 간단한 코드이다.
인스턴스의 생성부터 생성된 인스턴스를 사용하는 과정을 단계별로 살펴보도록 하겠다.
Tv oled_tv;
Tv
클래스 타입의 참조변수 oled_tv
를 선언한다. 메모리에 참조변수 oled_tv
를 위한 공간이 상