📌생성자란?

말 그대로 객체를 생성하는 역할을 하는 클래스의 구성 요소이다.

인스턴스가 생성될 때 호출되는 인스턴스 초기화 메서드

메서드와 생성자의 차이

  • 생성자의 이름은 반드시 클래스의 이름과 같아야한다.
  • 생성자는 리턴 타입이 없다.
클래스명(매개변수) { // 생성자 기본 구조
	...생략...
}

생성자도 오버로딩이 가능

public class ConstructorExample {
	public static void main(String[] args) {
    	Constructor constructor1 = new Constructor();
        Constructor constructor2 = new Constructor("Hello World");
        Constructor constructor3 = new Constructor(5, 10);
        
     }
}

class Constructor {
	Constructor() {	//(1) 생성자 오버로드
    	System.out.println("1번 생성자");
    }
    
    Constructor(String str) {	//(1) 생성자 오버로드
    	System.out.println("2번 생성자");
    }
    
    Constructor(int a, int b) {	//(1) 생성자 오버로드
    	System.out.println("3번 생성자");
    }
 }

📌기본 생성자 vs 매개변수가 있는 생성자

기본 생성자(Default Constructor)

모든 클래스에는 반드시 하나 이상의 생성자가 존재해야 한다.

  • 매개변수가 없는 생성자
  • 생성자가 하나도 없을 때만, 컴파일러가 자동 추가
클래스명(){} //기본 생성자

DefaultConst(){} //예시) DefaultConst 클래스의 기본 생성자
예제
class Dc {
	int value;
    Dc(){}; // 원래 직접 추가해야하지만, 생성자가 하나도 없으니 컴파일러가 알아서 추가한다.
}

매개변수가 있는 생성자

매개변수가 있는 생성자를 사용하게되면 인스턴스를 만든 후에 인스턴스의 필드값을 일일이 설정해줄 필요없이 생성과 동시에 원하는 값으로 설정할 수 있음

public class ConstructorExample {
    public static void main(String[] args) {
        Car c = new Car("Model X", "빨간색", 250);
        System.out.println("제 차는 " + c.getModelName() + "이고, 컬러는 " +  c.getColor() + "입니다.");
    }
}

class Car {
    private String modelName;
    private String color;
    private int maxSpeed;

    public Car(String modelName, String color, int maxSpeed) {
        this.modelName = modelName;
        this.color = color;
        this.maxSpeed = maxSpeed;
    }

    public String getModelName() {
        return modelName;
    }

    public String getColor() {
        return color;
    }
}

//Output
제 차는 Model X이고, 컬러는 빨간색입니다.

📌this vs this()

this()

this() 메서드는 자신이 속한 클래스에서 다른 생성자를 호출하는 경우에 사용한다.

this() 메서드를 사용하기 위해서는 크게 두 가지의 문법요소를 충족시켜야 한다.

  • this() 메서드는 반드시 생성자의 내부에서만 사용할 수 있다.
  • this() 메서드는 반드시 생성자의 첫 줄에 위치해야 한다.
public class Test {
    public static void main(String[] args) {
        Example example = new Example();
        Example example2 = new Example(5);
    }
}

class Example  {
    public Example() {
        System.out.println("Example의 기본 생성자 호출!");
    };

    public Example(int x) {
        this(); // 기본 생성자 호출
        System.out.println("Example의 두 번째 생성자 호출!");
    }
}

//Output
Example의 기본 생성자 호출!
Example의 기본 생성자 호출!
Example의 두 번째 생성자 호출!

this

public class ConstructorExample {
    public static void main(String[] args) {
        Car car = new Car("Model X", "빨간색", 250);
        System.out.println("제 차는 " + car.getModelName() + "이고, 컬러는 " +  car.getColor() + "입니다.");
    }
}

class Car {
    private String modelName;
    private String color;
    private int maxSpeed;

    public Car(String modelName, String color, int maxSpeed) {
        this.modelName = modelName;
        this.color = color;
        this.maxSpeed = maxSpeed;
    }

    public String getModelName() {
        return modelName;
    }

    public String getColor() {
        return color;
    }
}

//Output
제 차는 Model X이고, 컬러는 빨간색입니다.

인스턴스 변수와 매개변수를 이름만으로 구분하기가 어려워지는 문제가 발생하기에, 이를 구분해주기 위한 용도로 주로 사용되는 방법이 바로 this 키워드이다.

위 코드에서 this.modelName = modelName 대신 modelName = modelName 라고 작성하면 둘 다 지역변수로 간주되게 된다.

