2023. 11. 24. 15:52ㆍ프로그래밍 언어/Java
1. 객체지향언어의 목표
- 코드의 재사용성
- 유지보수
- 중복된 코드의 제거
이 세 관점을 중심으로 객체지향개념을 학습해 보자.
2. 클래스와 객체
클래스란 객체를 정의해 놓은 것이다. 객체의 설계도 또는 틀이라고 생각하면 된다. 객체는 클래스에 정의된 내용대로 메모리에 생성된 것을 뜻한다. 어떤 클래스로부터 만들어진 객체를 그 클래스의 인스턴스라고 한다. 클래스로부터 인스턴스를 생성하는 방법은 일반적으로 다음과 같이 한다.
클래스명 변수명;
변수명 = new 클래스명(); //클래스의 객체를 생성한 후, 객체의 주소를 참조변수에 저장
Tv t;
t = new Tv();
- Tv t;
Tv클래스 타입의 참조변수 t를 선언한다. 이때 메모리에 참조변수 t를 위한 공간만 마련되고 참조변수 t에는 아무 값도 저장되어있지 않다. - t = new Tv();
Tv클래스의 인스턴스가 연산자 new에 의해 생성된다. 이 인스턴스에 Tv클래스의 멤버변수와 메서드들이 저장된다. 그리고 = 연산자에 의해 참조변수 t의 값이 생성된 인스턴스의 주소를 담게 되는 것이다.
3. 객체 배열
길이가 3인 객체 배열을 생성해 보자.
tV[] tvArr = new Tv[3];
for(int i=0; i<tvArr.length; i++)
tvArr[i] = new Tv();
//혹은 아래와 같이 가능하다.
Tv[] tvArr = {new Tv(), new Tv(), new Tv()};
이처럼 객체 배열을 다룰 수 있지만 객체 배열은 하나의 타입만 저장할 수 있다. 다음에 배울 다형성을 이용하면 하나의 배열로 여러 종류의 객체를 다룰 수 있게 된다.
4. 클래스 발전 과정
프로그래밍언어에서 데이터 저장형태의 발전 과정은 다음과 같다.
- 변수 : 하나의 데이터를 저장할 수 있다.
- 배열 : 같은 종류의 여러 데이터를 저장할 수 있다.
- 구조체 : 서로 관련된 여러 종류의 데이터를 저장할 수 있다.
- 클래스 : 데이터와 함수가 결합된 형태로, 구조체에 함수를 더한 형태이다.
5. 변수의 선언 방법에 따른 종류
변수는 클래스 변수, 인스턴스 변수, 지역 변수로 세 종류가 있다. 멤버변수를 제외한 나머지 변수들은 지역 변수이고, 멤버변수 중 static이 붙은 것은 클래스 변수, 붙지 않은 것은 인스턴스 변수이다.
class Variables{
int iv; //인스턴스 변수
static int cv; //클래스 변수
void method(){
int lv = 0; //지역 변수
}
}
변수들의 생성시기는 클래스가 메모리에 올라갈 때 생성되는 클래스 변수가 가장 빠르고, 인스턴스가 생성되면 인스턴스 변수, 변수 선언문이 수행되었을 때 지역변수 순으로 빠르다.
각 변수들을 자세히 알아보자.
- 인스턴스 변수
클래스 영역에 선언되며, 클래스의 인스턴스를 생성할 때 만들어진다. 인스턴스는 독립적인 저장공간을 가지므로 인스턴스별로 서로 다른 값을 가질 수 있다. - 클래스 변수
모든 인스턴스가 공통된 저장공간을 공유하게 된다. 한 클래스의 모든 인스턴스들이 공통적인 값을 유지해야 하는 변수들을 클래스 변수로 사용한다. 클래스 변수는 인스턴스 변수와 달리 인스턴스를 생성하지 않고도 언제라도 바로 사용할 수 있다는 특징이 있으며, '클래스이름. 클래스변수'와 같은 형식으로 사용한다. - 지역 변수
메서드 내에서 선언되면 메서드 내에서만 사용 가능하며 해당 블록을 벗어나면 소멸되어 사용할 수 없다.
6. JVM의 메모리 구조
- 메서드 영역
프로그램 실행 중 어떤 클래스가 사용되면, 해당 클래스에 대한 정보를 이곳에 저장한다. 이때 그 클래스의 클래스변수도 이 영역에 함께 생성된다. 클래스의 모든 인스턴스가 같은 메서드 코드를 공유하므로 메서드 코드도 이곳에 저장된다. - 힙
인스턴스가 생성되는 공간으로 인스턴스변수들이 생성되는 공간이다. - 호출스택(call stack)
호출스택은 메서드의 작업에 필요한 메모리 공간을 제공한다. 메서드가 호출되면, 호출 스택에 호출된 메서드를 위한 메모리가 할당되며, 메서드가 작업을 마치면 할당되었던 공간 또한 반환되어 비어진다. 따라서 호출스택의 제일 위에 있는 메서드가 현재 실행 중인 메서드이고 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드이다. 지역변수 또한 이곳에 저장된다.
7. 인스턴스 메서드와 클래스 메서드
클래스 메서드는 클래스 변수와 같은 역할을 한다. 똑같이 static을 붙여 선언하고 인스턴스를 생성하지 않아도 사용할 수 있다. 주의할 점으로 클래스 메서드는 인스턴스 변수를 사용할 수 없다. 따라서 메서드 내에서 인스턴스 변수를 사용하지 않는다면 static을 붙이는 것을 고려하자. 실제 사용 예시를 보자.
class MyMath{
long a, b;
//인스턴스 변수 a, b를 계산하는 인스턴스 메서드이다.
long add() {return a + b;}
long multiply() {return a * b;}
//인스턴스 변수와 관계없이 매개변수만으로 작업이 가능한 클래스 메서드이다.
static long add(long a, long b) {return a + b;}
static long multiply(long a, long b) {return a * b;}
}
class MyMathTest{
public static void main(String args[]){
MyMath.add(20L, 30L);
MyMath.multiply(2L, 30L);
}
}
이제 인스턴스 멤버들과 클래스 멤버들 간의 참조와 호출을 보자. 클래스 멤버끼리는 언제나 참조, 호출이 가능하고 인스턴스 멤버가 클래스 멤버를 사용하는 것도 문제가 안 된다. 또한, 인스턴스 멤버 간의 호출도 아무런 문제가 없다. 하나의 인스턴스 멤버가 존재한다는 것은 이미 인스턴스가 생성되었다는 것을 의미하기 때문이다. 이런 이유로 클래스 멤버가 인스턴스 멤버를 호출하는 것은 문제가 된다. 이런 경우는 매우 드물다. 만일 그런 경우가 발생한다면, 인스턴스 메서드로 작성해야 할 메서드를 클래스 메서드로 한 것은 아닌지 한 번 더 생각해봐야 한다.
'프로그래밍 언어 > Java' 카테고리의 다른 글
[JAVA] 객체지향언어 - 변수의 초기화와 초기화 블록 (0) | 2023.11.27 |
---|---|
[JAVA] 객체지향언어 - 오버로딩과 생성자, this, this()를 구별하자. (1) | 2023.11.27 |
[JAVA] 배열의 생성부터 다차원 가변 배열까지 (1) | 2023.11.23 |
[JAVA] 연산자 활용과 난수 구하기, 반복문 지정하여 탈출하기 (0) | 2023.11.23 |
[JAVA] 정수형과 실수형 - 정밀도를 주의하자! (1) | 2023.11.11 |