숨 참고 JAVA 다이브 🌊 (11) - 오버로드, 객체 형변환

joyfulwave·2022년 8월 17일
0

숨 참고 JAVA 다이브

목록 보기
11/21

어려울 거 같아서 미뤄뒀던 프로그래밍 공부 이번에 숨 딱 참고 Java 다이브 💦


💡 오버로드

오버로드로 메서드의 다양성을 지켜줄 수 있어요.

📎 메서드 오버로드(Overload)

  • 원칙적으로 하나의 클래스 안에는 동일한 이름의 메서드가 두개 이상 존재할 수 없지만, 이를 가능하게 하는 예외적인 처리 기법이에요.

⚫️ 이름이 동일한 메서드를 정의하기 위한 조건

  • 메서드간의 파라미터가 서로 달라야해요.
    - 파라미터의 데이터 타입이 다른경우. (데이터 형이 동일하고 변수의 이름이 다른 경우는 동일한 파라미터로 인식돼요.)
    - 파라미터의 개수가 다른 경우.
    - 파라미터들의 전달 순서가 다른 경우

  • 리턴형이 다른 경우는 오버로드의 성립에 아무런 영향을 주지 않아요.

⚫️ 생성자의 Overload

  • 객체 생성 방법의 다양화
  • 생성자 역시 메서드의 한 종류이므로 Overload가 가능해요.
  • 생성자를 Overload 할 경우, 해당 클래스에 대해 객체를 생성하는 방법을 다양하게 준비할 수 있게 돼요.
  class Hello{
      Hello(){ 
          System.out.println("Hello"); 
      } 
      Hello(String msg){ // 생성자의 Overload
          System.out.println(msg);
      }
  }

  public class Main01 {

      public static void main(String[] args) {
      	  // 기본 생성자 출력
          Hello h1 = new Hello();
          // Overload된 생성자 출력
          Hello h2 = new Hello("안녕하세요");
      }
  }
  
  /*
  출력결과)
  Hello
  안녕하세요.
  */

⚫️ this 키워드를 사용한 생성자 Overload

  • this 키워드의 용법
    - 메서드처럼 사용할 경우, 현재 클래스의 다른 생성자를 의미해요.
  • this 키워드를 사용하여 생성자 Overload를 간결하게 처리할 수 있어요. 파라미터가 서로 다른 생성자들이 하나의 완전한 생성자를 호출하도록 하여, 데이터의 초기화를 한 곳에서 일괄적으로 처리하도록 구현할 수 있어요.
  public class Article {
      private int seq;
      private String subject;
      private String writer;

      public Article(int seq, String subject, String writer) {
          super();
          this.seq = seq;
          this.subject = subject;
          this.writer = writer;
      }

      public Article(int seq) {
          //this.seq = seq;
          //this.subject = "제목없음";
          //this.writer = "익명";
          this(seq, "제목없음", "익명");
      }

      public Article(int seq, String subject) {
          //this.seq = seq;
          //this.subject = subject;
          //this.writer = "익명";
          this(seq, subject, "익명");
      }

      @Override
      public String toString() {
          return "Article [seq=" + seq + ", subject=" + subject 
                  + ", writer=" + writer + "]";
      }


  }



💡 객체 형변환

  • Java 기본 유형의 데이터들처럼 객체 참조변수의 경우에도 형변환(casting)이 이루어져요.

Parent parent = new Child();

  class Unit{ .. }
  class Army extends Unit{ .. }
  
  public class Main{
  	public static void main(String[] args){
    	Unit u = new Army();
    }
  }

서로 다른 클래스 유형으로부터 나온 객체 참조변수들 간의 대입에는 일정한 규칙이 있어요.

  • 왼쪽 항(부모 클래스)과 오른쪽 항(자식 클래스)의 객체 유형이 서로 다른 경우, 두 유형이 서로 상속 관계에 있고 왼쪽 객체(부모 클래스)가 오른쪽 객체(자식 클래스)의 상위 클래스인 경우에만 암묵적 형변환이 일어나요.
  • 하위 클래스에서 상위클래스 유형으로 할당하는 것은 가능하나 그 반대의 경우에는 명시적 형변환을 해야해요. 그러나 상위 클래스 유형을 하위 클래스 유형으로 강제 형변환하는 경우에는 할당되는 객체의 유형에 따라서 실행 오류가 발생할 수 있어요.

📎 객체간의 암묵적 형변환

	A a1 = new B(); // 암묵적 형변환 가능
	A a2 = new X(); // 암묵적 형변환 가능
	A a3 = new C(); // 암묵적 형변환 가능
	A a4 = new Y(); // 암묵적 형변환 가능
	---------------
	B b1 = new C(); // 암묵적 형변환 가능
	X x1 = new Y(); // 암묵적 형변환 가능
	---------------
	C c = new C();
	B b2 = c;	// 암묵적 형변환 가능
	---------------
	Y y = new Y();
	X x2 = y;	// 암묵적 형변환 가능
	---------------