결론
this는 인스턴스 자신을 가리키며, 우리가 참조변수를 통해 인스턴스의 멤버에 접근할 수 있는 것처럼 this를 통해서 인스턴스 자신의 변수에 접근할 수 있는 것이다.


📌내부 클래스

내부 클래스는 클래스 내에 선언된 클래스이다.

class Outer { // 외부 클래스
	
	class Inner {
		// 인스턴스 내부 클래스	
	}
	
	static class StaticInner {
		// 정적 내부 클래스
	}

	void run() {
		class LocalInner {
		// 지역 내부 클래스
		}
	}
} 
종 류선언 위치사용 가능한 변수
인스턴스 내부 클래스 (instance inner class)외부 클래스의 멤버변수 선언위쳉 선언(멤버 내부 클래스)외부 인스턴스 변수, 외부 전역 변수
정적 내부 클래스 (static inner class)외부 클래스의 멤버변수 선언위치에 선언(멤버 내부 클래스)외부 전역 변수
지역 내부 클래스 (local inner class)외부 클래스의 메서드나 초기화블럭 안에 선언외부 인스턴스 변수, 외부 전역 변수
익명 내부 클래스 (anonymous inner class)클래스의 선언과 객체의 생성을 동시에 하는 일회용 익명 클래스외부 인스턴스 변수, 외부 전역 변수

멤버 내부 클래스

인스턴스 내부 클래스

인스턴스 내부 클래스는 객체 내부에 멤버의 형태로 존재하며, 외부 클래스의 모든 접근 지정자의 멤버에 접근할 수 있다.

class Outer { //외부 클래스
    private int num = 1; //외부 클래스 인스턴스 변수
    private static int sNum = 2; // 외부 클래스 정적 변수

    private InClass inClass; // 내부 클래스 자료형 변수 선언

    public Outer() {
        inClass = new InClass(); //외부 클래스 생성자
    }

    class InClass { //인스턴스 내부 클래스
        int inNum = 10; //내부 클래스의 인스턴스 변수

        void Test() {
            System.out.println("Outer num = " + num + "(외부 클래스의 인스턴스 변수)");
            System.out.println("Outer sNum = " + sNum + "(외부 클래스의 정적 변수)");
        }
    }

    public void testClass() {
        inClass.Test();
    }
}

public class Main {
    public static void main(String[] args) {
        Outer outer = new Outer();
        System.out.println("외부 클래스 사용하여 내부 클래스 기능 호출");
        outer.testClass(); // 내부 클래스 기능 호출
    }
}

// 출력값

외부 클래스 사용하여 내부 클래스 기능 호출
Outer num = 1(외부 클래스의 인스턴스 변수)
Outer sNum = 2(외부 클래스의 정적 변수)

정적 내부 클래스

내부 클래스가 외부 클래스의 존재와 무관하게 정적 변수를 사용할 수 있게 한다.

class Outer { // 외부 클래스
    private int num = 3; // 외부 클래스의 인스턴스 변수
    private static int sNum = 4;

    void getPrint() {
        System.out.println("인스턴스 메서드");
    }

    static void getPrintStatic() {
        System.out.println("스태틱 메서드");
    }

    static class StaticInClass { // 정적 내부 클래스
        void test() {
            System.out.println("Outer sNum = " +sNum + "(외부 클래스의 정적 변수)");
            getPrintStatic();
            // num 과 getPrint() 는 정적 멤버가 아니라 사용 불가.
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Outer.StaticInClass a = new Outer.StaticInClass(); //정적 이너 클래스의 객체 생성
        a.test();
    }
}

//출력값
Outer sNum = 4(외부 클래스의 정적 변수)
스태틱 메서드

지역 내부 클래스

메서드 내에서 정의되는 클래스이다.
지역 변수와 유사하게 메서드 내부에서만 사용 가능!

일반적으로 메서드 안에서 선언 후 바로 객체를 생성해서 사용

class Outer { //외부 클래스
    int num = 5;
    void test() {
        int num2 = 6;
        class LocalInClass { //지역 내부 클래스
            void getPrint() {
                System.out.println(num);
                System.out.println(num2);
            }
        }
        LocalInClass localInClass = new LocalInClass();
        localInClass.getPrint();
    }
}
public class Main {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.test();
    }
}

//출력값
5
6
profile
프로젝트, 오류, CS 공부, 코테 등을 꾸준히 기록하는 저만의 기술 블로그입니다!

0개의 댓글