본문 바로가기
개발/JAVA

[JAVA개념]객체지향언어-3

by Develaniper 2021. 5. 11.

오늘도 객체지향!! 오늘은 Chapter6을 끝낼 수 있을 것 같아요~

1. 메서드 오버로딩

  자바의 한 클래스 내에서 사용하고 있는 메서드의 이름이 여러개 중복되더라도 매개변수의 개수나 타입이 다르다면 여러개의 메서드를 정의할 수 있는데 이것을 오버로딩이라고 한다.

 

오버로딩에는 몇가지 조건이 있다.

 - 메서드 이름이 같아야한다.

 - 매개변수의 개수 혹은 타입이 달라야한다.

 - 매개변수가 같으면 리턴타입이 달라도 오버로딩이 아니다.

 

 오버로딩의 예

void println()
void println(boolean x)
void println(char x)
void println(char[] x)
void println(double x)
void println(float x)
void println(int x)
void println(long x)
void println(Object x)
void println(String x)

- 오버로딩의 장점

 같은 역할을 하는 메서드들은 같은 이름으로 작성하여 이름을 짓기도 쉽고 사용할 때 기억하기(예측하기)도 편하다.

 

2. 생성자

- 인스턴스가 생성될 때 호출되는 '인스턴스를 초기화 하는 메서드'이다. 

생성자 또한 몇가지 조건이 있다.

 - 클래스와 이름이 같아야한다.

 - 생성자는 리턴 값이 없다.

 

생성자의 예

public ConstTest{
	ConstTest(){
    	//...
    }
    ConstTest(int a, String b){
    	//...
	}
}

 

생성자는 몇가지 특징을 제외하면 메서드와 같다. 다음은 생성자의 특징이다.

 - 연산자 new에 의해 메모리(heap)에 ConstTest클래스의 인스턴스가 생성된다.

 - 생성자 ConstTest()가 호출되어 수행된다.

 - 연산자 new의 결과로, 생성된 ConstTest인스턴스의 주소가 반환되어 참조변수에 저장된다.

 

※ 기본 생성자

 - 모든 클래스는 생성자가 필수이지만 기본 생성자인 ConstTest()를 사용하지 않아도 아무런 문제 없이 사용할 수 있었다. 이는 컴파일러가 제공하는 '기본 생성자' 덕분이었다.

 - 컴파일 시 소스파일의 클래스에 생성자가 하나도 없을 경우 컴파일러는 자동으로 클래스이름(){ } 과같은 생성자를 추가하여 컴파일 한다.

 

 

 

반면에 생성자에 매개변수가 있는 단하나의 생성자를 만들고 정작 인스턴스를 생성할 때는 매개변수를 추가하지 않는다면 에러가 생길 수 있다.

class ConstructorTest{
    public static void main(String[] args) {
        ConstTest c = new ConstTest();
        //The constructor ConstTest() is undefined

    }
}
class ConstTest{
    ConstTest(int a){
        System.out.println(a);
    }
}

따라서 매개변수가 있는 생성자만을 사용하려고 해도 매개변수가 없는 생성자를 추가한 아래와 같은 형식으로 클래스를 작성해야 한다.

class ConstTest{
    ConstTest(){
    }
    ConstTest(int a){
        System.out.println(a);
    }
}

컴파일러가 기본 생성자를 추가하는 경우는 생성자가 아에 없을 때 뿐이기 때문이다.

 

- 매개변수가 있는 생성자

매개변수가 있는 생성자의 경우는 보통 인스턴스변수를 초기화 하며 사용하기 위함이다.

