[JAVA] 05. 상속 (Inheritance)

gogori6565·2022년 10월 5일
0

JAVA

목록 보기
9/11

📌 상속 (inheritance)

부모 클래스에 만들어진 필드, 메소드를 자식클래스가 물려받음. 동일 특성을 재정의할 필요 없어 자식 클래스 간결해짐.

  • 상속의 장점
    1) 클래스 간결화
    2) 클래스 관리 용이 - 계층적 분류
    3) 소프트웨어 생산성 향상 - 클래스 재사용-확장 용이, 새 클래스 작성 빠름

자바의 상속 선언 - extends

public class Person{
}

public class Student extends Person { //Person을 상속받는 클래스 Student
}

public class StudentWorker extends Student{ //Student를 상속받는 StudentWorker
}

extends 키워드 사용 ★

자바 상속의 특징

  1. 클래스의 다중 상속 지원 X
    -> 다중 상속? 부모가 2개 이상
  2. 상속 횟수 무제한
  3. 상속 최상위 조상 클래스는 java.lang.Object 클래스

상속과 접근 지정자

  1. 슈퍼 클래스의 public : 모든 클래스 접근 허용
  2. 슈퍼 클래스의 디폴트 : 패키지 내 모든 클래스에 접근 허용
  3. 슈퍼 클래스의 protect : 같은 패키지 내 모든 클래스 접근 허용, 다른 패키지에 있어도 서브 클래스는 슈퍼 클래스의 protected 멤버 접근 가능
  4. 슈퍼 클래스의 private : 다른 모든 클래스에 접근 불허, 클래스 내 멤버들에게만 허용


📌 서브 클래스 / 슈퍼 클래스

생성자 호출 및 실행

Q. 서브 클래스 객체가 생성될 때, 서브와 슈퍼 클래스의 생성자가 모두 실행되는가?
A. Yes. 둘 다 실행됨. 서브 클래스 객체 생성 시 이 객체에 서브 클래스 멤버와 슈퍼 클래스 멤버가 모두 들어있다.

Q. 서브 클래스의 생성자와 슈퍼 클래스의 생성자 중 누가 먼저 실행되는가?
A. 슈퍼 클래스 -> 서브 클래스 순서로 실행된다.
호출 순서 : 서브 클래스의 생성자가 먼저 호출 -> 서브 클래스의 생성자가 실행 전 슈퍼 클래스 생성자 호출 -> 슈퍼 클래스 생성자 실행 -> 서브 클래스 생성자 실행

서브 클래스에서 슈퍼 클래스의 생성자 선택

  • 서브 클래스 생성자 작성 원칙
    서브 클래스 생성자에서 슈퍼 클래스 생성자 하나 선택
  • 서브 클래스에서 슈퍼 클래스의 생성자를 선택하지 않는 경우
    컴파일러가 자동으로 슈퍼 클래스의 기본 생성자 선택 (이 경우, 기본 생성자가 없다면 오류 발생)
  • 서브 클래스에서 슈퍼 클래스의 생성자를 선택하는 방법
    super() 이용

super() - 명시적으로 슈퍼 클래스 생성자 선택

  • 인자를 이용해 슈퍼 클래스의 생성자 호출
  • 반드시 서브 클래스 생성자 코드의 제일 첫 라인에 와야함

업캐스팅 (upcasting)

: 서브 클래스 객체를 슈퍼 클래스 타입으로 타입 변환

class Person {}
class Student extends Person {}

Student s = new Student();
Person p = s; // 업캐스팅, 자동타입변환
  • 업캐스팅된 레퍼런스
    : 객체 내에 슈퍼 클래스의 멤버만 접근 가능

설명))
그냥 슈퍼클래스를 쓴다는 게 아니라

Person p;
Student s = new Student("이재문");
p=s; //업캐스팅

이게 레퍼런스 p가 Student 객체의 멤버 중에서 그 슈퍼클래스인 Person의 멤버만 접근한다는 의미!!
"Student 객체 멤버 중 슈퍼클래스 멤버만 접근"이란 의미가 중요

다운캐스팅 (downcasting)

: 슈퍼 클래스 객체를 서브 클래스 타입으로 변환. 개발자의 명시적 타입 변환 필요.

class Person {...}
class Student extends Person {...}
...
Person p = new Student("이재문"); //업캐스팅
...
Student s = (Student)p; //다운캐스팅, (Student)의 타입 변환 표시 필요

instanceof 연산자와 객체의 타입 변환

업캐스팅된 레퍼런스로 객체의 타입을 판단하기가 어려움 -> 슈퍼 클래스는 여러 서브 클래스에 상속되기 때문

instanceof 연산자
레퍼런스가 가리키는 객체의 타입 식별을 위해 사용

