[JAVA] 메소드 오버로딩 / 메소드오버라이딩

정효진·2021년 8월 7일
1

Developer Study

목록 보기
24/47
post-thumbnail

★ 메소드 오버로딩 / 오버라이딩은 면접 단골 문제이기 때문에 말로 설명할수 있어야함!!★

◼메소드 오버로딩(Method Overloading)

  • 보통 하나의 메서드로 하나의 기능만 구현해지만
  • 하나의 메서드로 여러 기능을 구현하기 때문에 붙여진 이름이다.

▪ 메소드 오버로딩이란

메소드가 처리하는 기능은 같고,
메소드 괄호 속에 오는 인수(인자, 매개변수, 파라미터)의 갯수가 다르거나
자료형(Date Type)이 다른 경우
메소드의 이름을 동일한 이름으로 부여하여 메소드를 정의할 수 있도록
문법적으로 허용하게 되는데
이를 메소드 오버로딩(Method Overloading)이라고 한다.

▪ 메소드 오버로딩 코드 설명📝

public class Test099
{
	public static void main(String[] args)
	{
		drawLine();
		//--==>> ====================
		drawLine('+');
		//--==>> ++++++++++++++++++++

		drawLine('>');
		//--==>> >>>>>>>>>>>>>>>>>>>>

		drawLine('/',50);
		//--==>> //////////////////////////////////////////////////


		drawLine('+',50);
		//--==>> ++++++++++++++++++++++++++++++++++++++++++++++++++


	}

	// 선을 그리는 메소드 정의
	public static void drawLine()
	{
		System.out.println("====================");	
	}

	// 선의 형태를 바꾸어 그리는 메소드 정의    ====> 이거는 메소드 오버로딩이 아니다!
	/*
	public static void drawLine()
	{
		System.out.println("++++++++++++++++++++")
	}
	*/

	public static void drawLine(char c)
	{
		for (int i=0; i<20; i++)
		{
			System.out.print(c);
		}
		System.out.println();	
	}

	//선의 형태와 길이를 바꾸어 그리는 메소드 정의
	public static void drawLine(char c, int n)
	{
	

			for (int i=0; i<n; i++)

				System.out.print(c);

			System.out.println();

	
	}
}

▪ Method Overloading 이 가능한 형태와 불가능한 형태 코드 설명📝

public class Test100
{
	
	public static void main(String[] args)
	{
		print('A');
		print(10, 20);
		print(10,'A');

		double result = print(3.14);
		print(4.75);                    //11번과 12번은 다른거처럼보이지만 자바는 print(xxx)부터 보기때문에 같은 것!
	}

	public static void print() {}
	public static void print(int i) {}
	//public static void print(int j) {}                    //--(X) 자료형과 변수갯수가 같아서 구분이 안됨
	public static void print(char c) {}                     //-- 자동 형 변환 규칙 check~!!!
	public static void print(int i, int j) {}               //-- i가 같은걸보는게 아니라 매개변수의 갯수!
	public static void print(double d) {}
	//public static void print(double d) {return 10.0;}     //-- 정의 불가 void인데 리턴자료형
	//public static double print(double d) {return 10.0;}   //--(X) 위에 23번줄 double d 와 구분 불가  check~!!!

▪ 메소드 오버로딩 중복 코드

class Calculator{
    int left, right;
    int third = 0;
      
    public void setOprands(int left, int right){
        System.out.println("setOprands(int left, int right)");
        this.left = left;
        this.right = right;
    }
     
    public void setOprands(int left, int right, int third){
        this.setOprands(left, right);       //-- check~!!!! 오버로딩하면 14,15줄의 중복을 이런식으로 줄일 수 있음!!
	System.out.println("setOprands(int left, int right, int third)");
        //this.left = left;
        //this.right = right;
        this.third = third;
    }
     
    public void sum(){
        System.out.println(this.left+this.right+this.third);
    }
      
    public void avg(){
        System.out.println((this.left+this.right+this.third)/3);
    }
}
  
public class CalculatorDemo {
      
