Programming Language/Java

상속(Inherit) - 상속, 오버라이딩(Overriding), 예약어

Ma_Sand 2022. 3. 4. 13:48
반응형

1. 상속(Inherit)

  : 매 클래스마다 중복된 필드와 메소드를 하나의 클래스(부모 클래스)로 모아서 정의한 후 상속을 받아

    자식 클래스가 자신의 필드와 메소드처럼 사용하는 개념

 

 (1) 목적

    : 클래스를 재사용하기 위해, 연관된 클래스들에 대해 공통적인 규약을 정의하기 위해

 

 

 (2) 특징

   ① 클래스 간에 다중 상속은 불가하고, 단일 상속만 가능하다.

     ⓐ 단일 상속: Java에서는 하나의 부모클래스에게만 상속받을 수 있다.(여러 부모클래스에게 상속받을 수 없다.)

 

   ② 모든 클래스는 Object 클래스의 후손이다.

     ⓐ 모든 클래스에는 이미 만들어진 클래스와 새로 만들 클래스들이 모두 포함되어 있다.

     ⓑ Object 클래스에 있는 메소드들을 사용할 수 있다.

     ⓒ Object 클래스에서 상속 받은 메소드를 오버라이딩(Overriding)으로 재정의하여 사용할 수 있다.

       - 실행하고자 하는 메소드가 자식 클래스에 존재하지 않으면 자동으로 해당 클래스의 부모 클래스에 있는

         메소드로 호출된다. 

       - 단, 자식 클래스에 오버라이딩한 메소드가 있으면 그 메소드가 호출된다. → 오버라이딩한 메소드가 우선권을

         가진다.

 

 

 (3) 표현법

접근제한자 class 클래스명 extends 클래스명 {}

public class Apple extends Fruit {}

// 자식클래스 extends 부모클래스

 

 

 (4) super()와 super.

   ① super()

     : 부모 객체의 생성자를 호출하는 메소드(자식 생성자에 부모 생성자가 포함된다.)

     ⓐ 자식 클래스의 생성자 안에 부모 생성자를 호출하는 'super()'가 "첫 번째 줄"에 와야 한다.(부모 생성자가 제일

         먼저 실행되어야 하기 때문이다.)

     ⓑ 매개변수가 있는 부모 생성자를 호출할 땐 'super(매개변수)'로 작성하면 된다.

 

   ② super.

     : 자식 클래스에서 정의할 때에 부모 객체를 가리키는 참조변수

     ⓐ 자식 클래스 내에서 부모 클래스의 필드나 메소드를 호출할 때 사용한다.

 

부모 클래스 Product
// 필드
public class Product {  // 부모 클래스를 조상 클래스 또는 super 클래스라고도 부른다.
    private String brand;
    private String name;    // 자손 클래스 간의 공통된 변수들을 부모 클래스로 한번에 정의
    private int price;
    
// 생성자
    public Product() {  // 기본 생성자
    
    }
    public Product(String brand, String name, int price) {
        super();  // 이 super();는 생략 가능.
        this.brand = brand;
        this.name = name;
        this.price = price;
    }

// 메소드
    // 각 매개변수들 setter/getter 메소드 생성
    중간 과정 생략;
    
    public String information() {
        return brand + " " + name + " " + price;
    }
}


자식 클래스 Phone
// 필드
public class Phone extends Product {
    private String Agency;  // 공통된 변수를 제외한 자식 클래스의 고유한 변수
    
// 생성자
    public Phone() {  //  기본 생성자
    
    }
    public Phone(String brand, String name, int price, String agency) {
        super(brand, name, price, agency);  // 부모 생성자를 호출하여 super()로 한번에 초기화
        this.agency = agency;  // 같은 클래스 내에 있는 메소드 호출(this.)
    }
    
// 메소드
    // 매개변수 agency setter/getter 메소드 생성
    중간 과정 생략;
    
    @Override
    public String information() {
        return super.information() + " " + agnecy;
        // 자식 클래스에서 정의할 때 부모 객체를 가리키는 참조변수 super.를 사용하여
        // 부모 메소드 information()을 자식 클래스로 호출
    }
}

 

 

 (5) 장점

   ① 적은 양의 코드로 새로운 클래스를 작성할 수 있다.

   ② 부모 클래스에서 코드를 공통으로 관리하므로 코드를 추가하고 변경하는 데에 용이하다.

   ③ 중복된 코드를 제거하기 때문에 프로그램의 생산성과 유지보수에 좋다.

 

 

 

