본문 바로가기
JAVA/JAVA

[JAVA] 02. 상속

by ssunooo 2024. 7. 4.

 

상속

 

상속이란 부모 클래스(상위 클래스)의 코드를 
자식 클래스(하위 클래스)가 전부 '재사용' 할 수 있는 행위이다.

 

자식 클래스의 모든 '생성자'들은 가장 먼저 부모클래스의 기본 '생성자'를 호출한다.

클래스를 상속받으면
해당 클래스의 코드를 전부 재사용할수있다.

 

 

상속에 대한 설명의 예

 

 

 

 

위 예시와 같이 class Point는 상위 클래스이고

class ColorPoint는 하위 클래스로

상위class에 있는 멤버변수는

하위class로 상속 되므로 

Point 클래스의 멤버변수인 int x, int y 는 Color Point 에 입력되있지 않더라도 포함된다.

 

이렇게 상속을 사용하는 이유는

코드를 잘게 잘게 잘라서(모듈화, 컴포넌트화, 함수화)

코드 재사용성을 증가시키고

오류 발견시 수정을 적게 가져가서 오류의 파급효과를 절감 시키기 위함이다.

 

그로인해 결과를 다양하게 추출하고, 개발시간을 단축시키고, 개발비용이 줄어들어

"유지보수 용이성 극대화" 라는 개발자의 최상위 목표에 알맞다.

 

"먼저 작성된 코드를 나중에 작성되는 코드때문에 변경한다?"는
대부분 잘못된 해결방식이다.
기본 생성자를 사용하지않는 이유는
기본 생성자를 만들어버리면 강제성을 잃게되기 때문이다.

 

다음은 상속을 이용한 예시이다.

 

모양 Shape
    String name 이름
    double area 넓이
    String color 색
    void draw()
        ㅁㅁ모양은 ㅁㅁ.ㅁㅁ만큼의 넓이

 

원 Circle
    int radius 반지름
    double PI 3.14 원주율

 

사각형 Rectangle
    int x,y 가로,세로

요구사항
1. 이름이 없는 모양 객체는 없음
2. 어떤 모양의 색을 별도로 지정하지않으면 기본 색은 검정
3. 원의 경우, 반지름을 별도로 지정하지않으면 기본 1
4. new 사각형(10) == 정사각형
5. new 사각형(10,20) == 직사각형

 

class Shape {
     String name;
     double area;
     String color;
     Shape (String name) {
          this(name,"검정");
     }
     Shape(String name,String color) {
          this.name=name;
          this.color=color;
          this.area=0.0;
     }
     void draw() {
          System.out.println(this.color+"ㅁㅁ색 "+this.name+" 모양 넓이 : "+this.area);
     }
     void setArea() {
          System.out.println("Shape에서 호출한 setArea()");
     }
}
class Circle extends Shape {
     int radius;
     static final double PI=3.14; // final == 상수화, static == 클래스 변수화 => 바로 초기화
     Circle() {
          this(1,"검정");
     }
     Circle(String color) {
          this(1,color);
     }
     Circle(int radius) { // 이 생성자를 사용한 사용자의 마음
          this(radius,"검정");
     }
     Circle(int radius,String color) {
          super("원",color);
          this.radius=radius;
          // this.setArea();
     }
     void setArea() {
          // 넓이를 설정하는 메서드
         System.out.println("Circle에서 호출한 setArea()");
          this.area=this.radius* this.radius*Circle.PI;
     }

}
class Rectangle extends Shape {
     int x;
     int y;
     Rectangle(int x) {
          this(x,"검정");
     }
     Rectangle(int x,String color) {
          super("정사각형",color);
          this.x=x;
          this.y=x;
          // this.setArea();
     }
     Rectangle(int x,int y) {
          this(x,y,"검정");
     }
     Rectangle(int x,int y,String color) {
          super("직사각형",color);
          this.x=x;
          this.y=y;

          // this.setArea();
     }
     // 오버라이딩 : 메서드 재정의
     // 오버로딩 : 함수명 중복정의 허용
     @Override // @ 어노테이션, 애너테이션
     void setArea() {
          System.out.println("Rectangle에서 호출한 setArea()");
          this.area=this.x*this.y;
     }
}


public class Test01 {

     public static void main(String[] args) {
          Shape s=new Shape("모양");
          s.setArea();

          Circle c=new Circle(1);
          c.setArea();

          Rectangle r=new Rectangle(2);
          r.setArea();

          // 객체지향의 핵심
          // 같은 메서드를 수행시켜도
          // 다른 주체자가 수행했다면
          // 다른 결과가 나온다.

     }

}

 

 

위 예시에 오버라이딩, @Override 한 곳을 보면

void setArea() 메서드를 부모에게서 가져다썼지만

다른 출력이 나오게 된다.

 

 

console)

Shape에서 호출한 setArea()
Circle에서 호출한 setArea()
Rectangle에서 호출한 setArea()

 


오버라이딩은 메서드 재정의 라고도 부르며

상속관계에서만 발생하고,

메서드명이 동일할 때, 기능이 같을 때

코드가 다른 상황일 경우 사용한다.

 

마우스 우클릭후 source > Override.... 를 클릭하면 현재 사용되는 메서드를 선택해

Override를 편하게 코드에 칠 수 있다.

 

오버라이드를 하게되면 메서드 안에
// TODO Auto-generated method stub
return super.

의 문구가 있는데

이 뜻은 "너가 아무행동도 하지 않으면 부모의 것을 그대로 가져다 쓸거야!!" 라는 뜻으로 해석한다.

 

 

2024.07.04