[객체지향][상속]

포키·2022년 10월 24일
0

국비과정

목록 보기
22/73

모델링 할 때 '특징 정리하기' 단계 빼먹지 말기
만들기 전, 만들 대상의 정보를 정리하는 작업은 중요하다 특히 우리같은 초보자에게


상속

  • '계층구조, 상하개념'이란 (나: 계층구조의 목적보다는 계층구조의 특징?)

계층구조에서 하위 계층은 상위 계층의 특징을 당연히 가지고 있음
즉 하위 계층이 상위 계층에서 언급된 특징까지 설명할 필요 없음
상속 관계는 클래스 사이의 계층구조를 형성한다

상속이란

  • 정의
    '기존에 존재하는 클래스로부터 필드와 메서드를 이어받고, 필요한 기능은 추가할 수 있는 기법'
    '검증된 소프트웨어를 재사용할 수 있어서 신뢰성 있는 소프트웨어를 손쉽게 개발, 유지 보수할 수 있게 해주는 중요한 기술'
  • ‘클래스 간 중복 제거’
class ElectricCar extends Car{
	int batteryLevel;
}
// 'class A extends B' 형태
// 전기차 클래스는 차 클래스를 확장한다. -> 전기차 클래스는 차 클래스를 상속받아온다.

  • 상속의 조건
    ① +a가 존재 (추가정보-멤버변수, 메서드, 생성자 등의-가 존재)
    ② is-a 관계 성립 (하위 개념이면 상위 개념이 충족됨-B가 A를 상속해온다면 ‘B is a A’)
    ex) 가수 클래스를 상속해오는 아이유, 에일리 클래스
    -> 아이유 is a Singer, 에일리 is a Singer
    둘 다 만족될 때만 상속을 사용할 수 있음
    (그런 경우마다 반드시 사용해야 하는 것은 아님!)

  • 프로그램에서 상속을 '해준다'는 말은 없다. 상속은 '받는(받아오는)‘ 것이다.
    : 'A <- B (B가 A를 상속받음)' 관계에서 B는 A를 인지하지만, A도 B를 인지하는 것은 아니다.
    상속은 A가 하는 게 아니라 B가 받아오는 것이다.

모든 객체지향 언어에는 상속 개념이 존재함
언어마다 상속의 정의가 조금씩 다름

상속 남발의 주의점
‘태권v 클래스 <- 사람 클래스’의 상속관계를 만든다면, 사람 객체에 '주먹 발사'가 들어갈 수 있다!
(is-a 관계가 성립하지 않기 때문 - ‘사람 is NOT a 태권v’)
단순히 코드 재활용을 위해 마구잡이로 상속을 사용하면, 사람이 주먹을 발사하게 된다😅

상속 또한 중복을 줄이는 방법 중 하나
지금까지 배운 중복 줄이기 방법은 '클래스 안'에 한정되었으나,
이젠 상속을 통해 클래스 사이에 존재하는 중복도 제거할 수 있다.
(물론 상속 말고 다른 방법도 있다. - 아직 안배움)

  • 상속을 잘 이용하기 위해선
  1. 하위 클래스들의 특징을 먼저 생각해보고
  2. 그 후 그들의 공통점을 찾아 정리해서 상위 클래스를 만든다.
  3. 만들어진 상위 클래스의 이름을 정의하는 것도 중요한 부분이다.
  • 상속의 목적
  1. 존재하는 것의 개량 (확장) - 존재하는 상위개념을 확장하여 하위개념으로 발전
    ex) 우리가 봐온 api 클래스들, library 클래스 등 (Scanner 등)
    ex) Car <- ElectricCar
  2. 존재하지 않는 상위개념을 생성 (상위개념 생성) - 하위개념을 정리하며 존재하지 않는 상위개념을 발명
    ex) Car, Truck, Bus -> Vihicle을 만드는 식
  • 상속을 사용하는 이유
    현실에서 계층구조 사용하는 이유와 같다?

  • 상속의 방향
    상속은 '단방향 행위'다
    무슨 말이냐?
    A를 상속받아 사용하는 B가 있어도, A는 B를 인지하지 않기 때문에, B를 고려하지 않고 A를 변경할 수 있다
    => A를 상속받는 B에게 치명적 오류가 생길 수 있다
    심지어 A를 상속받는 B를 상속받는 C를 상속받는 D가 있다면? 고려하기 어렵고, 자칫 의도하지 않은 심각한 문제가 생길 가능성이 높아지는 것.