2. 오버라이딩(Overriding)

 (1) 의미

    : 자식 클래스가 상속 받은 부모 클래스를 재정의하는 것(부모 클래스가 상속하는 메소드를 다르게 고쳐서

      사용하겠다는 뜻으로, 이때는 오버라이딩한 자식 클래스의 메소드가 우선권을 가진다.)

 

 

 (2) 특징

   ① 오버라이딩한 메소드 윗줄에 반드시 Annotation, '@Override'를 표시해야 한다.

   ② 접근제어자를 부모 클래스와 같거나 부모 클래스보다 넓은 범위로 변경할 수 있다.

   ③ 부모 메소드의 예외 처리 클래스 처리 범위보다 좁은 범위로 예외 처리 클래스를 수정할 수 있다.

 

 

 (3) 성립 조건

   ① 부모 클래스의 메소드명과 자식 클래스의 메소드명이 동일해야 한다.

   ② 서로 매개변수의 타입과 개수가 동일해야 한다.

   ③ 리턴(return) 타입도 동일해야 한다.

   ④ 단, private 메소드는 오버라이딩할 수 없다.

 

 

 (4) 오버로딩(Overloading)과의 비교★★

구분 오버라이딩(Overriding) 오버로딩(Overloading)
위치 하위 클래스에서 메소드를 정의 같은 클래스 내에서 메소드를 정의
성립 조건 메소드명과 매개변수의 타입, 개수, 순서가 동일해야 하며, 리턴(return) 타입도 동일해야 함 메소드명이 동일해야 하고, 매개변수의 타입과 개수, 순서는 달라야 함
리턴(return) 타입은 상관 없음
접근 범위 자식 메소드의 접근 범위가 부모 메소드보다 같거나 넓어야 함 접근제어자와 상관 없음
예외 처리 자식 메소드의 예외 처리 클래스 처리 범위가 부모 메소드보다 좁아야 함 예외처리와 상관 없음

 

[오버라이딩(Overriding)]
공통 메소드가 String brand(), String name(), int price()라고 하면
public class Product {  // 부모 클래스 Product

    중간 과정 생략;
    
    public String information() {
        return brand + " " + name + " " + price;
    }
}

public class Phone extends Product {  // 부모 클래스 Product에게 상속받은 자식 클래스 Phone
    
    중간 과정 생략;
    
    // 부모 클래스의 메소드에 "자신만의 메소드를 추가"하고 싶다면 "오버라이딩"을 한다.
    @Override  // 어노테이션은 꼭 적어주기!
    public String information() {
        return super.information() + " " + Agency;
        
        // 부모 메소드의 형태는 return 타입까지 똑같이 유지한다.
        // 그리고 부모 메소드를 호출하는 'super.부모메소드명()'을 사용하여 해당 값을 그대로 옮기고
        // 자신만의 메소드(Agency)를 추가하면 오버라이딩이 된 메소드가 된다.
        // 이렇게 오버라이딩 된 자식 메소드는 부모 메소드보다 우선권을 가지므로
        // 실행시키면 자식 메소드가 출력된다.
    }
}



[오버로딩(Overloading)]
public class Product {
    private String brand();
    private String name();
    private int price();
    
    public Product(String brand) {  // 자신 클래스명의 메소드
        this.brand = brand;  // 자기 클래스 내에서 메소드를 가져다 쓰므로 this.를 사용
    }
    public Product(String brand, String name) {  // 매개변수의 개수가 다름
        this.brand = brand;
        this.name = name;
    }
    public Product(String name, String brand) {  // 매개변수의 순서가 다름
        this.name = name;
        this.brand = brand;
    }
    public Product(String brand, String name, int price) {  // 매개변수의 개수가 다름
        this.brand = brand;
        this.name = name;
        this.price = price;
    }
}

 

 

 

3. 예약어

 (1) final 예약어

   ① final 클래스: 상속이 불가능한 클래스

public final class Name {}

 

   ② final 메소드: 상속 시 오버라이딩이 불가한 메소드

public final void method() {}

 

 

 (2) 대상별로 사용할 수 있는 접근제어자, 예약어

대상 사용할 수 있는 접근제어자 / 예약어
클래스 public, (default), final, abstract
메소드 모든 접근제어자, final, abstract, static
변수 모든 접근제어자, final, static
지역변수 final
반응형