2021. 4. 11. 00:04ㆍ스터디/자바스터디_발표준비
1. 객체지향 언어(Object-Oriented Programming)
1-1. 객체지향 언어(Object-Oriented Programming)란?
객체지향 언어는 프로그램을 객체 단위로 나누어서 객체를 중심으로 프로그램을 구성하는 언어를 의미함.
1-2. 객체지향 언어의 특징
- 코드의 재사용성이 높음
- 코드의 관리가 용이함
- 신뢰성이 높은 프로그래밍을 가능하게함
1-3. 객체지향 언어의 역사
- 과학자들이 모의실험을 위해 가상 세계를 컴퓨터 속에 구현하고자 노력하면서 객체지향이론이 탄생함
- 1960년대 중반 시뮬라(Simula)라는 최초의 객체지향언어가 탄생함
- 1980년대 중반에 C++을 비롯하여 여러 객체지향언어가 발표됨
- 1995년 자바가 발표됨
- 1990년대 말에 인터넷의 발전과 함께 객체지향언어는 프로그래밍언어의 주류로 자리 잡음
2. 클래스와 객체
2-1. 클래스
- 객체를 정의해 놓은 것(정의)
- 객체를 생성하는데 사용(용도)
2-2.객체
- 실제로 존재하는 것. 사물 또는 개념(정의)
- 객체가 가지고 있는 속성과 기능에 따라 다름(용도)
2-3. 객체와 인스턴스
- 객체:모든 인스턴스를 대표하는 포괄적인 의미를 가짐
- 인스턴스:어떤 클래스로부터 만들어진 것인지를 강조하는 보다 구체적인 의미
- 인스턴스화:클래스로부터 객체를 만드는 과정
2-4. 객체의 구성요소
- 객체는 속성(attribute)과 기능(method) 두 종류의 구성요소로 이루어져 있으며, 일반적으로 객체는 다수의 속성과 기능을 가짐
ex) TV를 객체의 관점에 바라보면, '속성'은 '색상,전원상태,채널'등이 될 수 있고 '기능'은 '전원을 키다/끄다','채널을 높인다/내린다' 등의 행위가 될 수 있음
2-5. 인스턴스의 생성과 사용
-인스턴스의 사용을 위한 생성과정은?
클래스 작성 -> 인스턴스 생성 -> 인스턴스 사용
2-6. 객체배열
-객체배열
객체배열 === 참조변수배열
2-7. 클래스의 또 다른 정의
- 클래스의 용도?
설계도, 데이터+함수의 결합, 사용자 정의 타입
- 설계도 : 객체를 사용하기 위한 작성
- 데이터+함수의 결합
변수 : 하나의 데이터를 저장할 수 있는 공간
배열 : 같은 종류의 여러 데이터를 하나의 집합으로 저장할 수 있는 공간
구조체 : 서로 관련된 여러 데이터 종류에 관계없이 하나의 집합으로 저장할 수 있는 공간
클래스 : 데이터와 함수의 결합(구조체 + 함수)
- 사용자 정의 타입
프로그래머가 직접 새로운 타입을 정의 가능
서로 관련된 값을 묶어서 하나의 타입으로 정의 가능
3. 변수와 메서드
3-1. 변수의 종류
3-2. 메서드
메서드란 특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것
3-2-1. 메서드의 정의
- 메서드를 정의한다는 것은 '선언부'와 '구현부'로 작성하는 것을 의미
3-2-2. 메서드의 호출
- 메서드는 정의되었어도 호출되지 않으면, 아무 일도 일어나지 않기 때문에 메서드를 호출해야만 구현부의 문장들이 수행됨
-메서드 호출방법 : 메서드이름(값1, 값2, ...)
3-3. return문
return문은 현재 실행중인 메서들르 종료하고 호출한 메서드로 되돌아 가도록 해줌.
-반환값이 없는 경우 : return문은 원래 반환값의 유무에 관계없이 모든 메서드에는 적어도 하나의 return문이 있어야 하지만, 반환값이 void인 경우에는 컴파일러가 메서드의 마지막에 자동적으로 'return;'을 추가해주기 때문에 생략이 가능
- 반환값이 있는 경우 : return문은 반환값이 있는 메서드는 모든 경우에 있어야 함.
3-4. JVM 메모리 구조
-JVM(Java Vrtual Machine) : JVM은 자바 가상 머신으로 자바 바이트 코드를 실행 할 수 있는 주체이며, CPU나 운영체제(플랫폼)의 종류와 무관하게 실행이 가능함. 즉, 운영체제 위에서 동작하는 프로세스로 자바 코드를 컴파일해서 얻은 바이트 코드를 해당 운영체제가 이해할 수 있는 기계어로 바꿔 실행시켜주는 역할을 함.
JVM의 구성은 크게 4개로 나누어 볼 수 있음.
-Class Loader : 자바에서 코드를 작성하면, '.java'파일이 생성되는데 '.java'코드를 자바 컴파일러가 컴파일하면 '.class'파일(바이트코드)이 생성되고 이렇게 생성된 클래스파일들을 엮어서 JVM이 운영체제로 부터 할당받은 메모리 영역인 Runtime Data Area로 적재하는 역할을 함.
-Execution Engine : Class Loader에 의해 메모리에 적재된 클래스(바이트 코드)들을 기계어로 변경해 명령어 단위로 실행하는 역할을 함.
-Garbage Collector : 가비지 컬렉터는 Heap메모리 영역에 생성된 객체들 중에 참조되지 않는 객ㄱ체들을 탐색 후 제거하는 역할을 함. 가비지컬렉터가 역할을 하는 시간은 정확히 언제인지를 알 수 없음.
-Runtime Data Area : JVM의 메모리 영역으로 자바 어플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역
JVM 메모리 구조(Runtime Data Area)
- 메서드 영역(method area) : 클래스 파일의 바이트 코드가 로드되는 곳.메소드 영역에 바이트코드가 올라가는 것을 '클래스 로딩'이라고 함.
- 힙(heap) : new 키워드로 생성된 객체와 배열이 생성되는 영역
- 메소드 영역에 로드된 클래스만 생성이 가능하고 Garbage Collector가 참조되지 않는 메모리를 확인하고 제거하는 영역
-호출스택(call stack 또는 execution stack) : 지역 변수, 파라미터, 리턴 값, 연산에 사용되는 임시 값 등이 생성되는 영역. 메소드를 호출할 때마다 개별적으로 스택이 생성됨.
- PC Regidter(PC 레지스터) : 현재 쓰레드가 실행되는 부분의 주소와 명령을 저장하고 있는 영역(CPU의 레지스터와 다름). 이것을 이용해서 쓰레드를 돌아가면서 수행할 수 있게 함.
* 클래스 로딩을 위한 JVM의 로딩절차(메서드 영역)
1) 메서드를 호출하는 문장을 읽을 때, 그 메소드를 가진 클래스 바이트코드가 아직 로딩된 적이 없다면, 곧바로 JVM은 JRE라이브러리 폴더에서 클래스를 찾음
2) JRE라이브러리 폴더에 없으면, CLASSPATH 환경변수에 지정된 폴더에서 클래스를 찾음
3) 찾아 낸 클래스 파일이 올바른지 바이트코드를 검증
4) 올바른 바이트코드라면 메소드영역으로 파일을 로딩
6) 클래스 블록이 있으면, 순서대로 그 블록을 실행
7) 한 번 클래스의 바이트 코드가 로딩되면, jvm이 종료될 때까지 유지됨
3-5. 기본형 매개변수와 참조형 매개변수
메서드를 호출할 때 매개변수로 지정한 값을 메서드의 매개변수에 복사해서 넘겨줌
매개변수의 타입이 기본형(primitive type)일 때는 기본형 값이 복사되겠지만, 참조형(reference type)이면 인스턴스의 주소가 복사됨.
메서드의 매개변수를 기본형으로 선언하면 단수히 저장된 값만 얻어오지만, 참조형으로 선언하면 값이 저장된 곳의 주소를 알 수 있기 때문에 값을 읽어 오는 것은 물론 값을 변경하는 것도 가능함.
3-6. 참조형 반환타입
반환타입이 참조형이라는 것은 메서드가 객체의 주소를 반환한다는 것을 의미
3-7. 재귀호출(recursive call)
메서드의 내부에서 메서드 자신을 다시 호출하는 것을 재귀호출이라고 하고, 재귀호출 하는 메서드를 재귀메서드라고 함.
재귀호출은 무한하게 자신을 호출하기 때문에, 반드시 탈출할 수 있는 조건을 만들어 주어야 함.
대부분의 재귀호출은 반복문으로 작성하는 것이 가능한데, 반복문은 그저 같은 문장을 반복해서 수행하는 것이지만, 메서드를 호출하는 것은 반복문보다 매개변수의 복사와 종료 후 복귀할 주소저장 등 몇 가지 과정이 더 필요하기 때문에 반복문보다 재귀호출의 수행시간이 더 오래걸림.
-재귀호출이 더 비효율적인데도 사용하는 이유: 논리적 간결함 때문에 사용. 어떤 작업을 반복문으로 처리해야 한다면, 먼저 반복문으로 작성해보고 너무 복잡할 경우 재귀호출로 간단히 바꿀 수 있는 고민을 할 수 있음. 다만, 재귀호출은 비효율적이므로 재귀호출에 드는 비용보다 재귀호출의 간결함이 주는 이득이 충분히 큰 경우에만 사용해야 함.
3-8. 클래스 메서드와 인스턴스 메서드
-클래스 메서드(static 메서드) : 객체 생성 없이 '클래스.메서드이름()'으로 호출. 인스턴스 멤버(iv,im) 와 관련없는 작업을 하는 메서드. 메서드 내에서 인스턴스 변수 사용 불가
- 인스턴스 메서드 : 인스턴스 생성 후, '참조변수.메서드이름()'으로 호출. 인스턴스 멤버와 관련된 작업을 하는 메서드. 메서드 내에서 인스턴스 변수 사용 가능
4. 오버로딩(overloading)
4-1. 오버로딩
- 오버로딩 : 한 클래스 내에 같은 이름의 메서드를 여러 개 정의 하는 것을 의미
- 오버로딩의 조건
1) 메서드의 이름이 같아야 함
2) 매개변수의 개수 또는 타입이 달라야 함
- 오버로딩의 장점 : 하나의 이름만 기억하면 되므로 오류의 가능성이 줄어듬. 메서드 기능을 쉽게 예측가능(같은 메서드는 메서드명이 같으므로). 메서드 이름을 절약할 수 있음.
4-2. 가변인자(varargs)
- 기존에는 메서드의 매개변수 개수가 고정적이었으나, JDK1.5부터 동적으로 지정해 줄 수 있게 된 기능
- 가변인자는 '타입... 변수명'과 같은 형식으로 선언
ex) PrintStream printf(String format, Object args)
-가변인자 외에도 매개변수가 더 있다면, 가변인자를 매개변수 중에서 가장 마지막에 선언해야 함.(그렇지 않으면 가변인자인지 아닌지를 판단할 수 없어서 컴파일 에러 발생)
- 가변인자는 내부적으로 배열로 처리됨. (가변인자가 선언된 메서드를 호출할 때 마다 배열이 새로 생성되기 때문에 비효율적인 면이 있으므로 꼭 필요할 때만 사용하는 것이 좋음)
- 가변인자는 빈 인자값이나 배열도 인자값으로 줄 수 있음. (매개변수의 타입을 배열로 했을 경우 매개변수를 생략이 불가능 하기 때문에, null이나 길이가 0인 배열을 인자로 지정해 주어야 하는 불편함이 있음.)
- 가변인자가 사용된 메서드 오버로딩 시에는 컴파일러가 어떤 메서드를 사용해야 하는지 구별하지 못하는 경우가 발생하기 쉽기 때문에 가변인자를 사용한 메서드는 오버로딩하지 않는 것이 좋음.
5. 생성자(Constructor)
5-1. 생성자
- 생성자 : 생성자는 인스턴스가 생성될 때 호출되는 인스턴스 초기화 메서드
- 생성자의 조건
1) 생성자의 이름은 클래스의 이름과 같아야 함.
2) 생성자는 리턴 값이 없음(모든 생성자는 리턴값이 없으므로 void 생략)
5-2. 기본 생성자(default constructor)
- 모든 클래스에는 반드시 하나 이상의 생성자가 정의되어 있어야 하는데, 클래스에 생성자를 정의하지 않고도 인스턴스를 생성할 수 있었던 이유는 컴파일러가 소스파일(*.java)의 클래스에 생성자가 하나도 정의되지 않은 경우 자동적으로 '기본생성자(defaulr constructor)'를 추가하여 컴파일 함
- 컴파일러가 자동적으로 기본 생성자를 추가해주는 경우는 '클래스 내에 생성자가 하나도 없을 때'만 가능
- 이미 매개변수가 있는 생성자가 존재하는 클래스는 기본생성자를 컴파일러가 자동으로 추가해주지 않기 때문에, 기본생성자를 호출하면 컴파일에러 발생
5-3. 매개변수가 있는 생성자
- 생성자도 메서드처럼 매개변수를 선언하여 호출 시 값을 넘겨 받아서 인스턴스의 초기화 작업에 사용 가능
- 인스턴스마다 각기 다른 값으로 초기화 되어야 하는 경우가 많기 때문에 매개변수를 사용한 초기화는 매우 유용함
5-4. this()
- 생성자의 이름으로 클래스이름 대신 this를 사용
- 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능
5-5. this
- 인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어 있음.
- 모든 인스턴스메서드에 지역변수로 숨겨진 채로 존재
- static메서드에서는 this 사용 불가
6. 변수의 초기화
6-1. 변수의 초기화
- 변수를 선언하고 처음으로 값을 저장하는 것
- 멤버변수는 초기화를 하지 않아도 자동적으로 변수의 자료형에 맞는 기본값으로 초기화 됨
- 지역변수는 사용하기 전에 반드시 초기화 진행해야 함
- 멤버변수의 초기화 방법
1) 명시적 초기화(explicit initialization) : 가장 기본적이고 간단한 초기화 방법
2) 생성자(Constructor) : 생성자를 이용한 초기화 방법
3) 초기화 블럭(initialization block) : 초기화 블럭 내에는 메서드 내에서와 같이 조건문, 반복문, 예외처리구문 등을 자유롭게 사용할 수 있으므로, 초기화 작업이 복잡하여 명시적 초기화만으로 부족한 경우 초기화 블럭을 사용
6-2. 초기화 블럭(initialization block)
- 클래스 초기화 블럭(클래스 변수의 복잡한 초기화에 사용됨) : static {}
- 인스턴스 초기화 블럭(인스턴스 변수의 복잡한 초기화에 사용됨) : {}
6-3. 멤버변수의 초기화 시기와 순서
6-3-1. 멤버변수의 초기화 시기
- 클래스변수의 초기화 시점 : 클래스가 처음 로딩될 때 단 한 번 초기화됨.
- 인스턴스변수의 초기화 시점 : 인스턴스가 생성될 때마다 각 인스턴스별로 초기화가 이루어짐
6-3-2. 멤버변수의 초기화 순서
- 클래스변수의 초기화 순서 : 기본값 -> 명시적 초기화 -> 클래스 초기화 블럭
- 인스턴스변수의 초기화 순서 : 기본값 -> 명시적 초기화 -> 인스턴스 초기화 블럭 -> 생성자
참고 : 자바의 정석(남궁 성 지음/도우출판) 교재