230322 - java(7)

팝콘·2023년 3월 22일

Java

목록 보기
6/17

1. 생성자

  • 인스턴스가 생성될 때 호출되는 '인스턴스 초기화 메서드'다. 인스턴스의 초기화를 담당하고 있다.
  • 생성자 메소드는 반드시 메소드 클래스 이름과 동일해야한다.
  • return 값이 없고 void를 생략할 수 있기 때문에 반환타입을 적지 않는다.
  • 객체를 생성할 때만 호출할 수 있다. (객체는 new 연산자가 생성한다.)
    Sample s1 = new Sample();  <-- 생성자
    // 객체를 생성하는 것은 new 키워드

기본 생성자

  • 매개변수도 없고 아무런 내용도 없는 아주 간단한 생성자를 뜻한다.
  • 클래스 내에 생성자가 하나도 없을 때만 컴파일러에 의해서 자동으로 추가된다.
	클래스이름() {}
    // 기본 생성자

매개변수가 있는 생성자

	클래스이름(타입 변수명, 타입 변수명, ...) {
    	// 인스턴스 생성시 수행될 코드,
        // 주로 인스턴스 변수의 초기화 코드를 적는다.
    }
  • 인스턴스 생성시 매개변수를 전달받아서 초기화 작업에 사용할 수 있다.
  • 초기화 작업은 객체마다 다르다.

생성자 메소드를 사용하는 이유

  1. 생성자 메소드의 이름이 클래스(설계도) 이름과 동일함으로, 객체 생성에 사용되는 설계도가 무엇인지 알려준다.

  2. 모든 객체는 초기화 작업을 수행한 후에 사용할 수 있다. 즉, 객체가 생성된 후에는 즉시 초기화 작업을 수행해야 한다. 생성자 메소드에 초기화 작업을 구현해 놓으면, 생성자 메소드를 통해서 객체 생성에 사용할 설계도 이름, 객체 생성 직후에 실행할 메소드 이름을 한번에 알려줄 수 있다.


2. this()와 this

this()

  • 생성자에서 다른 생성자를 호출하는 메소드이며 오직 생성자에서만 사용할 수 있다.

  • 코드의 중복을 제거하기 위해 사용하며 반드시 첫줄에 적어야 한다.

  • 같은 클래스 내의 생성자들은 일반적으로 서로 관계가 깊은 경우가 많다. 이처럼 서로 호출하도록 하여 유기적으로 연결해주면 수정이 필요한 경우 보다 적은 코드만을 변경하면 되므로 유지보수가 쉬워진다.

예)
	Employee (String id, String name, 
    		  String department, int salary) {
		this(id, name, department, salary, 0.0);
	}
	
	Employee (String id, String name, 
    		  String department, int salary, 
              double commissionPct) {
		this.id = id;
		this.name = name;
		this.department = department;
		this.salary = salary;
		this.commissionPct = commissionPct
 	}

this

  • 객체가 자기 자신을 가리키는 키워드다.
  • 생성된 객체 자신의 주소값을 가지고 있다.
  • 따로 정의하지 않더라도 모든 객체는 자신의 주소값을 가지고 있는 this를 포함하고 있다.
  • this를 사용해서 객체의 멤버변수에 접근할 수 있다.
  • this를 사용해서 객체의 멤버변수메소드나 생성자의 지역변수를 구분할 수 있다.
  • 객체 내부에서만 사용이 가능하다.
  • 메소드 내부에서 변수를 사용할 때 변수이름에 해당되는 매개변수 선언, 지역변수 선언이 존재하지 않으면 변수에 this를 붙인다.
예)
	public class Product {
		int no;
    	String name;
 	}
 
 	Product(int no, String name) {
 		this.no = no;
    	this.name = name;

	 }


3. 초기화

변수의 초기화

  • 멤버변수(클래스 변수와 인스턴스 변수)와 배열은 초기화를 하지 않아도 자동적으로 변수의 자료형에 맞는 기본값으로 초기화가 이루어지므로 초기화하지 않고 사용할 수 있다.
  • 지역변수는 사용하기 전에 반드시 초기화를 해야한다.

멤버변수의 초기화

  • 명시적 초기화
    - 변수를 선언과 동시에 초기화하는 것을 명시적 초기화라고 한다.
    - 가장 기본적이면서 간단한 초기화 방법이다.

  • 초기화 블럭

  1. 클래스 초기화 블럭
    : 클래스 변수의 복잡한 초기화에 사용된다.
    : 인스턴스 초기화 블럭 앞에 static을 덧붙이기만 하면 된다.

  2. 인스턴스 초기화 블럭
    : 인스턴스변수의 복잡한 초기화에 사용된다.
    : 단순히 클래스 내에 블럭{}을 만들고 그 안에 코드를 작성하기만 하면 된다.

초기화 순서

  1. 클래스 변수의 초기화 --> 인스턴스 변수의 초기화
  2. 자동 초기화 --> 명시적 초기화(간단) --> 초기화 블럭, 생성자(복잡)