상속, 사용할 때 주의해야 하는 이유
상속은 기본적으로 의존성이 굉장히 높은 기술 (A가 있어야 B가 존재할 수 있다는 높은 의존성)
프로그래밍에서 의존성은 지양해야 하는 특성이며 의존성이 높으면 위험성이 높다.

  • 다중상속을 지원하지 않는다
    부모 클래스는 하나만 존재한다. (상속받아오는 클래스는 1개)
    다중상속은 상위 클래스간 개념의 충돌로 문제가 생길 수 있음 -> 최근으로 올수록 더 많은 언어에서 금지함

  • 상속 횟수에는 제한이 없다.

  • 상속 계층 구조의 최상위에는 java.lang.Object 클래스가 있다.
    (모든 것은 결국 객체다. 모든 객체는 결국 Object 클래스의 자식이다.)
    (그러므로 모든 객체에는 toString이 존재함 - java.lang.Object가 소유하는 toString을 상속받아오는 것.)

상속관계는 생각하기 나름
①컴퓨터, ②랩탑, ③데스크탑, ④태블릿의 관계도

상속과 접근지정자

  • 부모 클래스의 private 멤버는 상속되지 않는다.
  • 상속 관계와 관계없이 package는 사용하는 패키지가 같은 경우에만 쓸 수 있다.
  • protected는 자식 클래스거나 패키지가 같으면 사용 가능하다.
    접근지정자 허용범위 : private < package(생략) < protected < public
    (자기 자신만 돼 < 패키지 같으면 돼 < 상속 관계면 돼 < 전부 돼)
    하위범주는 상위범주의 허용범위를 포함한다. (범위 확장 개념)
  • 재귀호출
    메소드 안에 자기 자신을 부르는 부분이 있음 (일반적으로 반복문 형태가 됨)
public void attack(Zealot target) {
	...
    target.attack(this);
    ...
}

만들기도 이해하기도 어렵지만, 일반 반복문보다 속도가 빠르다

상속과 생성자

class Parent {
	private int age;
	public Parent(int age) {
    	this.age = age;
		System.out.println("Parent");
	}
    public int getAge() {
    	return age;
    }
    public void setAge(int age) {
    	this.age = age;
    }
}
class Child extends Parent {
	public Child(int age) {
    	super(age);						// 작성하지 않아도 알아서 추가되는 super() : 부모클래스 생성자
        System.out.println("Child");
    }
    public void printAge() {
    	System.out.println(getAge());
    }
}
class Ex1 {
	public static void main(String[] args) {
    	Child c = new Child(30);
        c.setAge(15);
        c.printAge();
    }
}
  • super() : 부모 클래스의 생성자를 호출
    this()와 마찬가지로 생성자의 첫 명령으로 들어가야 한다.

  • this()보다 super()를 많이 사용하는 이유

  1. 대체 가능한 방법의 유무 (this()는 메소드
  2. 상위 클래스의 생성자를 추가·변경하기 어려운 경우 (타인이 짠 코드 등)

  • 자녀 클래스의 객체가 생성되면 부모 클래스의 객체도 함께 생성되어 연결된다.
  • 데이터를 찾는 순서는 자녀클래스 객체 -> 부모클래스 객체 -> ... -> Object 객체

  • 부모클래스 객체 또한 자녀클래스 객체와 마찬가지로 개별 생성된다.
    각자 다른 한 덩어리임을 명심하자.
profile
welcome

0개의 댓글