학습목표
- 생성자 개념
- 기본생성자
- 매개변수가 있는 생성자
- this.
- this() 메서드
배운 내용
**생성자(Constructor)**
- 객체를 생성하는 역할을하는 클래스 구성요소
- 인스턴스가 생성될 때 호출되는 인스턴스 초기화 메서드
생성자가 필요한 이유
- 정보 은닉을 하기위해 private 영역에 변수를 선언해 놓으면 main문에서 접근 하는 것이 불가능하다. 그래서 public 영역에 생성자를 만들어 놓으면 main문에서 생성자를 통해서 변수의 값에 간접적으로 접근할 수 있다.
생성자 구조
- 생성자의 이름은 반드시 클래스의 이름과 같아야 한다.
- 생성자는 리턴 타입이 없다.
클래스명(매개변수) {
...생략...
}
생성자 오버로딩
class Constructor {
Constructor() {
System.out.println("1번 생성자");
}
Constructor(String str) {
System.out.println("2번 생성자");
}
Constructor(int a, int b) {
System.out.println("3번 생성자");
}
}
**기본 생성자(Default Constructor)**
- 모든 클래스에는 반드시 하나 이상의 생성자가 존재해야 한다.
- 생성자가 클래스 안에 포함되어 있지 않은 경우에는 자바 컴파일러가 기본 생성자를 자동으로 추가
- 기본생성자 :
클래스명(){}
- 기본 생성자에는 매개변수도 없고 바디에 아무런 내용이 없다.
**매개변수가 있는 생성자**
클래스명(int a, int b){}
: 매개변수를 통해 호출시에 해당값을 받아 인스턴스를 초기화
this()
this()
메서드: 자신이 속한 클래스에서 다른 생성자를 호출할때 사용
조건
this()
메서드는 반드시 생성자의 내부에서만 사용 가능
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의 세 번째 생성자 호출");
}
}
**this 키워드(내부객체 참조 변수명)**
- 모든 메서드에는 자신이 포함된 클래스의 객체를 가리키는
this
라는 참조변수가 있다.
this.
를 생략하면 컴파일러가 자동으로 this.
를 추가
this
는 인스턴스 자신을 가리키며, this
를 통해서 인스턴스 자신의 변수에 접근한다.
- 클래스의 외부에서 멤버(필드, 메서드, 이너 클래스)를 호출하기 위해서는 객체를 먼저 생성한 후
‘참조 변수명.맴버명'
의 형태로 호출하지만, 클래스 내부`에서는 객체의 생성 없이 필드와 메서드를 바로 사용할 수 있다
- 모든 사용할 수 있는 상태의 맴버는 항상
객체 속
에만 존재, 클래스 내부에서도 객체 안의 멤버를 사용하기 위해 this.
키워드 통해 접근
- 지역 변수는 맴버가 아니므로
this.
가 자동으로 붙지 않는다.
- 지역 변수와 필드 모두를 사용할 수 있는 영역에서는 사용 범위가 좁은 변수, 즉 지역 변수로 인식
- 따라서
init()
메서드 안에서 m = m
, n = n
과 같이 작성하면 컴파일러는 이들 모두를 지역 변수로 인식this.
는 당연히 추가되지 않고 지역변수 m
← m
값을 대입]
- 자바에서 제공하는 대부분의
API
에는 메서드의 지역 변수명이 필드명과 동일하게 구성되 있다.
class A{
int m,n;
void init(int m, int n) {
m = m;
n = n;
}
}
class B{
int m;
int n;
void init(int m, int n) {
this.m = m;
this.n = n;
}
}
**내부 클래스**
- 클래스 내에 선언된 클래스, 외부클래스와 내부클래스가 서로 연관있을때 사용
장점
- 외부클래스의 멤버들에 쉽게 접근 가능
- 코드 복잡성 줄일 수 있다.
- 외부의 불필요한 데이터 감출수 있다(캡슐화)
종류
종 류 | 선언 위치 | 사용 가능한 변수 |
---|
인스턴스 내부 클래스(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();
}
}
어려운 내용(에러)
문제
해결