자바의 정석
스터디 노트
클래스와 객체
객체지향이론 관점에서 클래스의 정의 / 의미
클래스 정의 : 클래스란 객체를 정의해 놓은 것이다.
클래스 용도 : 클래스는 객체를 생성하는데 사용된다.
객체의 정의 : 실제로 존재하는 것, 사물 또는 개념
객체의 용도 : 객체가 가지고 있는 기능과 속성에 따라 다름
유형의 객체 : 책상, 의자..
무형의 객체 : 공식, ...
ex) TV설계도(클래스)는 TV라는 제품(객체)를 정의 한 것이며, TV(객체)를 만드는데 사용한다.
클래스로 부터 객체를 만드는 과정을 클래스의 인스턴스화라고 한다.
인스턴스 : 클래스로 부터 만들어진 객체
객체는 다수의 속성, 기능의 집합이다.
속성 = 멤버변수 (ex TV의 크기, 색상..) (ex String color, size..)
기능 = 메서드 (ex TV의 볼륨 기능 , 채널변경 기능.. ) (ex void power(), void channel()..)
객체 : 모든 인스턴스를 대표하는 포괄적인 의미
인스턴스: 어떤 클래스로부터 만들어진 것인지를 강조하는 보다 구체적인 의미
class Tv {
String color;
boolean power;
int channel;
void power( ){
}
void channel(){
--channel;
}
}
인스턴스 생성
Tv t ; Tv클래스 타입의 참조변수 t를 선언 인스턴스 생성 안됨,
t= new Tv();
연산자 new에 의해 Tv클래스의 인스턴스가 메모리의 빈공간에 생성된다.
대입연산자에 의해 생성된 객체의 주소값이 참조변수 t에 저장된다.
따라서 참조변수 t를 통해 Tv 인스턴스에 접근 할 수 있다.
t.channel = 7;
참조변수 t에 저장된 주소에 있는 인스턴스 멤버변수(속성) 채널에 7 저장한다.
t.power();
참조변수 t에 저장된 주소에 있는 인스턴스 메소드(기능) 채널() 호출한다.
메소드는 채널을 1을 감소 시키고 6을 저장한다.
인스턴스는 참조변수를 통해서만 다룰 수 있으며, 참조변수의 타입은 인스턴스의 타입과 일치해야 한다.
객체의 배열 : 객체의 배열 안에 객체가 저장되는 것은 아니고, 객체의 주소가 저장된다.
->객체 배열은 참조변수들을 하나로 묶은 참조 변수 배열이다.
Tv tv1, tv2, tv3;
-> TV [] tvarr = new Tv[3]; 참조변수 배열을 생성
참조 변수에 각각 객체를 저장 시켜 줘야 한다.
tvarr[1] = new Tv(); tvarr[2] = new Tv(); ...
프로그래밍 관점에서 클래스의 정의 / 의미
1. 데이터와 함수의 결합
2. 사용자정의 타입
변수와 메서드
변수 : 변수의 선언된 위치에 따라 클래스변수, 인스턴스변수, 지역변수
지역변수 : 멤버변수를 제외한 나머지 변수
클래스변수 : 멤버변수 중 static이 붙은것
인스턴스변수 : static 붙지 않은것은
class t {
int a; // 멤버변수 이면서 static x : 인스턴스 변수 (클래스영역)
static int b; //멤버변수 이면서 static : 클래스 변수 (클래스영역)
void method(){
int c =0; //지역변수 (메서드영역)
}
}
클래스 변수 : 클래스가 메모리에 올라갈 떄 생성
모든 인스턴스가 공통된 저장공간(변수)을 공유
한 클래스의 모든 인스턴스들이 공통적인 값을 유지해야 하는 속성의 경우 사용
인스턴스 변수 : 인스턴스가 생성되었을 때 생성
따라서 인스턴스 변수의 값을 읽어오거나 저장하기 위해서는 먼저 인스턴스를 생성해야 한다.
독립적인 저장공간을 가지므로 서로 다른 값을 가질 수 있다.
인스턴스마다 고유한 상태를 유지해야 하는 속성의 경우 사용
지역변수 : 변수 선언문이 수행되었을때 생성
메서드 내에서만 사용 가능
지역변수는 사용하기 전에 반드시 초기화해야 한다.
인스턴스변수는 인스턴스가 생성될 때 마다 생성되므로 인스턴스마다 각기 다른 값을 유지할 수 있지만, 클래스 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로, 항상 공통된 값을 갖는다.
같은 클래스 내의 메서드끼리는 참조변수를 사용하지 않고도 서로 호출이 가능하지만, static 메서드는 같은 클래스 내의 인스턴스 메서드를 호출할 수 없다.
모든 메서드에는 하나의 return 문이 있어야 한다. void는 컴파일러가 메서드의 마지막에 return;을 자동적으로 추가하기 때문에 작성 안해도 된것이다.
매개변수 유효성 검사 : 메서드 작성시 매개변수의 값이 적절한 것인지 먼저 검사하는 코드를 작성하는 것이 좋다.
멤버변수(클래스변수, 인스턴스변수), 배열의 초기화는 선택적이지만, 지역변수의 초기화는 필수적이다.
JVM의 메모리 구조
응용프로그램이 실행되면, JVM은 시스템으로부터 프로그램을 수행하는데 필요한 메모리를 할당 받고 JVM은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리한다.
주요영역 : method area, call stack, heap
1. 메서드 영역 : 프로그램 실행 중 어떤 클래스가 사용되면, JVM은 해당 클래스의 클래스파일(*.class)을 읽어서 분석하여 클래스에 대한 정보(클래스 데이터)를 이곳에 저장한다. 클래스변수도 이 영역에 함께 저장한다.
2. 힙 : 인스턴스변수들이 생성되는 공간
3. 호출스택 : 메서드의 작업에 필요한 메모리 공간을 제공한다. 메서드가 호출되면, 호출스택에 호출된 메서드를 위한 메모리가 할당되며, 이 메모리는 메서드가 작업을 수행하는 동안 지역변수(매개변수 포함)들과 연산의 중간결과 등을 저장하는데 사용된다. 그리고 메서드가 작업을 마치면 할당되었던 메모리 공간은 반환되어 비워진다.
각 메서드를 위한 메모리상의 작업공간은 서로 구별된다. 호출스택의 제일 상위에 위치하는 메서드가 현재 실행 중인 메서드이며, 나머지는 대기상태이다.
- 메서드가 호출되면 수행에 필요한 만큼의 메모리를 스택에 할당받는다.
- 메서드가 수행을 마치고나면 사용했던 메모리를 반환하고 스택에서 제거된다.
- 호출스택의 제일 위에 있는 메서드가 현재 실행 중인 메서드이다.
- 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드이다.
- 반환타입 메서드는 종료되면서 결과값을 호출한 메서드에게 반환한다.
반환타입이 참조형이라는 것은 메서드가 객체의 주소를 반환한다는 것을 의미한다.
재귀호출 : 메서드 내부에서 메서드 자신을 다시 호출하는 것/ 재귀호출은 비효율적이므로 재귀호출에 드는 비용보다 재귀호출의 간결함이 주는 이득이 충분히 큰 경우에만 사용해야 한다.
클래스메서드(static메서드) 인스턴스 메서드
변수에서와 같이, 메서드 앞에 static 붙으면 클래스 메서드 / 붙어있지 않으면 인스턴스 메서드
클래스 메서드 : 객체를 생성하지 않고도 ' 클래스이름.메서드이름 ' 식으로 호출 가능하다. ( 클래스가 메모리에 올라갈 때 자동적으로 생성되기 때문에)
인스턴스 변수를 사용 할 수 없다.
인스턴스 메서드 : 객체를 생성해야만 호출 할 수 있다.
- 클래스의 멤버변수 중 모든 인스턴스에 공통된 값을 유지해야 하는 것이 있는지 살표보고 있으면 static을 붙여준다.
- 작성한 메서드 중에서 인스턴스 변수나 인스턴스 메서드를 사용하지 않는 메서드에 static을 붙일 것을 고려한다.
생성자(constructor)
생성자 : 인스턴스가 생성될 떄 호출되는 인스턴스 초기화 메서드 / 초기화 작업 또는 인스턴스 생성 시에 실행되어야 할 작업을 위해 사용된다. (연산자 new 가 인스턴스를 생성하는 것이지 생성자가 인스턴스를 생성하는 것이 아니다)
1. 생성자의 이름은 클래스의 이름과 같아야 한다.
2. 생성자는 리턴 값이 없다. void 생략
3. 오버로딩 가능 ( 하나의 클래스에 여러개의 생성자 존재 가능)
지금까지 인스턴스를 생성하기 위해 사용해왔던 ' 클래스이름() ' 이 바로 생성자 이다.
인스턴스를 생성할 떄는 반드시 클래스 내에 정의된 생성자 중의 하나를 선택하여 지정해주어야 한다.
Card c = new Card();
1. 연산자 new에 의해 인스턴스 클래스 생성되어 힙에 저장
2. 생성자 Card() 호출되어 수행
3. 연산자 new 로 생성된 인스턴스 주소 참조변수 c에 저장
기본생성자
모든 클래스에는 하나 이상의 생성자가 정의되어 있어야 한다. 지금까지 클래스에 생성자를 정의하지 않고도 인스턴스를 생성할 수 있었던 이유는 컴파일러가 제공하는 기본생성자 덕분이다.
컴파일 할 때, 소스파일(*.java)의 클래스에 생성자가 하나도 정의되지 않은 경우 컴파일러는 자동적으로 기본 생성자를 추가하여 컴파일 한다.
기본 생성자가 컴파일러에 의해서 추가되는 경우는 클래스에 정의된 생성자가 하나도 없을때 뿐이다.
매개변수가 있는 생성자
기본생성자 Card()를 사용하면 인스턴스를 생성한 다음에 변수들을 따로 초기화 해 주어야 한다.
매개 변수가 있는 생성자는 Card c = new Card("w","t")..와 같이 인스턴스 생성과 동시에 원하는 값으로 초기화 가능하다.
생성자에서 다른 생성자 호출하기 - this(), this
this : 참조변수
this():생성자
- 생성자 이름으로 클래스이름 대신 this를 사용한다.
- 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다.
위의 조건에 만족 할 경우 생성자 간에도 서로 호출이 가능하다.
class Car{
String a ;
String b;
String c;
Car(){
this("w","z","y");
}
Car(String a, String b, String c){
this.a = a;
this.b = b;
this.c = c;
}
}
class test{
public static void main(String[] args){
Car c1 = new Car();
System.out.println(c1.a + c1.b + c1.c);
}
}
결과: wzy
생성자의 매개변수로 선언된 이름 a가 인스턴스 변수 a과 같을 경우 인스턴스변수 앞에 this 를 사용
this는 참조변수로 인스턴스 자신을 가르킨다.
'개발 > java' 카테고리의 다른 글
[java] 제어자 static / final / abstract / 접근제어자 (0) | 2018.10.07 |
---|---|
[java] 오버라이딩 / 오버로딩 / super (0) | 2018.10.07 |
[java] 자리수 맞추기, printf (1) | 2018.10.07 |