생성자 : 클래스에 선언하는 메서드 중 하나

  • 형태 : 메서드 형태
  • 리턴타입: 선언하지 않음
  • 이름: 클래스명
  • 역할 : 필드(인스턴스 변수, 멤버변수)의 초기화, 메모리 할당
  • 호출 시기 : 인스턴스 생성 시 딱 한번 자동 호출

생성자와 일반 메서드의 차이

  • 인스턴스 생성 시 자동으로 호출
  • 반환값(리턴타입)이 없다
  • 클래스 이름과 같다. 따라서 일반 메서드와 달리 대문자로 시작

#생성자 선언

[접근제한자 클래스명(매개변수){

        실행문;

}]

 

생성자 실행(new 클래스(); ) : new 명령문은 두 가지일 실행

  1. 필드를 힙 메모리에 생성(필드의 값 설정)
  2. new 다음에 선언된 생성자를 호출(메서드 호출해 객체를 사용할 수 있도록 준비하는 역할 수행)

#기본 생성자

[public 클래스( ){ }]

모든 클래스는 생성자가 반드시 존재, 하나 이상 가질 수 있음

생성자 선언을 생략하면 컴파일러는 기본 생성자 추가

 

#생성자 오버로딩(Overloading) : 매개변수의 타입, 개수가 다른 생성자 여러 개 선언(단지, 순서가 바뀐 것은 오버로딩이 아님)

[public 클래스([매개변수]){

...

}

public 클래스([매개변수, 매개변수,...]{

...

})]

 

다른 생성자 호출( this() ) : 현재 실행중인 인스턴스의 주솟값을 나타냄.this는 사용되는 곳에 따라 값이 달라짐

  • 생성자 오버로딩되면 생성자 간의 중복된 코드가 발생
  • 초기화 내용을 한 생성자에 몰아 작성
  • 다른 생성자는 초기화 내용을 작성한 생성자를 this()로 호출

예약어 this.

  • 클래스의 멤버를 가리킬 때
  • 생성자를 호출 할 때
  • 자신의 주솟값을 전달하고 싶을 때

정적 멤버(static member) : 클래스의 특정 인스턴스만 사용하는 게 아니라 해당클래스로 생성된 모든 인스턴스가 공유하는 멤버이다. 필드와 메서드를 공유 멤버로 선언할 수 있으며 static 키워드 사용한다. 프로그램이 시작될 때 딱 한번 메모리의 코드 영역에 할당되며 프로그램이 종료될 때까지 유지되는 특징을 가진다.

 

  • 클래스에 소속된 멤버
  • 객체 내부에 존재하지 않고,메소드 영역에 존재
  • 객체를 생성하지 않고 클래스로 바로 접근해 사용

#정적 멤버 선언 : 필드 또는 메소드 선언 할 때 static 붙임

[public class 클래스{

//정적 필드

static 자료형 필드;

 

//정적 메서드

publid static 리턴타입 메서드(매개변수)

}]

 

인스턴스 변수: 객체마다 가지고 있어야 할 데이터

정적 변수 : 공용적인 데이터

구분 메모리 할당 시점 메모리 할당 위치 메모리 해제 시점
인스턴스 필드 인스턴스 생성시 힙 메모리 인스턴스 소멸시
클래스 필드 프로그램 시작시 코드 메모리 프로그램 종료시

클래스 필드를 사용할 때는 참조변수가 필요 없다. main() 메서드가 실향되기 전에 이미 메모리에 할당되었으므로 바로 사용할 수 있다.

 

정적 멤버는 클래스의 인스턴스를 만들지 않고 사용 가능. 객체가 없으므로 클래스 이름을 객체처럼 사용하려 접근. 프로그램이 종료될 때까지 유지

 

#클래스 필드 사용

[클래스명.필드명]

 

정적 메소드(static method) : 클래스 메서드는 선언부에 static 키워드가 선언된 메서드. 변수든 메서드든 static이 선언하면 무조건 main()메서드가 실행되기 전에 코드 메모리 영역에 생성되어 사용 준비를 완료한다. 인스턴스 생성과 무관하게 사용하는 메서드는 static으로 선언. 객체가 생성되지 않는 상태에서 호출되는 메소드.

  • 인스턴스 변수와 인스턴스 메소드는 사용할 수 없다.
  • 정적변수와 지역 변수만을 사용할 수 있다.
  • 정적 메소드에서 정적 메소드를 호출하는 것은 가능하다.
  • 정적 메소드는 this 키워드를 사용할 수 없다.(this가 참조할 인스턴스가 없기 때문에)

#클래스 메서드 사용

[클래스명.메서드명(); ]

