다형성과 오버로딩, 오버라이딩

nkcho·2023년 2월 21일

개념 아카이빙

목록 보기
8/9

다형성?

  • 일반 명사적 의미?
    • '여러 개의 형태를 갖는다'라는 의미의 그리스어에서 유래했다. 또 사전에서 찾아보면 poly(하나 이상), morph(형태)가 합성된 단어로 '하나 이상의 형태'를 뜻한다.
  • 고유 명사적 의미?
    • 프로그램 언어의 다형성은 그 프로그래밍 언어의 자료형 체계의 성질을 나타내는 것으로, 프로그램 언어의 각 요소들(상수, 변수, 식, 오브젝트, 함수, 메소드 등)이 다양한 자료형(type)에 속하는 것이 허가되는 성질을 가리킨다. 반댓말은 단형성으로, 프로그램 언어의 각 요소가 한가지 형태만 가지는 성질을 가리킨다.
    • 같은 모양의 코드가 다른 행위를 하는 것. 핸드폰에 있는 키패드로 다이얼을 누르고, 문자를 하기도 하며, 게임을 하는 것까지 가능한 것처럼 모양은 같은데 다른 기능을 수행하는 것은 디바이스 기반의 다형성의 한 예라고 볼 수 있다.
    • 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미.
    • 객체 지향 패러다임의 4원칙(캡슐화, 다형성, 상속, 추상화) 중의 하나
  • 컴파일 다형성의 예가 오버로딩, 런타임 다형성의 예는 오버라이딩.

오버로딩(@Overloading)?

  • 일반 명사적 의미?
    • 과적하다, 너무 많이 주다(부과하다), 지나치게 많음. 과부하
  • 고유 명사적 의미?
    • Overloading allows different methods to have the same name, but different signatures where the signature can differ by the number of input parameters or type of input parameters or both. Overloading is related to compile-time (or static) polymorphism(Single function has multiple form = 다형성).
  • Overloading은 왜 사용하는가?
    • 같은 동작을 하는 함수를 매번 다른 이름으로 생성하고 기억할 필요가 없다. We don’t have to create and remember different names for functions doing the same thing. For example, in our code, if overloading was not supported by Java, we would have to create method names like sum1, sum2, … or sum2Int, sum3Int, … etc.
  • Overloading은 어떻게 사용하는가?
    • 메소드의 이름이 모두 같아야 한다.

    • 메소드에 따라 매개 변수의 개수 또는 타입이 달라야 한다. → 인자들의 타입이나 개수가 다르면 메소드 이름이 같더라도 어떤 메소드를 호출할 지 컴파일러가 알 수 있기 때문.

    • 매개 변수는 같고, 리턴 타입이 다를 때는 성립하지 않는다.

    • 오버로딩된 메소드들은 매개 변수로만 구분될 수 있다.

      // Java program to demonstrate working of method
      // overloading in Java.
      
      public class Sum {
      
      	// Overloaded sum(). This sum takes two int parameters
      	public int sum(int x, int y)
      	{
      		return (x + y);
      	}
      
      	// Overloaded sum(). This sum takes three int parameters
      	public int sum(int x, int y, int z)
      	{
      		return (x + y + z);
      	}
      
      	// Overloaded sum(). This sum takes two double parameters
      	public double sum(double x, double y)
      	{
      		return (x + y);
      	}
      
      	// Driver code
      	public static void main(String args[])
      	{
      		Sum s = new Sum();
      		System.out.println(s.sum(10, 20));
      		System.out.println(s.sum(10, 20, 30));
      		System.out.println(s.sum(10.5, 20.5));
      	}
      }
      
      //Output
      
      //30
      //60
      //31.0
  • 오버로딩을 구현한 실제 Java Development Tool 코드 중에 하나로 String.valueOf()가 있다.
  • 단, 메소드 오버로딩을 사용하는 경우 요구 사항이 바뀌었을 때 모든 메소드를 수정해야 할 수도 있으므로 꼭 필요할 때만 사용해야 한다.

