언어/Java

상속

O_oz 2023. 8. 24. 13:09
반응형

1. 상속 : 부모 클래스를 자식 클래스에 물려주어 자식 클래스가 부모 클래스를 쉽게 사용할 수 있도록 함

    - 부모 클래스에서 private 접근 제한을 갖는 필드와 메소드는 상속 대상에서 제외

    - 부모와 자식 클래스가 서로 다른 패키지에 존재한다면 default 접근 제한을 갖는 필드와 메소드도 상속 대상에서 제외

    - 장점 : 코드의 중복을 줄여줌 / 클래스 수정을 최소화 할 수있음

 

2. 클래스 상속

    - 자식 클래스를 선언할 때 어떤 부모 클래스를 상속받을 것인지 결정하고 선택된 부모 클래스를 extends 뒤에 기술

class 자식클래스 extends 부모클래스 {
	// 필드
    // 생성자
    // 메소드
}

    - 다중 상속 불가능 : 한번에 여러 개의 부모 클래스를 상속할 수 없음

public class CellPhone {
    // 필드
    String model;
    String color;
    
    // 생성자
    
    // 메소드
    void powerOn() {System.out.println("전원을 켭니다.");}
    void powerOff() {System.out.println("전원을 끕니다.");}
    void bell() {System.out.println("벨이 울립니다.");}
    void sendVoice(String message) {System.out.println("본인 : " + message);}
    void receiveVoice(String message) {System.out.println("상대방 : " + message);}
    void hangUp() {System.out.println("전화를 끊습니다");}
}
public class DmbCellPhone extends CellPhone {
    // 필드
    int channel;
    
    // 생성자
    DmbCellPhone(String model, String color, int channel) {
        this.model = model;
        this.color = color;
        this channel = channel;
    }
    
    // 메소드
    void turnOnDmb() {
        System.out.println("채널 " + channel + "번 DMB 방송 수신을 시작합니다.");
    }
    void changeChannelDmb(int channel) {
        this.channel = channel;
        System.out.println("채널 " + channell + "번으로 바꿉니다.");
    }
    void turnOffDmb() {
        System.out.println("DMB 방송 수신을 멈춥니다.");
    }
}
public class Example {
    public static void main(String[] args) {
        // DmbCellPhone 객체 생성
        DmbCellPhone dmbCellPhone = new DmbCellPhone("자바폰", "검정", 10);
        
        // CellPhone으로부터 상속받은 필드
        System.out.println("모델 : " + dmbCellPhone.model);	// 모델 : 자바폰
        System.out.println("색상 : " + dmbCellPhone.color);	// 색상 : 검정
        
        // DmbCellPhone의 필드
        System.out.println("채널 : " + dbmCellPhone.channel);	// 채널 : 10
        
        // CellPhone으로부터 상속받은 메소드 호출
        dmbCellPhone.powerOn();			// 전원을 켭니다.
        dmbCellPhone.bell();			// 벨이 울립니다.
        dmbCellPhone.sendVoice("여보세요");	// 본인 : 여보세요
        dmbCellPhone.receiveVoice("안녕하세요");	// 상대방 : 안녕하세요
        dmbCellPhone.hangUp();			// 전화를 끊습니다.
        
        // DmbCellPhone의 메소드 호출
        dmbCellPhone.turnOnDmb();		// 채널 10번 dMB 방송 수신을 시작합니다.
        dmbCellPhone.changeChannelDmb(12);	// 채널 12번으로 바꿉니다.
        dmbCellPhone.turnOffDmb();		// DMB 방송 수신을 멈춥니다.
    }
}

 

3. 부모 생성자 호출

    - 자식 객체를 생성하면, 부모 객체가 먼저 생성되고 자식 객체가 그 다음에 생성됨

    - super(); : 부모 객체를 생성하기 위한 부모 생성자 / 자식 생성자의 맨 첫줄에서 호출됨

    - 자식 생성자나 부모 생성자가 생략되었다면 각각 기본 생성자가 생성됨

    - super(매개값, ...)는 매개값의 타입과 일치하는 부모 생성자를 호출하는데, 부모 클래스에 기본 생성자가 없고 매개 변수가 필요한 생성자만 존재한다면 자식 생성자에서 반드시 super(매개값, ...)를 명시적으로 호출해야 함

public class People {
    public String name;
    public String ssn;
    
    public People(String name, String ssn) {
        this.name = name;
        this.ssn = ssn;
    }
}
public class Student extends People {
    public int studentNo;
    
    public Student(String name, String ssn, int studentNo) {
        super(name, ssn);	// 주석 처리하면 컴파일 오류 발생
        this.studentNo = studentNo;
    }
}

    - 5라인을 주석 처리하면 부모의 기본 생성자가 없어서 다른 생성자를 명시적으로 호출하라는 오류 발생

public class Example {
    public static void main(String[] args) {
        Student student = new Student("홍길동", "123456-1234567", 1);
        System.out.println("이름 : " + student.name);	// 상속 필드 출력
        System.out.println("주민 번호 : " + student.ssn);	// 상속 필드 출력
        System.out.println("학생 번호 : " + student.studentNo);
    }
}

 

4. final 클래스와 final 메소드 (final 필드 설명 글)

    - final 키워드는 클래스, 필드, 메소드 선언 시에 사용할 수 있는데, 사용하면 해당 선언이 최종 상태이고, 이후 수정 될 수 없음을 의미함

    - 클래스와 메소드 선언 시에 사용되는 final 키워드는 상속과 관련됨

상속할 수 없는 final 클래스

    - final 클래스는 부모 클래스가 될 수 없어 자식 클래스를 만들 수 없음

public final class 클래스 { ... }

 

오버라이딩 할 수 없는 final 메소드

    - final 메소드는 최종적인 메소드이므로 오버라이딩 할 수 없음

public final 리턴타입 메소드([매개변수, ...]) { ... }

 

5. protected 접근 제한자

    - protected 접근 제한자는 필드, 생성자, 메소드에 사용할 수 있는 접근 제한자로 같은 패키지에서는 default 접근 제한자와 기능이 같지만, 다른 패키지에서는 자식 클래스만 접근을 허용함

    - 다른 패키지의 자식 클래스에서 호출할 때, new 연산자를 사용해서 생성자를 직접 호출할 수는 없고 자식 생성자에서 super()로 부모 생성자를 호출할 수 있음

package com.mycompany.package1;

public class A {
    protected String field;
    
    protected A() {}
    
    protected void method() {}
}
package com.mycompany.package2;
import com.mycompany.package2.A;

public class B extends A {
    public B() {
        super();
        this.field = "value";
        this.method();
    }
}
반응형

'언어 > Java' 카테고리의 다른 글

클래스의 타입 변환과 다형성  (0) 2023.08.27
메소드 재정의 (오버라이딩)  (0) 2023.08.24
어노테이션  (0) 2023.08.24
Getter와 Setter  (0) 2023.08.23
접근 제한자  (0) 2023.08.23