    public static void main(String[] args) {
          
        Calculator c1 = new Calculator();
        c1.setOprands(10, 20);
        c1.sum();       
        c1.avg();
        c1.setOprands(10, 20, 30);
        c1.sum();       
        c1.avg();
         
    }
  
}
/*
setOprands(int left, int right)
30
10
setOprands(int left, int right)
setOprands(int left, int right, int third)
60
20
계속하려면 아무 키나 누르십시오 . . .
*/

◼메소드 오버라이딩(Method Overriding)

▪ 메소드 오버라이딩(Method Overriding)

상위 클래스(부모 클래스)를 상속받은 하위 클래스(자식 클래스)에서
상위 클래스에 정의된 메소드를 다시 정의하는 것으로(재정의)
객체 지향 프로그래밍의 특징인 다형성을 나타낸다.
재정의(Overriding)는 반드시 상속 관계에 있어야 하며,
메소드의 이름, 리턴타입, 매개변수의 갯수나 타입이
완전히 일치해야 한다.

▪ 메소드 오버라이딩(Method Overriding)의 특징

  • 메소드 이름, 리턴타입, 파라미터 수나 타입이 완전히 일치해야 한다.
  • 반드시 상속 관계가 있어야 한다.
  • 재정의된 하위 클래스의 메소드 접근제어지시자는 상위 클래스의 메소드 접근제어지시자보다 범위가 크거나 같아야 한다.
    예를 들어, 상위 클래스 메소드의 접근제어지시자가 『protected』인 경우 하위 클래스가 이 메소드를 오버라이딩(Overriding)하는 경우 접근제어지시자는 『protected』 또는 『public』이어야 한다.
  • 『static』,『final』,『private』 메소드는 오버라이딩(Overriding)할 수 없다.
  • Exception의 추가가 불가능하다.
    즉, 상위 클래스의 메소드가 가지고 있는 기존 예외 사항에
    새로운 Exception 을 추가하는 것은 불가능하다는 것이다.
-> @Override void 메소드(int n) throws IOException, A   불가능!!
					      // ----

▪ 메소드 오버라이딩 코드

class SuperTest108
{
	protected double area;
	private String title;

	public SuperTest108()
	{
		System.out.println("SuperTest108... 인자 없는 생성자");
	}

	public SuperTest108(String title)
	{
		this.title = title;
		System.out.println("SuperTest108... 문자열을 인자로 받는 생성자");
	}

	public void write()
	{
		System.out.println(title + " - " + area);
	}
}

class Rect108 extends SuperTest108
{
	private int w, h;  // w, h, area
	
	public Rect108()
	{
		//super();  //자동으로 삽입
	}

	public void calc(int w, int h)
	{
		this.w = w;
		this.h = h;
		area = (double)this.w * this.h;

		write();
	}

	@Override
	public void write()
	{
		System.out.println("W: " + w + ", h : " + h);
		System.out.println("사각형 - " + area);
	}
}//end class Rect108

class Circle108 extends SuperTest108
{
	public Circle108(String title)
	{
		super(title);
	}

	public void calc(int r)
	{
		area = r * r * 3.141592;
		write();
	}
}

public class hyodii108
{
	public static void main(String[] args)
	{
		Rect108 ob1 = new Rect108();
		
		ob1.calc(10,20);
		//--==>>SuperTest108... 인자 없는 생성자
		//		W: 10, h : 20
		//		사각형 - 200.0

		Circle108 ob2 = new Circle108("아무거나 입력해도 됌");
		ob2.calc(11);
		//--==>>SuperTest108... 문자열을 인자로 받는 생성자
		//		원 - 380.132632
		
	}
}

▪ 메소드 오버라이딩 코드 설명📝


// Rect108 클래스와 Circle108 클래스의 부모 클래스
class SuperTest108
{
	protected double area;  // protected를 썻다!? -> 이거는 거의 상속을 염두해도 만들었다고 봐도 됨
	private String title;   // 프라이베잇은 자식이 접근을 못함!

	//부모 클래스의 인자없는 사용자 정의 생성자
	public SuperTest108()
	{
		System.out.println("SuperTest108... 인자 없는 생성자");
	}

	//부모 클래스의 문자열을 인자로 받는 사용자 정의 생성자
	public SuperTest108(String title)
	{
		this.title = title;
		System.out.println("SuperTest108... 문자열을 인자로 받는 생성자");
	}