class CarTest {
    public static void main(String[] args) {
        Car c = new Car("sonata", "white", 210);
        System.out.println("c의 이름 : "+ c.name+", 색 : "+ c.color+", 최대속력 : "+ c.maxSpeed);
        // c의 이름 : sonata, 색 : white, 최대속력 : 210
    }
    
}
class Car{
    String name;
    String color;
    int maxSpeed;
    Car(){  // 매개변수가 있는 생성자를 만들기 위해서는 필수

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

따라서 앞으로는 위와같은 코드를 많이 볼 것이다.

 

- 생상자에서 다른 생성자 호출하기(this())

class Car{
    String name;
    String color;
    int maxSpeed;
    Car(){  // 매개변수가 있는 생성자를 만들기 위해서는 필수
    	this("", "silver", 200);
    }
    Car(String name){
    	this(name, "silver", 200);
    }
    Car(String name, String color, int maxSpeed){
        this.name = name;
        this.color=color;
        this.maxSpeed = maxSpeed;
    }
}

위와같이 this()를 통해 다른 생성자를 호출할 수 있고 this.name과 같은 코드를 통해 클래스의 인스턴스변수를 가르킬 수 있다.

 ※주의사항

 - 생성자에서 다른 생성자를 호출하려면 가장 첫줄에 호출해야 한다. 이유는 생성자에서 초기화를 하는 도중 다른 생성자를 호출하면 그 값이 달라질 수 있기 때문이다.

 - this는 참조변수로 인스턴스 자신을 가리킨다.

 

 생성자를 통한 인스턴스 복사

package chapter6_ObjectOriented;

class CarTest {
    public static void main(String[] args) {
        Car c1 = new Car("sonata", "white", 210);
        System.out.println("c1의 이름 : "+ c1.name+", 색 : "+ c1.color+", 최대속력 : "+ c1.maxSpeed);
        // c의 이름 : sonata, 색 : white, 최대속력 : 210

        Car c2 = new Car(c1);

        System.out.println("c1의 이름 : "+ c1.name+", 색 : "+ c1.color+", 최대속력 : "+ c1.maxSpeed);
        System.out.println("c2의 이름 : "+ c2.name+", 색 : "+ c2.color+", 최대속력 : "+ c2.maxSpeed);

        c2.name = "K5";
        c2.color = "black";
        
        System.out.println("c1의 이름 : "+ c1.name+", 색 : "+ c1.color+", 최대속력 : "+ c1.maxSpeed);
        System.out.println("c2의 이름 : "+ c2.name+", 색 : "+ c2.color+", 최대속력 : "+ c2.maxSpeed);


//          c1의 이름 : sonata, 색 : white, 최대속력 : 210
//          c1의 이름 : sonata, 색 : white, 최대속력 : 210
//          c2의 이름 : sonata, 색 : white, 최대속력 : 210
//          c1의 이름 : sonata, 색 : white, 최대속력 : 210
//          c2의 이름 : K5, 색 : black, 최대속력 : 210
    }
    
}
class Car{
    String name;
    String color;
    int maxSpeed;
    Car(){  // 매개변수가 있는 생성자를 만들기 위해서는 필수
    	this("", "silver", 200);
    }
    Car(Car c){  // 매개변수가 있는 생성자를 만들기 위해서는 필수
    	this(c.name, c.color, c.maxSpeed);
    }
    Car(String name, String color, int maxSpeed){
        this.name = name;
        this.color=color;
        this.maxSpeed = maxSpeed;
    }
}

이와같이 생성자를 통해 인스턴스 변수를 복사하게 되면 간단하게 복사가 가능하고, 전처럼 c2가 c1의 참조 변수를 가리키는 일이 생기지 않게 된다.

 

 

초기화 블록

public class AreaTest {
    public static void main(String[] args) {
        System.out.println("Area 생성 전");
        Area a1 = new Area();
        Area a2 = new Area();
        Area a3 = new Area();
    }
}

class Area{
    static int number;
    static{
        number=0;
        System.out.println("number is generated as"+number);
    }
    {
        number++;
    }
    Area(){
        System.out.println("number : "+this.number);
    }
}
// Area 생성 전
// number is generated as0
// number : 1
// number : 2
// number : 3

위와 같이 static{} 블록을 이용하여 클래스가 처음 만들어 질때 1번만 number를 초기화 했으며 그 이후로는 number를 ++하며 증가된 number를 갖을 수 있다. 즉, 같은 클래스를 사용하는 모든 인스턴스는 static 변수값을 공유한다.

댓글