1. 클래스와 인스턴스
인스턴스화
클래스 ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ> 인스턴스(객체)
인스턴스는 참조변수를 통해서만 다룰 수 있으며, 참조변수의 타입은 인스턴스의 타입과 일치해야 한다.
Tv t = new Tv(); (Tv라는 클래스가 있다고 가정했을 때, 객체 생성 코드)
- t=인스턴스를 가리키는 참조변수(주소 저장)
- new연산자를 통해 객체 생성
- Tv()생성자를 통해 초기화
여러개의 참조변수가 하나의 객체를 가리킬수는 있지만,
하나의 참조변수가 여러개의 객체를 가리킬수는 없다.
2. 변수의 종류
| 변수의 종류 | 선언위치 | 생성시기 |
| 클래스 변수(cv) | 클래스 영역 | 클래스가 메모리에 올라갈 때 |
| 인스턴스 변수(iv) | 인스턴스가 생성되었을 때 | |
| 지역변수(lv) | 클래스 영역 이외의 영역 (매서드, 생성자, 초기화 블럭 내부) |
변수 선언문이 수행되었을 때 |
- 클래스 변수: 클래스 내에서 한 메모리를 공유 (인스턴스 변수에 static 붙이면 클래스 변수)
- 인스턴스 변수: 인스턴스 각각의 개별 저장공간 사용
ㅡㅡ> 클래스 내에서 다같이 공유되는 속성은 클래스 변수 사용, 인스턴스 별로 개별적인 속성은 인스턴스 변수 사용.
ex. 트럼프 카드를 클래스로 설계한다면,
클래스 변수: 카드의 폭, 넓이
인스턴스 변수: 카드의 무늬, 숫자
인스턴스 변수는 인스턴스가 생성될 때마다 생성되므로 인스턴스마다 각기 다른 값을 유지할 수 있지만, 클래스 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로, 항상 공통된 값을 갖는다.
3. 매서드
매서드 선언
선언부 반환타입 매서드이름 ( 타입 변수명, 타입 변수명, ...... )
구현부 { 매서드 호출 시 수행될 코드 }
매서드 호출
매서드이름( 값1, 값2, .......)
기타
main 매서드도 매서드다! ㅡ> main 매서드를 계속 class영역으로 인식하는 실수,,,,
매서드의 매개변수는 여러개일 수 있지만 반환값(return)은 반드시 한 개이다.
매서드 호출 시의 인자의 타입과 갯수와, 매서드 선언 시의 매개변수의 타입과 갯수가 일치해야 한다.
(최소한 자동형변환이 가능한 것이어야 한다.)
매개변수를 기본형으로 선언하면 값을 읽기만 가능, 매개변수를 참조형으로 선언하면 값이 저장된 곳의 주소를 알 수 있기 때문에 읽고 쓰기가 가능.
매개변수, 반환값 모두 참조형 가능.
참조형이라는 것은 매서드가 객체의 주소를 변수로 받고 반환한다는 의미이다.
재귀호출
- 매서드 내부에서 자신을 다시 호출.
- 기본적으로 반복의 형태를 가짐 ㅡ> if 문으로 조건 추가 필요
- 반복문보다 성능이 떨어지지만 보다 직관적으로 프로그래밍이 가능하다는 장점이 있음 ㅡ> 효율적이라도 알아보기 힘든 것보다 다소 비효율적이여도 알아보기 쉽게 작성하는 것이 논리적 오류가 적고 수정하기도 쉽다
- 재귀매서드가 잘못 코딩되면 무한 반복으로 스택오버플로우 오류 발생
클래스 매서드와 인스턴스 매서드
- iv를 사용하느냐 여부!
- 클래스의 멤버변수 중 모든 인스턴스에 공통된 값을 유지해야하는 것이 있는지 살펴보고 있으면, static을 붙여준다
- 작성한 매서드 중에서 인스턴스 변수나 인스턴스 매서드를 사용하지 않는 매서드에 static을 붙일 것을 고려한다.
public class Ex6_19 {
long a,b; //인스턴스 변수(iv) 선언
Ex6_19(){
this.a=1;
this.b=1;
}
long add(){return a+b;} //인스턴스 매서드(im) 선언 - 인스턴스 변수 a,b 사용
static long add2(long a, long b){return a+b;} //클래스 매서드(cm) 선언 - 매개변수 사용
public static void main(String[] args) {
//System.out.println(add()); //클래스 매서드에서 인스턴스 매서드 호출 불가
System.out.println(add2(1,2)); //같은 클래스 내에서는 Ex6_19.add() 이렇게 클래스명을 안 적어도 됨
Ex6_19 t=new Ex6_19();
System.out.println(t.add()); //객체 생성 후 인스턴스 매서드 호출 가능
}
}
3
2
종료 코드 0(으)로 완료된 프로세스
클래스 멤버와 인스턴스 멤버간의 참조와 호출
public class Ex6_20 {
int iv=10; //인스턴스 변수
static int cv=20; //static 변수(클래스 변수)
int iv2=iv; //인스턴스 변수 -> 인스턴스 변수 :가능
int iv3=cv; //인스턴스 변수 -> 클래스 변수 :가능
//static int cv2=iv; //static 변수 -> 인스턴스 변수 :불가능
static int cv3=cv; //static 변수 -> static 변수 : 가능
void InstanceMethod(){
System.out.println(iv); //인스턴스 매서드 -> 인스턴스 변수 :가능
System.out.println(cv); //인스턴스 매서드 -> static 변수 :가능
}
static void staticMethod(){
//System.out.println(iv); //static 매서드 -> 인스턴스 변수 :불가능
System.out.println(cv); //static 매서드 -> static 변수 :가능
}
void InstanceMethod2(){
InstanceMethod(); //인스턴스 매서드 -> 인스턴스 매서드 :가능
staticMethod(); //인스턴스 매서드 -> static 매서드 :가능
}
static void staticMethod2(){
//InstanceMethod(); //static 매서드 -> 인스턴스 매서드 :불가능
staticMethod(); //static 매서드 -> static 매서드 :가능
}
}
static 변수와 static 매서드에서는 인스턴스 변수와 인스턴스 매서드를 사용할 수 없다
4. 오버로딩
1. 매서드 이름이 같아야 한다
2. 매개변수의 갯수나 타입이 달라야 한다
3. 반환타입은 관련이 없다
long add(int a, long b){return a+b;}
long add(long a, int b){return a+b;}
ㅡ> 둘 다 int, long 하나씩이지만 순서가 달라서 매서드 호출 시 매개변수의 값에 따라 구분이 가능하므로 오버로딩
가변인자를 사용한 매서드는 오버로딩 하면 매서드를 호출 했을 때, 구분하지 못하는 에러가 발생하기 쉽기 때문에 가능하면 오버로딩 하지 않는 것이 좋다
5. 생성자
생성자: 인스턴스 변수 초기화 매서드
ㅡ> 인스턴스 변수 초기화, 인스턴스 생성 시 실행되어야 할 작업을 위해 사용
1. 생성자의 이름은 클래스의 이름과 같아야 한다
2. 생성자는 리턴 값이 없다 (리턴값이 없지만 void를 쓰지 않고 아무것도 적지 않는다)
생성자도 오버로딩이 가능하여 여러 생성자를 생성할 수 있다
생성자 내에서 다른 생성자를 호출할 때
1. 생성자의 이름으로 클래스 이름 대신 this를 사용한다
2. 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다
ex.
car(String color, String type, int door){
this.color=color;
this.type=type;
this.door=door;
}
car(String color){
this(color, "auto", 4); //위의 생성자를 호출해서 color만 입력 받은 값으로 하고 나머지는 auto, 4로 초기화
}
this 인스턴스 자신을 가리키는 참조변수로, 모든 인스턴스매서드에 지역변수로 숨겨진 채로 존재한다
지역변수와 인스턴스변수를 구분하는데 사용한다
this() 생성자로, 같은 클래스의 다른 생성자를 호출할 때 사용한다
인스턴스 생성 시 고려사항
1. 클래스 - 어떤 클래스의 인스턴스를 생성할 것인가?
2. 생성자 - 선택한 클래스의 어떤 생성자로 인스턴스를 생성할 것인가?
6. 변수의 초기화
클래스변수, 인스턴스변수의 초기화는 선택
지역변수는 초기화 필수
멤버변수들의 초기화블럭, 생성자 사용 시 실행 확인
public class Ex6_27 {
static{
System.out.println("static 초기화 블럭");
}
{
System.out.println("인스턴스 초기화 블럭");
}
public Ex6_27(){
System.out.println("생성자");
}
public static void main(String[] args) {
System.out.println("메인에서 객체 ex생성");
Ex6_27 ex=new Ex6_27();
System.out.println("메인에서 객체 ex2생성");
Ex6_27 ex2=new Ex6_27();
}
}
static 초기화 블럭
메인에서 객체 ex생성
인스턴스 초기화 블럭
생성자
메인에서 객체 ex2생성
인스턴스 초기화 블럭
생성자
종료 코드 0(으)로 완료된 프로세스
위의 코드의 실행 결과로 아래 2가지를 알 수 있다
1. static 초기화 블럭은 main보다 먼저 실행되고 한 번만 실행된다
2. 인스턴스 초기화 블럭과 생성자는 객체 생성시마다 초기화되며 초기화블럭이 먼저 실행되고 생성자가 실행된다
초기화블럭을 이용한 초기화 예제 - 제품을 생산할 때마다 갯수를 늘리고 갯수를 제품번호로 저장
class Product{
static int count=0;
int serialNo;
{
++count;
serialNo=count; //객체(제품)가 생성될 때마다 count를 증가하고 제품번호를 저장한다
}
}
public class Ex6_29 {
public static void main(String[] args) {
Product p1=new Product();
Product p2=new Product();
Product p3=new Product();
System.out.println("p1의 serialNo은: "+p1.serialNo);
System.out.println("p1의 serialNo은: "+p2.serialNo);
System.out.println("p1의 serialNo은: "+p3.serialNo);
System.out.println("생성된 제품의 갯수는: "+Product.count);
}
}
p1의 serialNo은: 1
p1의 serialNo은: 2
p1의 serialNo은: 3
생성된 제품의 갯수는: 3
종료 코드 0(으)로 완료된 프로세스
- product 클래스의 count 변수가 iv 였다면 객체가 생성될 때마다 새로 만들어져서 항상 1을 갖게 된다
생성자를 이용한 초기화 예제 - 문서 생성
class document{
static int count=0;
String title;
document(){
this("제목없음"+ ++count);
}
document(String title){
this.title=title;
System.out.printf("문서 [%s]가 생성되었습니다.%n",title);
}
}
public class Ex6_30 {
public static void main(String[] args) {
document d1=new document("문서1번");
document d2=new document();
document d3=new document();
document d4=new document("생성자로 초기화");
document d5=new document();
}
}
문서 [문서1번]가 생성되었습니다.
문서 [제목없음1]가 생성되었습니다.
문서 [제목없음2]가 생성되었습니다.
문서 [생성자로 초기화]가 생성되었습니다.
문서 [제목없음3]가 생성되었습니다.
종료 코드 0(으)로 완료된 프로세스
'Study > Java' 카테고리의 다른 글
| [개념]배열의 다양한 활용(예제 5가지) (1) | 2025.06.23 |
|---|---|
| [개념]연산자2 (1) | 2025.06.18 |
| [개념]JVM이 사용하는 메모리 영역 (0) | 2025.06.15 |
| [개념]Static, NoneStatic (1) | 2025.06.15 |
| [개념]매서드(Method) (0) | 2025.06.02 |