말 그대로 객체를 생성하는 역할을 하는 클래스의 구성 요소이다.
인스턴스가 생성될 때 호출되는 인스턴스 초기화 메서드
클래스명(매개변수) { // 생성자 기본 구조
...생략...
}
생성자도 오버로딩이 가능
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번 생성자");
}
}
모든 클래스에는 반드시 하나 이상의 생성자가 존재해야 한다.
클래스명(){} //기본 생성자
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()
메서드는 자신이 속한 클래스에서 다른 생성자를 호출하는 경우에 사용한다.
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의 두 번째 생성자 호출!
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