Overloading이란?

한 클래스 내에 동일한 이름의 메서드를 둘 이상 정의하는 것은 허용되지 않습니다. 하지만 매개변수가 다르다면 선언이 가능합니다. 이것을 오버 로딩이라고 합니다.

Overloading조건

1. 메서드의 이름 같음

2. 메서드의 매개변수 다름

(주의 반환형이 다른 것은 오버 로딩으로 볼 수 없습니다.)

 

Overloading 이점

1. 하나의 이름으로 메서드의 같은 기능을 정의할 수 있습니다. 

System.out.println 에서 볼 수 있습니다. Sytem.out.println()의 함수들을 살펴보겠습니다. 

public void println(boolean x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}

public void println(char x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}

public void println(int x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}

public void println(long x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}

public void println(float x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}
  • println이 의미하는 출력하고 한 줄 개행은 어떠한 매개변수가 들어와도 변하지 않습니다. 따라서 println의 매개변수들이 어떻게 실행되는지 모르지만 출력하고, 한 줄 개행이라는 공통된 기능을 제공하는 것을 알 수 있습니다. 

2. 메소드의 이름을 절약할 수 있습니다. 

위에서 본 System.out.println()의 오버 로딩이 안됐을 경우를 보겠습니다. 

public void printlnBoolean(boolean x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}

public void printlnChar(char x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}

public void printlnInt(int x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}

public void printlnLong(long x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}

public void printlnFloat(float x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}
  • 만약 오버로딩이 없다면, 코드처럼 매개변수로 들어올 수 있는 것을 메서드 이름으로 명시해야 합니다. 하지만 오버 로딩을 통해 하나의 메서드 이름으로 여러 가지 유형의 매개변수를 처리해 메서드 이름 절약이 가능합니다.

오버 로딩 사용

일반 메소드

Printer 클래스의 print는 int형 들어온다면, 덧셈을 하여 출력합니다. String클래스가 들어온다면, 공백을 넣고 출력합니다.

class Printer{

    public void print(int a, int b){
        System.out.println(a+b);
    }
    
    public void print(String a, String b){
        System.out.println(a+" "+b);
    }
}
Printer printer = new Printer();
printer.print(1,2); // 3출력
printer.print("1","2"); // 1 2 출력
  • 같은 이름의 메서드라도 매개변수를 다르게 전달함으로써 다른 기능이 수행되는 것을 볼 수 있습니다.

생성자

일반 메서드에서 오버 로딩을 적용할 수 있듯이 생성자에도 가능합니다.

 

Person 객체를 생성할 때 나이와 이름을 넘길 수 있고, 나이만 넘길 수도 있습니다. 이때 이름은 비밀로 저장됩니다.

class Person{

    int age;
    String name;

    public Person(int age, String name){
        this.age=age;
        this.name=name;
    }

    public Person(int age){
        this.age=age;
        this.name="secret";
    }
}
Person p1 = new Person(1,"kim");
Person p2 = new Person(10);

System.out.println(p1.toString()); //age: 1 name: kim 출력
System.out.println(p2.toString()); // age: 10 name: secret 출력
  • 생성자에도 오버 로딩을 적용하여, 변수를 다르게 초기화할 수 있었습니다. 

생성자 같은 경우 this를 사용할 수 있습니다. 위 코드 동일하게 동작하는 코드입니다.

class Person{

    int age;
    String name;

    public Person(int age, String name){
        this.age=age;
        this.name=name;
    }

    public Person(int age){ // age만 넘어올 경우 Person 객체의 Person(int String)을 호출해줍니다.
        this(age,"secret");
    }

    @Override
    public String toString() {
        return "age: "+age +" name: "+name;
    }
}

Overriding이란? 

상위 클래스에 정의된 메서드를 하위 클래스에서 재정의 하는 것을 의미합니다. 코드를 보겠습니다.

 

모든 클래스는 Object를 상속받고 있습니다. 따라서 모든 class는 별도로 toString을 정의하지 않으면 기본적으로 아래의 형태로 출력됩니다.

class Object{
	public String toString() {
   		return getClass().getName() + "@" + Integer.toHexString(hashCode());
	}
}
public class Main {
    public static void main(String[] args) throws IOException {

        Person p1 = new Person(1,"kim");
        Person p2 = new Person(10);

        System.out.println(p1.toString());
        System.out.println(p2.toString());
    }
}
  • 출력 내용입니다.

toString을 Overriding 하여 재정의 해보겠습니다.

@Override
public String toString() {
    return "age: "+age +" name: "+name;
}
  • 바뀐 출력 내용을 볼 수 있습니다.

상속받은 메서드를 사용할 수도 있습니다.

@Override
public String toString(){
    if(age==1){ // age가 1이라면 이것을 반환
        return "age: "+age + " name: "+name;
    }
    else{ // 그외에 상속받은 메소드를 호출
        return super.toString();
    }
}
Person p1 = new Person(1,"kim");
Person p2 = new Person(10);

System.out.println(p1);
System.out.println(p2);

  • 별거 아닌 기능 같지만 상속을 사용하는 객체지향에서는 다방면에서 활용됩니다. 

 


정리

Overloading -> 하나의 클래스에 같은 이름의 메서드를 여러 개 정의하며, 매개변수에 따라서 다르게 동작할 수 있게 해 준다. 

Overriding -> 상속받은 객체의 메서드를 재정의하여 추가적인 기능을 추가하거나, 다르게 동작하도록 할 수 있다. 

 

'JAVA' 카테고리의 다른 글

Java Garbage Collection  (0) 2022.05.30
이펙티브 자바  (0) 2022.04.22
JAVA Enum  (0) 2022.02.24
JAVA Stream  (0) 2022.02.23
JAVA Optional<T>  (0) 2022.02.23