객체레퍼런스 instanceof 클래스타입

연산 결과 : true/false의 불린 값


메소드 오버라이딩 (Method Overriding)

슈퍼 클래스의 메소드를 서브 클래스에서 재정의 (슈퍼 클래스의 메소드 이름, 매개변수 타입과 개수, 리턴 타입 등 모든 것을 동일하게 작성)

<동적 바인딩 발생!>
서브 클래스에 오버라이딩된 메소드가 무조건 실행되는 동적바인딩 (슈퍼 클래스 메소드가 무시, 덮어쓰기로 번역되기도 함)

  • 업캐스팅된 변수도 슈퍼가 아닌 서브 클래스의 오버라이딩 메소드를 실행한다

오버라이딩의 목적 - 다형성 실현

오버라이딩 : 슈퍼 클래스에 선언된 메소드를 각 서브 클래스들이 자신만의 내용으로 새로 구현

  • 상속을 통해 '하나의 인터페이스(같은 이름)에 서로 다른 내용 구현'이라는 객체 지향의 다형성 실현

super 키워드

super : 슈퍼 클래스의 멤버를 접근할 때 사용되는 레퍼런스

  • 슈퍼 클래스의 메소드를 호출
  • 컴파일러는 super의 접근을 정적 바인딩으로 처리
    정적바인딩 : 컴파일 시간에 성격이 결정
    동적바인딩 : 실행 시간(run time)에 성격이 결정

오버로딩 vs 오버라이딩


추상 메소드 (abstract method)

: 선언되어 있으나 구현되지 않은 메소드, abstract로 선언됨

public abstract String getName();
pubilc abstract void setName(String s);

추상 메소드는 서브 클래스에서 오버라이딩하여 구현해야함

추상 클래스(abstract class)의 2종류

  1. 추상 메소드를 하나라도 가진 클래스 (클래스 앞에 반드시 abstract라고 선언해야함)
  2. 추상 메소드가 하나도 없지만 abstract로 선언된 클래스
//1. 추상 메소드 하나 이상 가진 클래스

abstract class Shape { // 추상 클래스 선언
	public Shape() { }
	public void paint() { draw(); }
	abstract public void draw(); // 추상 메소드
}
//2. 추상 메소드가 없는 클래스

abstract class MyComponent { // 추상 클래스 선언
	String name;
	public void load(String name) {
		this.name = name;
	}
}

★ 추상 클래스는 객체를 생성할 수 없다!★

추상 클래스의 상속

추상 클래스 상속의 2가지 경우

  1. 추상 클래스의 단순 상속 - 서브 클래스도 추상 클래스
    -> 추상 클래스 상속받고 추상 메소드는 구현하지 않은 경우, 서브 클래스도 abstract로 선언해야함

  2. 추상 클래스 구현 상속 - 서브 클래스는 추상 클래스 X
    -> 서브 클래스에서 슈퍼 클래스의 추상 메소드 구현 (오버라이딩), 서브 클래스는 추상 클래스가 아님

추상 클래스의 용도

  1. 설계와 구현 분리
    -> 슈퍼 클래스에서는 개념을 정의하고, 서브 클래스마다 다른 구현이 필요한 메소드는 추상 메소드로 선언
    -> 각 서브 클래스에서 구체적인 행위 구현, 서브 클래스마다 목적에 맞게 서로 다른 추상 메소드를 구현

자바의 인터페이스

클래스가 구현해야 할 메소드들이 선언되는 추상형
interface 키워드로 선언함

public interface SerialDriver {...}
  • 인터페이스의 객체 생성 불가 X
  • 인터페이스 타입의 레퍼런스 변수는 선언 가능 O
  • 인터페이스 구현
    인터페이스를 상속받는 클래스는 인터페이스의 모든 추상 메소드를 반드시 구현해야함
  • 인터페이스 상속 및 다중 상속 가능

인터페이스 구현

인터페이스의 추상 메소드를 모두 구현한 클래스 작성

  • implements 키워드 사용
class SamsungPhone implements PhoneInterface { // 인터페이스 구현
	// PhoneInterface의 모든 메소드 구현
	public void sendCall() { System.out.println("띠리리리링"); }
	public void receiveCall() { System.out.println("전화가 왔습니다."); }
    
	// 메소드 추가 작성
	public void flash() { System.out.println("전화기에 불이 켜졌습니다."); }
}

인터페이스 목적

=> 인터페이스는 스펙을 주어 클래스들이 그 기능을 서로 다르게 구현할 수 있도록 하는 클래스의 규격 선언이며, 클래스의 다형성을 실현하는 도구이다.

profile
p(´∇`)q

0개의 댓글