객체
객체 지향 프로그래밍
- 주변의 많은 것들을 객체화 해서 프로그래밍 하는 것
- 교체와 재사용이 용이하다.
- 변경했을 때 바꿀 것이 많이 없다->유지보수성이 뛰어나다.
장점
- 블록 형태의 모듈화된 프로그래밍
- 신뢰성 높은 프로그래밍이 가능하다.
- 추가/수정/삭제가 용이하다.
- 재사용성이 높다.
현실의 객체와의 관계
- 현실의 객체가 갖는 속성과 기능은 추상화(abstraction)되어 클래스에 정의된다.
- 클래스는 구체화되어 프로그램의 객체(instance, object)가 된다.
- 현실의 객체는 우리가 만지고 느낄 수 있는 것 -> 실생활에 구체화되어 있는 내용
- 설계도(blueprint)는 하나의 종류(Type)가 되고 설계도를 통해 나온 제품을 객체라고 부르며 주체가 사용한다.
- 현실세계 객체 -> 추상화 -> 클래스 -> 구체화 -> 프로그램 객체
클래스
- 객체를 정의해 놓은 것, 즉 객체의 설계도/틀
- 클래스는 직접 사용할 수 없고 직접 사용되는 객체를 만들기 위한 틀을 제공할 뿐
- 클래스 또한 Type 이다.
- 레퍼런스 타입
객체(instance, Objcet)
- 클래스를 데이터 타입으로 메모리에 생성한 것
- 실제로 동작하는 것
객체 생성과 메모리
- JVM의 메모리구조
- class area
- 클래스 원형 로딩
- Field 정보
- Method 정보
- 타입 정보
- 상수 풀
- 정적(로딩 시점에 메모리에 올라감)
- method stack
- 메서드들의 실행 공간
- thread별로 별도 관리
- 메서드 호출 순서대로 쌓이는 구조
- 메서드 프레임에 로컬변수도 쌓이는 구조
- 로컬변수는 선언된 영역을 벗어나면 삭제
- heap
- 객체를 저장하기 위한 영역
- thread에 의해 공유
- 생성된 객체는 프로그래머가 삭제할 수 없고 GC만이 제어 가능
- 레퍼런스가 끊어지면 언젠가(주기적으로 검사함) GC가 제거함
- 동적(런타임에 메모리에 올라감)
변수
- 멤버 변수
- 클래스 멤버 변수
- 클래스 영역(static keyword)
- 클래스 영역에 클래스 로딩 시 메모리 등록
- 개별 객체의 생성과 무관하게 메모리에 올라간다.
- 모든 객체가 공유하게 됨(공유 변수라고도 불림)
- 타입 별로 default 초기화
- 객체 생성과 무관하게 클래스 이름(소속)으로 접근
- 프로그램 종료 시 소멸함
- 생성된 객체에서 접근하여 변경하여도 클래스 영역의 클래스 멤버 변수가 바뀜 -> 모든 객체가 영향을 받는다.
- 인스턴스 멤버 변수
- 클래스 영역
- 객체가 만들어질 때 객체 별로 생성됨(heap 영역에)
- 객체 생성후(메모리에 올린 후) 객체 이름(소속)으로 접근
- 객체를 만들 때마다 객체 별로 생성 -> 객체마다 고유한 상태(변수 값)유지
- GC에 의해 객체가 없어질 때 소멸함
- 지역 변수
- 지역 변수
- 함수 내부
- 선언된 라인이 실행될 때 생성됨
- thread 별로 생성된 stack 영역에 생성됨
- 사용하기 전 명시적 초기화 필요함
- 외부에서 접근이 불가하므로 소속 불필요
- 선언된 영역인 {}을 벗어날 때 소멸함
- 파라미터 변수
메서드 정의와 필요성
- 메서드란?
- 현실의 객체가 하는 동작을 프로그래밍화
- 어떤 작업을 수행하는 명령문의 집합
- 메서드를 작성하는 이유
- 반복적으로 사용되는 코드의 중복 방지
- DRY : don't repeat yourself
- WET : we enjoy typing or write everything twice
- 코드의 양을 줄일 수 있고 유지 보수가 용이함
- Variable arguments
- 메서드 선언 시 몇 개의 인자가 들어올 지 예상할 수 없을 경우(또는 가변적)
- 배열 타입을 선언할 수 있으나 -> 메서드 호출 전 배열을 생성, 초기화 해야 하는 번거로움
- ... 을 이용해 파라미터를 선언하면 호출 시 넘겨준 값의 개수에 따라 자동으로 배열 생성 및 초기화
- 메서드 호출을 위해서는 먼저 메모리 로딩 후에 호출 해야한다.
- static 메서드는 올라가있으나 인스턴스 메서드는 객체 생성 후에 호출 해야한다.
- 메서드 호출 스택은 FILO 구조
- 중간에 다른 메소드 호출시(stack에 쌓이면) 실행중이던 메소드 pending
메서드 오버로딩
- overloading
- 동일한 기능을 수행하는 메서드의 추가 작성
- 일반적으로 메서드 이름은 기능별로 의미있게 정함
- 동일한 기능을 여러 형태로 정의해야 한다면?
- ex. System.out.println();
- char, int, double 등 받는 파라미터를 대상으로 같은 기능 수행
- 장점
- 기억해야 할 메서드가 감소하고 중복 코드에 대한 효율적 관리 가능
- 방법
- 메서드 이름은 동일
- 파라미터의 개수 또는 순서, 타입이 달라야 한다.
- 리턴 타입은 의미 없다. -> 리턴타입만 다를 경우 중복선언임
- 메서드 오버로딩의 예
- 하는 일이 같을 경우 중복 작성하지 않고 한곳에만 작성하고 호출하는 방식으로 사용하는 것이 좋다.