자바 오버라이딩과 오버로딩 개념과 예제

오버로딩(Overloading)

함수로 전달되는 매개변수의 유형과 개수가 다르게 하여 동일한 이름의 여러 메소드를 가지게 하는 기법

메소드 오버로딩을 덧셈 기능을 통해 알아보자

sum(1 + 4)
sum(1.0 + 4.0)

int sum(int a, int b) {
	return a+b
}

double sum(double a, double b) {
	return a+b
}

계산기의 덧셈 기능을 만든다고 가정을 하면 인자가 정수형이 올 수도 있고 실수형이 올 수도 있다. 이럴 때 사용할 수 있는 기법이 메소드 오버로딩이다. 메소드 sum()에서 인자를 (int,int) 또는 (double,double) 에 따라 자바 컴파일러가 인식을 해서 매칭시킨다.

생성자 오버로딩 생성자도 매개변수의 유형과 개수를 달리하여 동일한 이름을 가지는 생성자를 여러개 만들 수 있다.

class A {
	private String name;
	private int age = 99;
	
	A() {
		this(0, "no name")
	}

	A(int age, String name) {
		this.age = age;
		this.name = name;
	}
	
	A(int age) {
		this(age, "no name");
	}
}

A a = new A();
A a = new A(50);
A a = new A(50, "WHAT")

a 객체를 만들 때 인자의 유형과 갯수에 따라 다양하게 생성자를 호출하여 사용할 수 있다. 예를 들면 객체에 정보를 넣을 때 특정 속성이 없는 경우가 있기에 생성자를 여러개 만들어 적절하게 호출할 수 있다. 위의 코드에서는 age나 name의 인자가 없는 경우 this() 키워드를 통해 자기 자신의 다른 생성자를 호출했다.

오버라이딩(Overriding)

오버라이딩은 부모의 메소드와 똑같은 타입&이름을 가진 메소드를 자식이 가지는 것으로 기능을 확장해서 사용할 수 있다. 오버로딩(Overloading)이 메소드의 편리한 활용이라면 오버라이딩(Overriding)은 상속의 개념과 관련이 있다.

아래의 코드를 통해 오버라이딩을 살펴보자.

public class  {
    public void run() {
        print("달려")
    }
 }

public class 경찰차 extends  {
    public void siren() {
        print("삐용 삐용")
    }

    @Override
    public void run() { //확장을 원한다면 ?
		//super.run()
        print("경찰차가 달린다")
    }
}

경찰차 _경찰차 = new ()
_경찰차.run()   //

일단 오버라이딩을 하게 되면 메소드 위에 @Override 라고 표시가 만들어 진다.

부모 클래스인 차에서 run()dms “달려”만 출력한다. 하지만 자식 클래스인 경찰차에서는 run() 메소드를 오버라이딩 한 후에 “경찰차가 달린다”을 출력하는 것으로 기능을 확장시켰다.

예제

class A {	
	public void run() { 
		System.out.println("A : RUN()"); 
	}
}

class B extends A {
	public void siren() { 
		System.out.println("B : SIREN()");
	}
	
	@Override
	public void run() {
		System.out.println("B : RUN()");
	}
}

//1번
A a1 = new A();
a1.run();

//2번	
B b1 = new B();
b1.siren();
b1.run();

//3번	
A a2 = new B();
a2.run();
a2.siren(); //Compile Error
((B)a2).siren();

//4번	
B b2 = new A();    //Compile Error
B b2 = (B) new A();//Runtime Error
b2.run();

4가지의 경우를 살펴보면 1, 2번의 경우는 눈에 보이는대로 따라가면 찾을 수 있다.

3번의 경우는 자식을 참조하게 했지만 컴파일러에서는 보이지 않으므로 타입 캐스트를 통해 알려줘야 합니다. ((B)a2).siren() 을 하면 정상적으로 메소드를 사용할 수 있습니다.

4번의 경우는 컴파일 에러가 나고 타입 캐스트를 해도 안됩니다. 부모 객체 = new 자식의 경우만 정상적인 작동이 가능합니다.

class A {
	public A() {
		System.out.println("부모 호출");
	}

	public void run() { 
		System.out.println("A : RUN()"); 
	}
}

class B extends A {
	public B() {
		System.out.println("자식 호출");
	}

	public void siren() { 
		System.out.println("B : SIREN()");
	}
}

//1번
B b1 = new B();
b1.siren();
b1.run();

//2번	
A a2 = new B();
a2.run();
((B)a2).siren();

1번의 경우

2번의 경우

결론



Related Posts