3. static 변수 (= 클래스변수)

  • 클래스변수는 모든 객체가 공통으로 사용하는 값을 저장하는 변수다.
  • 클래스변수는 객체 생성에 참여하지 않는다.
  • 클래스변수는 설계도가 메모리에 로딩되면 즉시 변수(저장소)가 생성되고, 초기화된다. 변수가 생성되면 설계도에서 삭제된다.
    1) 클래스변수는 메모리에 최초에 한 번만 만들어진다.
    2) 반면에, 멤버변수는 객체가 생성될 때마다 같이 새로 만들어진다.
  • 클래스변수는 객체 생성과 관계없이 "클래스이름.변수명"으로 사용가능하다.
  • 클래스변수는 대부분 상수값(한 번 정해진 값이 변하지 않는 값)을 담는 용도로 사용된다.
  • 클래스변수는 final 키워드와 같이 사용되는 경우가 많다.
  • 클래스변수는 상수를 정의할 때 주로 사용된다.
	public static final 타입 상수명 = 값;

4. static 메소드 (= 클래스메소드)

  • static 키워드가 포함된 메소드다.
  • 클래스메소드는 객체 생성없이 즉시 사용 가능한 메소드다.
  • 클래스가 메모리에 로딩되면 즉시 실행가능한 상태가 되고 설계도에서는 삭제된다. (최초에 한 번만 일어나는 작업)
  • 멤버변수와 상호작용하지 않는 기능의 구현에 사용된다.
  • 애플리케이션에서 여러 클래스에 광범위하게 사용되는 공통기능을 구현할 때 사용된다.
  • Factory패턴, Singleton패턴, Builder패턴 등 디자인 패턴을 구현할 때 사용한다.
  • 클래스메소드의 예시
    --> 환율계산하는 기능
    --> 경과시간을 계산하는 기능
    --> 날짜를 다양한 형식으로 변환하는 기능
  • 클래스메소드는 클래스이름.메소드명(값)의 형식으로 실행한다.
  • 클래스메소드는 멤버변수에 접근할 수 없다.
  • 클래스메소드는 멤버메소드를 실행할 수 없다.
  • 클래스메소드는 클래스변수에 접근할 수 있다.
  • 클레스메소드는 클래스메소드를 실행할 수 있다.
  • 클래스변수와 클래스메소드는 상호작용을 거의 안한다.
	public class Sample {
		int x;
    	static int y;
        
    	static void m1() {
    		// 클래스메소드는 멤버변수에 접근할 수 없다.
            sop(x);	//오류
    		sop(y);
    	}
        
        // 클래스메소드는 멤버메소드를 실행할 수 없다.
    	static void m2() {
    		m1();
    		m3();	//오류
    	}
    	
        // 멤버메소드는 멤버변수, 클래스변수 모두 사용할 수 있다.
    	void m3() {
    		sop(x);
    		sop(y);
    	}
    	
        // 멤버메소드는 멤버메소드, 클래스메소드 모두 실행할 수 있다.
    	void m4() {
    		m1();
    		m2();
    	}
	}

	* Sample.m1(); 수행문을 실행했을 때,
	  클래스변수 y, 클래스메소드 m1(), m2()는 사용가능한 상태다.
      멤버변수 x, 멤버메소드 m3(), m4()는 사용가능한 상태가 아니다.
      따라서, 클래스메소에서는 멤버변수와 멤버메소드를 사용할 수 없다.
    
    * 멤버변수를 사용하기 위해서는 객체를 생성하고, 
      생성된 객체를 참조하는 참조변수를 이용해야한다.
    	
  • main이 static인 이유
    : 객체 생성 없이 바로 실행 가능하게 하기 위해서

5. 상수

  • 프로그램이 실행되는 동안 값이 변하지 않는다.
  • static 키워드를 부여서 클래스 변수로 만든다. (값이 변하지 않기 때문에 객체마다 갖고 있을 필요가 없다.)
  • final 키워드를 붙여서 값을 변경하지 못하게 만든다. (값을 변경할 수 없게 해야 한다.)
  • 상수명은 전부 대문자로 적는다.
    - static final double PI = 3.141592;
    - static final int LIGHT_SPEED = 299_792_458
	public class Circle {
    	// 멤버변수, 인스턴스 변수
		double r;
       	// 클래스 변수
		static final double PI = 3.141592;

		Circle(double r) {
			this.r = r;
		}
	
    	// 멤버 메소드, 인스턴스 메소드
		void round() {
        	double result = 2*Circle.PI*r
            return result;
       	}
	}

6. final

  • '마지막의', '변경될 수 없는'의 의미를 가지고 있다.
  • 클래스, 메서드, 멤버변수, 지역변수에 사용될 수 있다.
  • 상수값을 담고 있는 경우 final 키워드를 붙여서 값을 변경하지 못하게 한다.
public final class A {				<--- final 클래스
	final int B = 10;				<--- final 멤버변수
	public void C {					<--- final 메서드
		final int D = B;			<--- final 지역변수
	}
}

final 클래스
	- 변경될 수 없는 클래스, 확장될 수 없는 클래스다.
    - 다른 클래스의 조상이 될 수 없다.
    
final 멤버변수
	- 변경될 수 없는 메서드다.
    - 오버라이딩을 통해 재정의 될 수 없다.

final 메서드
	- 값을 변경할 수 없는 상수가 된다.

final 지역변수
	- 값을 변경할 수 없는 상수가 된다.

7. 멤버 메소드

  • 멤버메소드는 객체 생성 후 사용가능하다.
  • 객체를 참조하는 참조변수를 이용해서 실행한다.
  • 객체의 멤버메소드는 멤버변수(인스턴스변수)와 상호작용하는 메소드다.
  • 멤버메소드는 클래스변수에 접근할 수 있다.
  • 멤버메소드는 클래스메소드를 실행할 수 있다.
  • 변수 앞에 private 키워드를 붙이면 값을 직접적으로 변경할 수 없다.
profile
터짐

0개의 댓글