	public void write()
	{
		System.out.println(title + " - " + area);
	}


	

}

// SuperTest108 클래스를 상속받는 자식 클래스
class Rect108  extends SuperTest108
{
	/* 이거 두개 상속받은것!!

	protected double area;  // protected를 썻다!? -> 이거는 거의 상속을 염두해도 만들었다고 봐도 됨
	

	public void write()
	{
		System.out.println(title + " - " + area);
	}

	*/
	
	private int w, h;  //w,h,area 가지고있는 변수 위에 상속까지

	//자식 클래스의 사용자 정의 생성자
	public Rect108()
	{
		// 자동으로 삽입
		//super();      //== SuperTest108();

		//super는 내가 속해있는 클래스 Rect108의 상속인 SuperTest108
	}

	public void calc(int w, int h)
	{
		this.w = w;
		this.h = h;
		//area = (double)this.w * h;// 이러면 매개변수 h이고 this.있으면 위에 private의 h
		area = (double)this.w * this.h;  //여기서 area는 물려받은 area
		//super.area = (double)this.w * this.h;  //라고 해도됨
		//this.area = (double)this.w * this.h;   //내가 가진 area라고 해도됨

		write();
	}

	@Override           //-- 어노테이션(annotation) - metadata - JDK 1.5 이상부터 지원됨
	public void write()
	{
		System.out.println("w : " + w + ", h : " + h);
		System.out.println("사각형 - " + area);
	}

	// ※ 메소드 오버라이딩(Method Overriding)

	//		상위 클래스(부모 클래스)를 상속받은 하위 클래스(자식 클래스)에서
	//		상위 클래스에 정의된 메소드를 다시 정의하는 것으로(재정의)
	//		객체 지향 프로그래밍의 특징인 다형성을 나타낸다.
	//		재정의(Overriding)는 반드시 상속 관계에 있어야 하며,
	//		메소드의 이름, 리던타입, 매개변수의 갯수나 타입이
	//		완전히 일치해야 한다.

	// 메소드 오버로딩은 가져가다 쓰는 것이고 메소드 오버라이딩은 가져다가 !덮어쓰는것!
}

// SuperTest108 클래스를 상속받는 자식 클래스
class Circle108  extends SuperTest108
{
	/* 이거 두개 상속받은것!!

	protected double area;  // protected를 썻다!? -> 이거는 거의 상속을 염두해도 만들었다고 봐도 됨
	

	public void write()
	{
		System.out.println(title + " - " + area);
	}

	*/
	
	/*
	// default생성자 -> 아래의 사용자 정의 생성자가 있기 때문에 생성자가 생기지 않음!!!
	public Circle108()
	{
		
	}
	*/
	
	//자식 클래스의 문자열을 인자로 받는 사용자 정의 생성자
	public Circle108(String title)
	{	//super(); 가 자동으로 삽입되기 때문에 인자없는생성자가 호출되는데 밑에 써주면 문자열로 인자를받는 생성자 호출!	
		super(title);
	}

	
	public void calc(int r)
	{
		area = r * r * 3.141592;
		write();
	}
}

// main() 메소드를 포함하고 있는 외부의 다른 클래스
public class Test108
{
	public static void main(String[] args)
	{
		Rect108 ob1 = new Rect108();
		//--==>> SuperTest108... 인자 없는 생성자  

		//Circle108 ob2 = new Circle108();
		//--==>> 에러 발생(컴파일 에러)
		//-- 현재 Circle108 클래스에는
		//	 매개변수를 필요로 하는 사용자 정의 생성자가 만들어져 있으며
		//   이로 인해 default 생성자가 자동으로 삽입되지 않은 상황.

		ob1.calc(10,20);
		//--==>>SuperTest108... 인자 없는 생성자
		//		W: 10, h : 20
		//		사각형 - 200.0

		Circle108 ob2 = new Circle108("원");
		ob2.calc(11);
		//--==>>SuperTest108... 문자열을 인자로 받는 생성자
		//		원 - 380.132632
	}
}

※ 메소드 오버로딩은 가져가다 쓰는 것이고, 메소드 오버라이딩은 가져다가 !덮어쓰는것!

profile
개발새발

0개의 댓글