ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [spring boot] JAVA 의 생성자와 Spring 의 @Bean (2)
    Spring 2023. 4. 22. 20:23

    생성자의 특징


    생성자의 이름은 클래스 이름과 동일해야 합니다.

    1. 생성자는 리턴 타입을 가지지 않으며, void도 허용되지 않습니다.
    2. 클래스는 여러 개의 생성자를 가질 수 있으며, 이를 생성자 오버로딩(Constructor Overloading)이라 합니다. 이때, 생성자들은 매개변수의 개수, 타입, 순서 등이 달라야 합니다.
    3. 생성자를 명시적으로 정의하지 않으면 컴파일러는 매개변수가 없는 기본 생성자(Default Constructor)를 자동으로 생성합
    4. 니다. 단, 클래스 내에 이미 다른 생성자가 정의되어 있다면, 컴파일러는 기본 생성자를 자동으로 추가하지 않습니다.


    Java에서 생성자 예시:

    public class Person {
        private String name;
        private int age;
    
        // 기본 생성자
        public Person() {
            this.name = "unknown";
            this.age = 0;
        }
    
        // 매개변수가 있는 생성자
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }

    위의 예시에서는 Person이라는 클래스를 정의하고, 기본 생성자와 매개변수가 있는 생성자를 두 가지 버전으로 오버로딩하여 정의했습니다. 이렇게 생성자를 사용하면, 객체가 생성되는 시점에 속성들을 초기화하거나 객체 생성과 관련된 작업을 수행할 수 있습니다.


    서브 클래스

    // 상위 클래스 Person 정의
    public class Person {
        private String name;
        private int age;
    
        public Person() {
            this.name = "unknown";
            this.age = 0;
        }
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }
    
    // Person 클래스를 상속받는 Student 서브클래스 정의
    public class Student extends Person {
        private String school;
        private String major;
    
        public Student() {
            super();
            this.school = "unknown";
            this.major = "unknown";
        }
    
        public Student(String name, int age, String school, String major) {
            super(name, age);
            this.school = school;
            this.major = major;
        }
    
        public String getSchool() {
            return school;
        }
    
        public void setSchool(String school) {
            this.school = school;
        }
    
        public String getMajor() {
            return major;
        }
    
        public void setMajor(String major) {
            this.major = major;
        }
    }

    위의 예시에서 Student 클래스는 Person 클래스를 상속받았습니다. Student 클래스에는 학교와 전공 정보를 추가로 포함하고 있으며, 상위 클래스의 생성자를 super()를 통해 호출하고 있습니다.

    기본 생성자와 매개변수가 있는 생성자를 포함한 두 가지 버전의 생성자를 정의했습니다. Student 클래스의 객체가 생성될 때, super()를 통해 Person 클래스의 생성자가 호출되어 name과 age 속성이 초기화되고, 추가로 school과 major 속성도 초기화됩니다. 이렇게 서브클래스에서 슈퍼클래스의 속성과 메서드를 상속받아 사용할 수 있습니다.

     

    super()

    부모 클래스(Parent Class) 또는 슈퍼 클래스(Super Class)는 다른 클래스에 멤버 변수와 메서드를 상속해주는 클래스입니다. 자식 클래스(Child Class) 또는 서브 클래스(Sub Class)는 부모 클래스로부터 멤버 변수와 메서드를 상속받아 확장 또는 변경하는 클래스입니다.

    super 키워드를 사용하여 서브 클래스에서 슈퍼 클래스의 생성자를 호출할 때 매개변수를 전달할 수 있습니다. 이를 통해 서브 클래스에서 슈퍼 클래스의 멤버 변수를 초기화하거나 슈퍼 클래스에서 필요한 작업을 수행할 수 있습니다.

    아래 예시는 부모 클래스와 자식 클래스의 관계와 super를 사용한 매개변수 전달을 보여줍니다.

    // 부모 클래스: Vehicle
    public class Vehicle {
        private String make;
        private String model;
    
        public Vehicle(String make, String model) {
            this.make = make;
            this.model = model;
        }
    
        public String getMake() {
            return make;
        }
    
        public String getModel() {
            return model;
        }
    }
    
    // 자식 클래스: Car
    public class Car extends Vehicle {
        private int year;
    
        public Car(String make, String model, int year) {
            super(make, model); // 부모 클래스의 생성자 호출 및 매개변수 전달
            this.year = year;
        }
    
        public int getYear() {
            return year;
        }
    }

    위의 예시에서 Car 클래스는 Vehicle 클래스를 상속받았습니다. Vehicle 클래스에는 make와 model이라는 멤버 변수가 있으며, 이를 초기화하기 위한 생성자를 가지고 있습니다.

    Car 클래스는 추가로 year라는 멤버 변수를 가지고 있고, 생성자에서 super(make, model)을 사용하여 부모 클래스인 Vehicle 클래스의 생성자를 호출하고, make와 model 매개변수를 전달합니다. 이를 통해 Vehicle 클래스의 멤버 변수가 올바르게 초기화되고, Car 클래스는 추가적으로 year 멤버 변수를 초기화할 수 있습니다.

     

    super(make, model) 호출은 서브 클래스에서 슈퍼 클래스의 생성자를 호출하는 것을 의미합니다. 이 호출 구조는 서브 클래스의 생성자에서 슈퍼 클래스의 생성자로 매개변수를 전달하며 호출하는 것을 나타냅니다. 이 경우 make와 model이라는 두 개의 매개변수를 전달하고 있습니다.

    아래는 해당 호출 구조를 설명하는 간단한 순서도입니다.

    서브 클래스 Car의 객체를 생성하려고 합니다.
    서브 클래스 Car의 생성자를 호출하면서 필요한 매개변수 make, model, year를 전달합니다.
    서브 클래스 Car의 생성자 내에서 슈퍼 클래스 Vehicle의 생성자를 호출하기 위해 super(make, model)을 사용합니다. 이렇게 하면 Vehicle 클래스의 생성자에 make와 model 매개변수가 전달됩니다.
    슈퍼 클래스 Vehicle의 생성자가 실행되면서 make와 model 멤버 변수를 초기화합니다.
    슈퍼 클래스 Vehicle의 생성자 호출이 완료된 후, 서브 클래스 Car의 생성자에서 남은 작업(여기서는 year 멤버 변수 초기화)을 수행합니다.
    이와 같이 super(make, model) 호출 구조를 사용하면 서브 클래스의 생성자에서 슈퍼 클래스의 생성자를 호출하여 적절한 초기화 작업을 수행할 수 있습니다. 이를 통해 클래스 계층 구조에서 상속 관계에 따른 초기화 작업을 제어하고 객체 생성 시 올바른 상태로 초기화할 수 있습니다.

     

     

    인스턴스의 생성순서

    1. 서브클래스 객체를 생성하기 위해 new 키워드와 함께 서브클래스의 생성자를 호출합니다.
    2. 서브클래스의 생성자 내에서 super() 키워드를 사용해 상위 클래스의 생성자를 호출합니다.
    3. 상위 클래스에서 더 이상 호출할 상위 클래스가 없을 때까지 이 과정이 반복됩니다.
    4. 최상위 클래스인 Object 클래스의 생성자가 먼저 실행되고, 그 결과를 이용하여 아래쪽으로 계층 구조를 따라 내려오면서 상위 클래스의 생성자들이 차례로 실행됩니다.
    5. 마지막으로 서브클래스의 생성자가 실행되고, 이때 서브클래스의 멤버 변수와 메서드를 초기화합니다.

     

    결합되는 방식

    서브클래스의 인스턴스가 생성되면, 상속받은 상위 클래스의 인스턴스도 함께 생성되어 결합됩니다. 이 결합된 인스턴스는 서브클래스의 객체로 사용되며, 상위 클래스와 서브클래스의 속성과 메서드를 모두 사용할 수 있습니다. 이 과정에서 상위 클래스와 서브클래스의 생성자가 실행되어 멤버 변수들이 초기화됩니다.

    자바에서 이러한 결합은 메모리 상에서 상위 클래스와 서브클래스의 인스턴스가 연결되어 있으며, 서브클래스 인스턴스는 상위 클래스의 멤버 변수와 메서드에 접근할 수 있습니다. 이 결합 과정은 내부적으로 자바 런타임 시스템에 의해 처리되며, 개발자는 단순히 new 키워드와 생성자를 사용해 객체를 생성하기만 하면 됩니다.



    상위 클래스와 서브클래스의 인스턴스 연결


    자바에서 상위 클래스와 서브클래스의 인스턴스 연결은 런타임 시스템이 관리하는 메모리 구조를 통해 이루어집니다. 상위 클래스와 서브클래스의 인스턴스 연결은 객체의 메모리 구조 및 클래스 정보를 사용하여 구현됩니다. 이 연결은 개발자에게 직접적으로 드러나지 않으며, 내부적으로 JVM(Java Virtual Machine)에 의해 처리됩니다.

    상속 관계에 있는 클래스의 인스턴스를 생성할 때, 상위 클래스와 서브클래스의 인스턴스는 메모리 상에서 연속된 공간에 할당됩니다. 서브클래스의 인스턴스는 상위 클래스의 인스턴스를 포함하게 되며, 메모리에서는 서브클래스의 멤버 변수와 메서드, 그리고 상위 클래스의 멤버 변수와 메서드가 차례대로 배치됩니다.

    이러한 메모리 구조를 통해, 서브클래스의 인스턴스가 상위 클래스의 멤버 변수와 메서드에 접근할 수 있습니다. 이는 서브클래스에서 상속받은 메서드를 호출하거나, 멤버 변수를 참조할 때 내부적으로 처리되는 방식입니다. 이 메모리 구조는 JVM에 의해 관리되며, 개발자가 직접적으로 인스턴스 연결을 관리할 필요는 없습니다.

    따라서 상위 클래스와 서브클래스의 인스턴스 연결은 JVM의 내부 메모리 구조 및 클래스 정보를 사용하여 구현되며, 개발자는 단순히 상속 및 객체 생성을 통해 이 연결을 이용할 수 있습니다.

    댓글

Designed by Tistory.