⚫️ 암묵적 형변환과 메서드 오버라이드

  • 암묵적 형변환은 부모를 상속받는 자식객체의 기능을 부모에게 물려받은기능만 사용하도록 제한해요.
  • 그러므로 암묵적 형변환이 발생하게 되면 오버라이드된 기능만 사용가능하고, 추가적으로 구현한 기능은 사용할 수 없어요.
  • 주의할 점은 기능의 제한이지 기능의 변경은 아니에요.
	class Unit{
    	public void attack(){ .. }
    }    
    
    class Army extends Unit{ 
    	public void tank(){ .. }
    }
    
    class Navy extends Unit{
    	public void nucleus(){ .. }
    }
    
    class AirForce extends Unit{ 
    	public void bombing(){ .. }
    }
    
    public class Main{
    	public static void main(String[] args){
          Unit u1 = new Army();
          Unit u2 = new Navy();
          Unit u3 = new AirForce();
          
		  // 오버라이드 된 메서드 사용 가능
          u1.attack();
          u2.attack(); 
          u3.attack();
          
          // 추가적으로 구현한 메서드 사용 불가능
          //u1.tank(); 
          //u2.nucleus(); 
          //u3.bumbing(); 
        }
    }
	

📎 명시적 형변환

  • 암시적 형변환으로 인하여 추가적으로 작성된 메서드들을 다시 사용할 수 있게 해줘요.
  • 부모 클래스의 객체를 자식 클래스 형태로 변환하는 거에요.
  • 형변환을 위해서는 변환할 클래스 이름을 명시적으로 지정해줘야해요.

ChildCalss child = (ChildClass)parent;

⚫️ 명시적 형변환의 조건

  • 객체가 최초 생성될 때 자식 클래스 형태로 생성되고, 부모 형태로 암묵적 형변환이 된 상태를 다시 원래 자식 클래스 형태로 되돌릴 경우에만 가능해요.

ChildClass child1 = new ChildClass();
PartentClass parent= child; //암묵적 형변환
ChildClass child2 = (ChildClass)parent; //명시적 형변환

⚫️ 명시적 형변환이 가능한 경우

(1)

  Army arm1 = new Army();
  Unit u = army1;
  Army army2 = (Army)u;

(2)

  Unit u = new Navy();
  Navy navy = (Navy)u;

⚫️ 명시적 형변환이 불가능한 경우

(1) : 최초 객체 생성이 부모 형태로 만들어진 경우에 불가능해요.

  Unit u = new Unit();
  Army army = (Army)u;

(2) : 최초 생성된 것과 다른 형식으로 변환하는 것은 불가능해요.

  Army army= new Army();
  Unit u = army;
  Navy navy = (Navy)u;

위의 두 경우 모두 문법적인 오류는 없기 때문에, 이클립스에서는 에러를 검출하지 못해요. 하지만 프로그램을 실행시켰을 경우에는 에러가 발생해요.

	class Unit{
    	public void attack(){ .. }
    }    
    
    class Army extends Unit{ 
    	public void tank(){ .. }
    }
    
    class Navy extends Unit{
    	public void nucleus(){ .. }
    }
    
    class AirForce extends Unit{ 
    	public void bombing(){ .. }
    }
    
    public class Main{
    	public static void main(String[] args) {
		
		// 자식 클래스로 객체 생성
		AirForce af = new AirForce("공군");
		Navy nv = new Navy("해군");
		Army am = new Army("육군");
		
		// 각각의 객체는 자신들의 고유 기능을 사용할 수 있다.
		af.bombing();
		nv.nucleus();
		am.tank();
		
		System.out.println("--------------------");
		
		// 암묵적 형변환
		Unit temp1 = af;
		Unit temp2 = nv;
		Unit temp3 = am;
		
		// 형변환이 되더라도 상속받거나 재정의한(Override)
		// 자신들의 기본 특성은 그대로 유지함
		temp1.attack();
		temp2.attack();
		temp3.attack();
		
		// 상위 클래스 형태로 형변환이 되면, 자신들의 독립 기능은 사용하지 못함
		//temp1.bombing();
		//temp2.nucleus();
		//temp3.tank();
		
		System.out.println("--------------------");
		
		// 다시 원래의 기능을 되돌리기 위해서는 하위 클래스 형태로 명시적 형변환이 필요		
		AirForce re1 = (AirForce)temp1;
		Navy re2 = (Navy)temp2;
		Army re3 = (Army)temp3;
		
		re1.bombing();
		re2.nucleus();
		re3.tank();
	}

}

	



다음 다이브에서 또 만나요 🌊




출처
https://media.giphy.com/media/l2Je1bFuOpkNpyqYM/giphy.gif
https://media.giphy.com/media/Jbb3KS22397YQ/giphy.gif

0개의 댓글