오버라이딩(@Overriding)?

  • 일반 명사적 의미?

    • 과적하다, 너무 많이 주다(부과하다), 지나치게 많음. 과부하
  • 고유 명사적 의미?

    • 상속 관계에 있는 부모 클래스에서 이미 정의된 메소드를 자식 클래스에서 같은 시그니쳐(메소드 이름과 매개변수 리스트)를 갖는 메소드로 다시 정의하는 것
    • 부모 클래스와 같은 메소드 이름과 매개변수 리스트를 가지고 있지만, 구현하는 기능이 달라질 수 있다. (=상위 클래스의 메소드를 하위 클래스가 재정의)
  • 오버라이딩의 사용 조건 및 방법

    • 메소드 재정의를 위해서는 시그니쳐 통일을 해야 한다(메소드의 이름, 리턴 타입, 매개변수의 개수, 자료형의 순서를 동일하게)
    • 하지만 메소드의 반환 타입은 부모 클래스의 반환 타입으로 타입 변환할 수 있는 타입이라면 변경 할 수 있다.
    • 접근제어자는 주로 부모 클래스와 동일하게 사용하지만 접근 범위를 넓게 지정할 수 있다. (ex. 부모가 default → 자식은 public) 반대로 좁게 지정하는 것은 불가능하다.
    • 부모 클래스의 메소드보다 더 큰 범위의 예외를 선언할 수 없다.
      class SuperClass {
    			public void check() {
    			System.out.println("부모 메소드");
    		}
    
    		public void sum(int x, int y) {
    			int sum = 0;
    			for (int i = x; i <= y; i++) {
    				sum += i;
    			}
    			System.out.println("합계 : " + sum);
    			}
    		}
      class SubClass extends SuperClass {
    		public void check() { // 메소드 오버라이딩
    			System.out.println("자식 메소드");
    		}
    
    		public void sum(int x, int y) { // 메소드 오버라이딩
    			int sum = 0, odd = 0, even = 0;
    			for (int i = x; i <= y; i++) {
    				sum += i;
    				if (i % 2 == 0) {
    					even += i;
    				} else {
    					odd += i;
    				}
    			}
    			System.out.print("합계 : " + sum);
    			System.out.println("(짝수 합 : " + even + " / 홀수 합 : " + odd + ")");
    //		super.sum(x, y); // 부모 메소드 호출
        }
    }
    
    public class OverridingEx01 {
        public static void main(String[] args) {
            SubClass sub = new SubClass();
            sub.check();
            sub.sum(0, 10);
        }
    }
    • main 메소드에서 자식 클래스로 인스턴스를 생성하고 메소드를 각각 호출한 결과 자식 클래스의 메소드로 데이터가 출력되는 것을 확인할 수 있다. 즉, 부모의 메소드는 은닉되고 자식 클래스의 재정의된 메소드만 호출된다. 이 때 부모의 메소드를 호출하고 싶다면 super.(메소드명)으로 호출이 가능하다.
class Parent {
    void display() { System.out.println("부모 클래스의 display() 메소드입니다."); }
}

class Child extends Parent {
    void display() { System.out.println("자식 클래스의 display() 메소드입니다."); }
}


public class Inheritance05 {
    public static void main(String[] args) {
        Parent pa = new Parent();
        pa.display();
        Child ch = new Child();
        ch.display();
        Parent pc = new Child();
        pc.display(); // Child cp = new Parent();
    }
}

위 예제에서 main 메소드 내 세 번째와 같은 인스턴스의 참조가 허용되는 이유는 다형성 때문.

간단히 정리하자면, 오버로딩은 새로운 메소드를 정의하는 것이고, 오버라이딩은 상속받은 기존의 메소드를 재정의하는 것이다.

class Parent {
    void display() { System.out.println("부모 클래스의 display() 메소드입니다."); }
}

class Child extends Parent {
    // 오버라이딩된 display() 메소드
    void display() { System.out.println("자식 클래스의 display() 메소드입니다."); }
    void display(String str) { System.out.println(str); } // 오버로딩된 display() 메소드
}


public class Inheritance06 {
    public static void main(String[] args) {
        Child ch = new Child();
        ch.display();
        ch.display("오버로딩된 display() 메소드입니다.");
    }
}

참고한 링크
http://www.tcpschool.com/java/java_polymorphism_concept
https://www.geeksforgeeks.org/overloading-in-java/
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=heartflow89&logNo=220979244668
http://ufx.kr/blog/407
https://velog.io/@godkimchichi/Java-13-클래스다이어그램
https://mozi.tistory.com/488 : 자바 클래스 변수와 클래스 메소드(static)

profile
FE developer

0개의 댓글