package practice;
class Count2{
	private static int totalCount;
	private static int count;
	
	public Count2() {
		totalCount++;
		count++;
	}
	
	public static void display() {
		System.out.println("count: "+count);
		System.out.println("totalCount: "+totalCount);
	}
}

public class Count1 {
	public static void main(String args[]) {
		
		Count2.display();
	}

}
  non-static 멤버 static 멤버
공간적 특성 멤버는 객체마다 별도 존재
인스턴스 멤버라고 부름
멤버는 클래스당 하나 생성
멤버는 객체 내부가 아니라 별도의 공간(클래스 코드가 적재되는 메모리)에 생성
클래스 멤버라고 부름
시간적 특성 객체 생성시에 멤버 생성됨
객체가 생길 때 멤버도 생성
객체 생성 후 멤버 사용 가능
객체가 사라지면 멤버도 사라짐
클래스 로딩 시에 멤버 생성
객체가 생기기전에 이미 생성
객체가 생기기 전에도 사용가능
객체가 사라져도 멤버는 사라지지 않음
멤버는 프로그램이 종료될 때 사라짐
공유의 특성 공유되지 않음
멤버는 객체 내에 각각 공간 유지
동일한 클래스의 모든 객체들에 의해 공유됨

메모리를 할당하고 나면 반드시 초기화를 해야한다. 

변수의 초기화 : 메모리에 처음으로 값을 저장하는 것

  • 멤버변수의 초기화 = 생략가능
  • 지역변수의 초기화 = 필수

 

멤버변수의 초기화

  • 명시적 초기화
  • 생성자를 이용한 초기화
  • 초기화 블록을 이용한 초기화

 

#초기화 블록(클래스 초기화 믈록, 인스턴스 초기화 블록) : 초기화 블록내에는 메서드의 몸체처럼 다양한 명령문을 함깨 사용할 수 있다. 그래서 복잡한 초기화에 사용한다.

[public class 클래스{

              static{클래스 변수의 초기화}

               {인스턴스 변수의 초기화}

}]

 

생성자에서 초기화를 하지 않는 정적 필드(클래스 필드) : 객체 생성 없이도 사용할 수 있기 때문에 생성자에서 초기화 작업을 하지 않는다. 생성자는 객체 생성 후 실행되기 때문이다.

final필드 선언

[final 자료형 필드[= 초기값] ]

final 필드에 초기값을 주는 방법

  • 필드 선언 시에 초기값 대입(고정된 값일 경우 제일 간단한 방법)
  • 생성자에서 초기값 대입(복잡한 초기화 코드가 필요하거나 객체 생성 시에 외부에서 전달된 값으로 초기화한다면 생성자에서 해야한다.)

클래스와 클래스 간의 관계

포함관계(has-a) : ~을 가지고 있다.

 

싱글톤 : 애플리케이션 전체에서 단 한개의 객체만 생성해서 사용하고 싶다면 싱글톤 패턴을 적용할 수 있다.

싱글톤 만들기

  • 외부에서 new 연산자로 생성자를 호출할 수 없도록 막기(private 접근제어자를 생성자 앞에 붙임)
  • 클래스 자신의 타입으로 정적 필드 선언(자신의 객체 생성해 초기화, private 접근제어자를 외부에서 필드 값 변경 불가하게)
  • 외부에서 호출할 수 있는 정적 메소드인 getInstance() 선언(정적 필드에서 참조하고 있는 자신의 객체 리턴)
  • 싱글톤 패턴이 제공하는 정적 메서드를 통해 간접적으로 객체를 얻을 수 있다.

싱글톤 얻는 방법

클래스 변수1 = 클래스.getInstance();

클래스 변수2 = 클래스.getInstance();

package practice;

public class Singleton {
	private static Singleton singleton = null;
	private Singleton() {}
	public static Singleton getInstance() {
		if(singleton == null) {
			singleton = new Singleton();
		}
		return singleton;
	}

}
package practice;

public class SingletonExample {
	public static void main(String args[]) {
		Singleton obj1 = Singleton.getInstance();
		Singleton obj2 = Singleton.getInstance();
		
		if(obj1==obj2) {
			System.out.println("두 객체는 같은 Singleton");
		}else {
			System.out.println("다른 Singleton");
		}
	}

}

'Java' 카테고리의 다른 글

Java 네트워크 프로그래밍  (0) 2023.05.17
Java 객체 지향 프로그래밍  (0) 2023.05.13
Java 배열  (0) 2023.05.13
Java 제어문(조건문, 반복문, 보조제어문)  (0) 2023.05.13
Java 변수 및 연산자, 수식  (0) 2023.05.13

+ Recent posts