[Java] 상속

thingzoo·2023년 6월 14일
0

Java

목록 보기
10/20
post-thumbnail

클래스간의 관계와 상속

상속

기존의 객체(부모객체)를 재사용해서 새로운 객체(자식객체)를 작성하는것

  • extends 키워드를 사용하여 정의
public class 자식클래스 extends 부모클래스 {

}

클래스 간의 관계

상속관계

is - a (”~은 ~(이)다”)

포함관계

has - a (”~은 ~을(를) 가지고 있다”)

단일 상속과 다중 상속

Java는 다중상속을 허용하지 않는다!

  • 왜냐하면 다중상속을 허용하면 클래스간의 관계가 복잡해지는 문제가 생기기 때문
  • 만약 자식 클래스에서 상속받는 서로 다른 부모 클래스들이 같은 이름의 멤버를 가지고 있다면??
  • 자식 클래스에서는 이 멤버를 구별할 수 있는 방법이 없다는 문제가 생김!

final 클래스와 final 메소드

final 클래스

최종적인 클래스로서 더 이상 상속할 수 없는 클래스

public final class Car {}
public class SportsCar extends Car{} // 오류가 발생합니다.

final 메소드

최종적인 메서드로서 더 이상 오버라이딩할 수 없는 메서드

public class Car {
    public final void horn() {
        System.out.println("빵빵");
    }
}
public class SportsCar extends Car{
    public void horn() { // 오류가 발생합니다.
        super.horn();
    }
}

Object 클래스

Java 내 모든 클래스들의 최상위 부모 클래스

  • 모든 클래스는 Object의 메서드 사용 가능
  • 부모 클래스가 없는 자식 클래스는 컴파일러에 의해 Object 클래스 자동 상속

🔎 Object 클래스의 메서드

  • Object clone() : 해당 객체의 복제본을 생성하여 반환
  • boolean equals(Object object) : 해당 객체와 전달받은 객체가 같은지 여부 반환
  • Class getClass() : 해당 객체의 클래스 타입 반환
  • int hashCode() : 자바에서 객체를 식별하는 정수값인 해시 코드 반환
  • String toString() : 해당 객체의 정보를 문자열 반환 & Object 클래스에서는 클래스이름 @해쉬코드값 반환

오버라이딩

부모 클래스로부터 상속받은 메서드의 내용을 재정의 하는 것

  • 부모 클래스의 메서드를 자식 클래스의 상황에 맞게 변경을 해야하는 경우 사용
  • 오버라이딩의 조건
    1. 선언부가 부모 클래스의 메서드와 일치
    2. 접근 제어자를 부모 클래스의 메서드 보다 좁은 범위로 변경 불가
    3. 예외는 부모 클래스의 메서드 보다 많이 선언할 수 없음
public class Car { // 부모
	...
    public double brakePedal() {
        speed = 0;
        return speed;
    }

    public void horn() {
        System.out.println("빵빵");
    }

}

public class SportsCar extends Car{ // 자식
	...
    @Override
    public double brakePedal() {
        speed = 100;
        System.out.println("스포츠카에 브레이크란 없다");
        return speed;
    }

    @Override
    public void horn() {
        booster();
    }
}

다형성

참조변수의 타입변환

자동 타입변환(up-casting)

부모타입 변수 = 자식타입객체;

  • 자식 객체는 부모 객체의 멤버를 상속받기 때문에 부모와 동일 취급
    • 하지만 이 과정에서 자식클래스에서 추가된 내용이 잘리는 '슬라이싱' 발생
    • 따라서 부모타입 변수로 자식객체의 멤버에 접근할 때는 부모 클래스에서 상속받은 멤버만 접근 가능

강제 타입변환(down-casting)

자식타입 변수 = (자식타입) 부모타입객체;

  • 부모타입객체는 자식타입 변수로 자동 타입변환 불가
  • (자식타입) 타입변환 연산자를 사용하여 강제 타입변환
  • 자식타입객체가 부모타입으로 자동 타입변환된 후 다시 자식타입으로 변환될 때만 강제 타입변환이 가능
// 자식타입객체가 자동 타입변환된 부모타입의 변수
Mammal mammal = new Whale();
mammal.feeding();

