#6 객체지향 (1)
자바보다 C++을 열심히 공부했어서 그런가.. 자바공부하면서 C++이 계속 아른거린다. 객체 개념은 자바로 익히고 실제 활용은 C++로 한 듯..
클래스와 객체(instance)
클래스 : 객체를 정의해놓은 것이며 객체를 생성하는데 사용.
객체(instance) : 클래스에 정의된 내용대로 메모리에 생성된 것.
ex) 붕어빵 틀 : 클래스, 붕어빵 : 객체
인스턴스의 생성과 사용
클래스명 변수명; //클래스 객체를 참조하는 참조변수 선언
변수명 = new 클래스명(); //객체 생성, 객체주소 참조변수에 저장
Tv t; //참조변수 t
t = new Tv(); //Tv 인스턴스 생성, 생성된 Tv 인스턴스 주소 t에 저장
객체 배열
클래스명 변수명; //클래스 객체를 참조하는 참조변수 선언
변수명 = new 클래스명(); //객체 생성, 객체주소 참조변수에 저장
Tv t; //참조변수 t
t = new Tv(); //Tv 인스턴스 생성, 생성된 Tv 인스턴스 주소 t에 저장
객체 배열 안에는 객체의 주소가 저장된다. 즉 객체배열은 참조변수들을 하나로 묶은 참조 변수 배열이라고 할 수 있다.
Tv[] tvArr = new Tv[3]; // 객체배열 생성, but 객체 생성되지 않아 초기화필요
//이렇게 초기화하든가
tvArr[0] = new Tv();
tvArr[1] = new Tv();
tvArr[2] = new Tv();
//아니면 이렇게
Tv[] tvArr = { new Tv(), new Tv(), new Tv() };
//객체배열이 크면 포문 돌리면 된다.
클래스변수와 인스턴스변수
class Card{
int num; //인스턴스 변수
static int width = 100; //클래스 변수
}
class Card{
int num; //인스턴스 변수
static int width = 100; //클래스 변수
}
인스턴스 변수의 경우 각 객체가 다른 값을 가질 수 있다. 인스턴스변수는 인스턴스가 생성되었을 때 생성되므로 인스턴스마다 각기 다른 값을 가질 수 있다.
클래스 변수(static 붙은 것)는 클래스가 메모리에 올라갈 때 생성되며 모둔 인스턴스가 하나의 저장공간을 공유하므로 항상 공통된 값을 가진다.
JVM의 메모리 구조
-
method area
클래스가 사용되면 해당 클래스의 .class 파일을 읽어 클래스 데이터를 저장. 그 클래스의 클래스 변수도 이 영역에 생성된다. -
heap
인스턴스가 생성되는 공간. 인스턴스 변수들이 생성되는 공간 -
call stack
호출스택은 메서드 작업에 필요한 메모리 공간을 제공. 메서드가 호출되면 호출된 메서드를 위해 메모리가 할당되며 이 메모리는 메서드가 작동하는 동안 지역변수 매개변수들과 연산의 중간결과등을 저장하는데 사용된다. 메서드가 종료되면 할당되었던 메모리는 반환되어 비어진다.
기본형 매개변수와 참조형 매개변수
기본형 : 변수의 값 read only
참조형 : read & write
메서드의 매개인자가 기본형이면
ex)
class Data {int x};
static void change(int x) {
x =1000;
} //변화가 없다.
static void change (Data d) {
d.x = 1000;
} //이 메서드를 써야 x 값이 변화된다.
static 메서드와 인스턴스 메서드
- 클래스 설계할 때 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.
- 모든 인스턴스에서 같은 값이 유지되어야하는 변수는 static을 붙여 클래스 변수로 정의한다.
- static 변수는 인스턴스를 생성하지 않아도 사용할 수 있다.
- 인스턴스가 생성되어야 메모리에 올라가는 인스턴스 변수와 달리 static이 붙은 변수는 클래스가 메모리에 올라갈 때 이미 자동적으로 생성되기 때문.
- static 메서드는 인스턴스 변수를 사용할 수 없다.
- 클래스 메서드가 호출되었을 때 인스턴스가 존재하지 않을 수도 있기 때문.
- 메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다
- 메서드 호출시간이 짧아지므로 성능이 향상된다. 인스턴스 메서드는 실행 시 호출되어야할 메서드를 찾는 과정에 필요해 시간이 더 든다.
오버로딩
하나의 메서드 이름으로 여러 기능을 구현하는 것.
조건 1. 메서드 이름이 같아야한다.
조건 2. 매개변수의 개수 또는 타입이 달라야한다.
가령..
Speak(Dog d) {
prinln("월월");
}
Speak(Cat c) {
println("야옹");
}
생성자
인스턴스 초기화 작업에 사용된다.
조건 1. 생성자의 이름은 클래스의 이름과 같아야한다.
조건 2. 생성자는 리턴 값이 없다.
class Car{
String color;
int door;
Car(String c, int d){
color = c;
door = d;
}
}
Car c = new Car("white", 4); //생성 및 초기화 완료.
변수의 초기화
지역변수는 사용하기 전 반드시 초기화!
1. 명시적 초기화
int door = 4; 이렇게 직접
2. 초기화 블럭
클래스 초기화 블럭
인스턴스 초기화 블럭
class BlockTest{
static {
//클래스 초기화 블럭
}
{
//인스턴스 초기화 블럭
}
}
-클래스 초기화 블럭은 클래스가 메모리에 처음 로딩될 때 한 번 수행
-인스턴스 초기화 블럭은 생성자와 같이 인스턴스 생성될 때 마다 수행
생성자보다 인스턴스 초기화 블럭이 먼저 수행된다.
순서 : 클래스 변수 -> 클래스 초기화 블럭이 초기화
초기화 순서
클래스 변수 초기화 시점 : 클래스가 처음 로딩될 때 한 번
인스턴스 "" : 인스턴스 생성될 때 마다 각각 초기화 이뤄진다
클래스변수 초기화 순서 : 기본값 -> 명시적 초기화 -> 클래스 초기화 블럭
인스턴스변수 초기화순서 : 기본값 -> 명시적 초기화 -> 인스턴스 초기화 블럭 -> 생성자
Author And Source
이 문제에 관하여(#6 객체지향 (1)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@naenha/6-객체지향-1저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)