생성자& 내부클래스

InSeok·2022년 7월 11일
0

TIL

목록 보기
11/51

학습목표


  1. 생성자 개념
  2. 기본생성자
  3. 매개변수가 있는 생성자
  4. this.
  5. this() 메서드

배운 내용


**생성자(Constructor)**

  • 객체를 생성하는 역할을하는 클래스 구성요소
  • 인스턴스가 생성될 때 호출되는 인스턴스 초기화 메서드

생성자가 필요한 이유

  • 정보 은닉을 하기위해 private 영역에 변수를 선언해 놓으면 main문에서 접근 하는 것이 불가능하다. 그래서 public 영역에 생성자를 만들어 놓으면 main문에서 생성자를 통해서 변수의 값에 간접적으로 접근할 수 있다.

생성자 구조

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

생성자 오버로딩

class Constructor {
    Constructor() { // (1) 생성자 오버로딩  -기본생성자
        System.out.println("1번 생성자");
    }

    Constructor(String str) { // (2)  - 매개변수가 String타입인 생성자
        System.out.println("2번 생성자");
    }

    Constructor(int a, int b) { // (3)  -int타입 매개변수가 두개인 생성자
        System.out.println("3번 생성자");
    }
}

**기본 생성자(Default Constructor)**

  • 모든 클래스에는 반드시 하나 이상의 생성자가 존재해야 한다.
  • 생성자가 클래스 안에 포함되어 있지 않은 경우에는 자바 컴파일러가 기본 생성자를 자동으로 추가
  • 기본생성자 : 클래스명(){}
  • 기본 생성자에는 매개변수도 없고 바디에 아무런 내용이 없다.

**매개변수가 있는 생성자**

  • 클래스명(int a, int b){} : 매개변수를 통해 호출시에 해당값을 받아 인스턴스를 초기화

this()

  • this() 메서드: 자신이 속한 클래스에서 다른 생성자를 호출할때 사용

조건

  1. this() 메서드는 반드시 생성자의 내부에서만 사용 가능
  2. this() 메서드는 반드시 생성자의 첫 줄에 위치
public class this_test {
    public static void main(String[] args) {
        Example example = new Example();
        Example example2 = new Example(5);
        Example example3 = new Example(1.0,3.0);
				wwa();
    }
     static void wwa(){
         System.out.println("메서드 내부에서 매서드 정의 안됨 호출은 가능");
    }
}

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

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

        public Example(double y, double z) {
            this(3);
            System.out.println("Example의 세 번째 생성자 호출");
        }
    }
/* 3번째 생성자 결과값: 
Example의 기본 생성자 호출!
Example의 두 번째 생성자 호출!
Example의 세 번째 생성자 호출
*/

**this 키워드(내부객체 참조 변수명)**

  • 모든 메서드에는 자신이 포함된 클래스의 객체를 가리키는 this라는 참조변수가 있다.
  • this.생략하면 컴파일러가 자동으로 this.를 추가
  • this는 인스턴스 자신을 가리키며, this를 통해서 인스턴스 자신의 변수에 접근한다.
  • 클래스의 외부에서 멤버(필드, 메서드, 이너 클래스)를 호출하기 위해서는 객체를 먼저 생성한 후 ‘참조 변수명.맴버명'의 형태로 호출하지만, 클래스 내부`에서는 객체의 생성 없이 필드와 메서드를 바로 사용할 수 있다
  • 모든 사용할 수 있는 상태의 맴버는 항상 객체 속에만 존재, 클래스 내부에서도 체 안의 멤버를 사용하기 위해 this. 키워드 통해 접근
  • 지역 변수는 맴버가 아니므로 this.가 자동으로 붙지 않는다.
  • 지역 변수와 필드 모두를 사용할 수 있는 영역에서는 사용 범위가 좁은 변수, 즉 지역 변수로 인식
  • 따라서 init()메서드 안에서 m = m, n = n과 같이 작성하면 컴파일러는 이들 모두를 지역 변수로 인식this.는 당연히 추가되지 않고 지역변수 mm 값을 대입]
  • 자바에서 제공하는 대부분의 API에는 메서드의 지역 변수명이 필드명과 동일하게 구성되 있다.
class A{
    // 필드 생성
    int m,n;

    // 메서드 생성
    void init(int m, int n) {
        // 매개변수는 지역변수에 할당되어 집니다.
        // 즉 init() 에서만 사용 가능
        m = m;
        n = n;
    }
}
//지역 변수에 지역 변수값을 다시 대입하는 형태이므로 필드값은 전혀 변화가 없습니다

class B{
	int m;
	int n;
	void init(int m, int n) {
		// 필드에 존재하는 m,n 값에 대입
		this.m = m;
		this.n = n;
	}
}
//필드와 지역 변수를 명시적으로 구분하여 정상적으로 대입
//

**내부 클래스**

  • 클래스 내에 선언된 클래스, 외부클래스와 내부클래스가 서로 연관있을때 사용

장점

  1. 외부클래스의 멤버들에 쉽게 접근 가능
  2. 코드 복잡성 줄일 수 있다.
  3. 외부의 불필요한 데이터 감출수 있다(캡슐화)

종류

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

	class Inner {
		// 인스턴스 내부 클래스
	}

	static class StaticInner {
		// 정적 내부 클래스
	}

	void run() {
		class LocalInner {
		// 지역 내부 클래스
		}
	}
}

**멤버 내부 클래스**

**인스턴스 내부 클래스**

  • 객체 내부에 멤버의 형태로 존재
  • 외부 클래스의 모든 접근 지정자의 멤버에 접근가능
  • 반드시 외부 클래스를 생성한 이후에 사용해야 한다
    • 정적 변수와 정적 메서드는 인스턴스 내부 클래스에서 선언할 수 없다.

정적 내부 클래스

  • 내부클래스가 외부클래스의 존재와 무관하게 정적변수를 사용할 수 있게 하기위해 사용

인스턴스 내부클래스 vs 정적 내부 클래스

//정적 내부 클래스는 독립적으로  객체 생성가능

void foo(){
    A.B b = new B();
}

// 인스턴스 내부 클래스는 반드시 외부클래스 객체 생성후 객체를 생성할 수 있다.
void foo(){
    A a = new A();
    A.B b = a.new B();
}

**지역 내부 클래스**

  • 클래스의 멤버가 아닌 메서드 내에서 정의되는 클래스
  • 메서드 안에서 선언 후에 바로 객체를 생성해서 사용
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();
    }
}

어려운 내용(에러)


문제

해결

profile
백엔드 개발자

0개의 댓글