// 자식객체 고래의 수영 기능을 사용하고 싶다면
// 다시 자식타입으로 강제 타입변환을 하면된다.
Whale whale = (Whale) mammal;
whale.swimming();

다형성

여러 가지 형태를 가질 수 있는 능력

  • 부모변수 = 자식객체; 를 선언하여 자동 타입변환된 변수를 사용하여 각각의 자식객체에 재정의 된 메서드를 통해 다양한 결과 도출
public class Main {
    public static void main(String[] args) {
        // 매개변수 다형성 확인!
        Car car1 = new Car(new KiaTire("KIA"));
        Car car2 = new Car(new HankookTire("HANKOOK"));

        // 반환타입 다형성 확인!
        Tire hankookTire = car1.getHankookTire();
        KiaTire kiaTire = (KiaTire) car2.getKiaTire();

        // 오버라이딩된 메서드 호출
        car1.tire.rideComfort(); // KIA 타이어 승차감은 60
        car2.tire.rideComfort(); // HANKOOK 타이어 승차감은 100
    }
}

instance of 연산자

해당 객체가 특정클래스의 객체인지 확인

  • {대상 객체} instance of {클래스 이름} boolean값 반환
  • 다형성 기능으로 인해 해당 클래스 객체의 원래 클래스명을 체크하는것이 필요

추상클래스

추상클래스

클래스가 설계도라면 추상 클래스는 미완성된 설계도

  • abstract 키워드로 추상 클래스 선언
    public abstract class 추상클래스명 {
    
    }
  • 추상 클래스는 추상 메서드를 포함 가능
    • 추상 메서드가 없어도 추상 클래스로 선언 가능
  • 완성된 설계도가 아니므로 인스턴스 생성 불가
  • 추상 클래스는 자식 클래스에 상속되어 자식 클래스에 의해서만 완성됨
  • 추상 클래스는 여러개의 자식 클래스들에서 공통적인 필드나 메서드를 추출해서 만들 수 있음

추상메소드

아직 구현되지 않은 미완성된 메서드

  • abstract 키워드로 추상 메서드 선언

    public abstract class 추상클래스명 {
            abstract 리턴타입 메서드이름(매개변수, ...);
    }
  • 추상 메서드는 일반적인 메서드와는 다르게 블록{ }이 없음

    • 즉, 정의만 할뿐 내용이 없음!

추상클래스 상속

  • 자식클래스에서 추상클래스의 추상메서드는 반드시 오버라이딩 되어야 함!!!
public class 클래스명 extends 추상클래스명 {
	@Override
    public 리턴타입 메서드이름(매개변수, ...) {
		       // 실행문
    }
}

추상클래스 사용방법

클래스들의 공통적인 필드와 메서드를 추출

public class BenzCar {
    String company; // 자동차 회사 : GENESIS
    String color; // 자동차 색상
    double speed;  // 자동차 속도 , km/h

    public double gasPedal(double kmh) {
        speed = kmh;
        return speed;
    }

    public double brakePedal() {
        speed = 0;
        return speed;
    }

    public void horn() {
        System.out.println("Benz 빵빵");
    }

}

public class AudiCar {
    String company; // 자동차 회사 : GENESIS
    String color; // 자동차 색상
    double speed;  // 자동차 속도 , km/h

    public double gasPedal(double kmh) {
        speed = kmh;
        return speed;
    }

    public double brakePedal() {
        speed = 0;
        return speed;
    }

    public void horn() {
        System.out.println("Audi 빵빵");
    }

}
  • BenzCar, AudiCar, ZenesisCar 는 horn() 메서드의 내용에 차이가 존재
  • 따라서 horn() 메서드를 추상 메서드로 선언하여 자식 클래스에서 재정의
public abstract class Car {
    String company; // 자동차 회사 : GENESIS
    String color; // 자동차 색상
    double speed;  // 자동차 속도 , km/h

    public double gasPedal(double kmh) {
        speed = kmh;
        return speed;
    }

    public double brakePedal() {
        speed = 0;
        return speed;
    }

    public abstract void horn();
}

Reference

🔗 스파르타코딩클럽 Java 문법 종합반
🔗 자바의 정석

profile
공부한 내용은 바로바로 기록하자!

0개의 댓글