[자바의 정석]chapter7 객체지향 프로그래밍2/ 2.오버라이딩

임대진·2022년 2월 27일
0
post-custom-banner

2. 오버라이딩(overriding)

2.1 오버라이딩이란?

  • 조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것
    class Point{
         int x;
         int y;
         
        ** String getLocation(){
                return "x :" + x + ", y :"+y;**
         }
    }
    class Point3D extends Point {
         int z; 
    String getLocation(){
                return "x :" +x+ ", y:"+y ", z:" + z;**
                }
    }
  • 이 두클래스는 서로 상속관계에 있으므로 Point3D클래스는 Point클래스로부터
    getLocation()을 상속받지만 Point3D클래스는 3차원 좌표계의 한 점을 표현하기 위한
    것이므로 조상인 Point클래스로부터 상속받은 getLocation()은 Point3D클래스에 맞지 않는다.
    그래서 이 메서드를 Point3D클래스 자신에 맞게 z축의 좌표값도 포함하여 반환하도록 오버라이딩 하였다.

2.2 오버라이딩의 조건

  1. 메서드의 선언부는 조상의 것과 완전히 일치해야 한다.(선언부)

    자손 클래스에서 오버라이딩하는 메서드는 조상 클래스의 메서드와

  • 이름이 같아야 한다.
  • 매개변수가 같아야 한다.
  • 반환타입이 같아야 한다.
  1. 접근 제어자는 조상 클래스의 메서드보다 좁은 범위로 변경 할 수 없다.
    만일 조상 클래스에 정의된 메서드의 접근 제어자가 protected라면,
    이를 오버라이딩하는 자손 클래스의 메서드는 접근 제어자가 protected나 public이어야 한다.
    대부분의 경우 같은 범위의 접근 제어자를 사용한다.
    접근제어자의 접근범위를 넓은 것에서 좁은 것 순으로 나열하면 public, protected,(default), private이다.
  2. 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.
class Parent {
      void parentMethod() throws IOException, SQLException{
      ...
      }
 }
 class Child extends Parent{
      void parentMethod() throws IOException{
      ...
      }
      ...
 }
class Child extends Parent{
     void parentMethod() throws Exception{
          ...
     }
     ...
}
  • Exception은 모든 예외의 최고 조상이므로 가장 많은 개수의 예외를 던질 수 있도록 선언
  • 예외의 개수는 적거나 같아야 한다는 만족시키지 못하는 잘못된 오버라이딩

2.3 오버로딩 vs. 오버라이딩

  • 오버로딩(overloading) 기존에 없는 새로운 메서드를 정의하는 것(new)
  • 오버라이딩(overriding) 상속받은 메서드의 내용을 변경하는 것(change, modify)
class Parent{
      void parentMethod(){}
}
class Child extends Parent {
     void parentMethod(){}   //오버라이딩
     void parentMethod(int i){}  //오버로딩
     
     void childMethod(){}
     void childMethod(int i){} //오버로딩
     void childMethod(){} //에러 중복정의 되었음 

2.4 super

  • super는 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조 변수
  • 조상 클래스의 멤버와 자손클래스의 멤버가 중복 정의되어 서로 구별해야하는 경우에만 super를 사용하는 것이 좋다.
  • 모든 인스턴스메서드에는 자신이 속한 인스턴스의 주소가 지역변수로 저장되는데, 이것이 참조변수인 this와 super의 값이 된다.
  • static메서드(클래스메서드)는 인스턴스와 관련이 없다. 그래서 this와 마찬가지로 super역시 static메서드에서는 사용할 수 없고 인스턴스메서드에서만 사용할 수 있다.
class SuperTest2{
  public static void main(String args[]){
      Child c = new Child();
      c.method();
  }
}
class Parent{
   int x=10;
}
class Child extends Parent{
   int x=20;
   
   void method(){
       System.out.println("x=" + x);
       System.out.println("this.x=" + this.x);
       System.out.println("super.x="+ super.x);
   }
}
  • 이처럼 조상 클래스에 선언된 멤버변수와 같은 이름의 멤버변수를 자손 클래스에서 중복해서 정의하는 것이 가능하며 참조변수 super를 이용해서 서로 구별할 수 있다.
  • 변수만이 아니라 메서드 역시 super를 써서 호출할 수 있다. 특히 조상 클래스의 메서드를 자손 클래스에서 오버라이딩한 경우에 super를 사용한다.
class Point{
     int x;
     int y;
     
     String getLocation(){
            return "x :" + x+", y:"+y;
            }
    }
    
    class Point3D extends Point{
          int z;
          String getLocation(){  //오버라이딩
           // return "x :" + x +", y:" +y+", z:" +z;
              return super.getLocation()+",z:"+z;//조상의 메서드 호출 
              
  • 조상클래스의 메서드의 내용에 추가적으로 작업을 덧붙이는 경우라면 이처럼 super를 사용해서 조상클래스의 메서드를 포함시키는 것이 좋다.
  • 후에 조상클래스의 메서드가 변경되더라도 변경된 내용이 자손클래스의 메서드에 자동적으로 반영될 것이기 때문이다.

2.5 super()-조상 클래스의 생성자

  • super()는 조상 클래스의 생성자를 호출하는데 사용된다.

    Object클래스를 제외한 모든 클래스의 생성자 첫 줄에 생성자,this() 또는 super(),를
    호출해야 한다. 그렇지 않으면 컴파일러가 자동적으로 'super();'를 생성자의 첫 줄에 삽입한다.

class PointTest{
   public static void main(String args[]){
       Point3D p3 = new Point3D(1,2,3);
       }
}
class Point{
      int x, y;
      Point(int x, int y){
          this.x = x;
          this.y = y;
      }
      String getLocation(){
           return "x :" + x + ", y :" + y;
     }
 }
 class Point3D extends Point{
      int z; 
      point3D(int x, int y, int z) {
        //생성자 첫 줄에서 다른 생성자를 호출하지 않기 때문에 컴파일러가 'super();'를 여기에 삽입한다. 
        //super()는 Point3D의 조상인 Point클래스의 기본 생성자인 Point()를 의미한다.
      this.x = x; // 조상의 멤버를 초기화
      this.y = y;  // 조상의 멤버를 초기화
      this.z = z;
    }
    String getLocation(){
        return "x :" + x + ", y :" + y + ", z :" +z;
    }
}
Point3D(int x, int y, int z) {
   super(x, y); //조상클래스의 생성자 Point(int x, int y)를 호출한다.
   this.z = z;
}
  • 조상 클래스의 멤버변수는 이처럼 조상의 생성자에 의해 초기화되도록 해야 하는 것이다.
profile
신입개발자 공부기록 블로그
post-custom-banner

0개의 댓글