[혼공자] 4주차_상속 학습후기

혼자 공부하는 자바 개정판

4주차 학습 진도 : Chapter 7 (상속)




7-1 상속

상속(Inheritance)은 객체 지향 프로그래밍의 핵심 개념 중 하나입니다. 상속을 통해 기존 클래스의 속성과 메소드를 새로운 클래스에 재사용할 수 있어 코드의 재사용성을 높일 수 있습니다. 또한 상속을 통해 다형성(Polymorphism)을 구현할 수 있어 유연한 프로그래밍이 가능합니다.


클래스 상속

상속은 객체 지향 프로그래밍의 핵심 개념 중 하나입니다. 상속을 통해 기존 클래스의 필드와 메소드를 물려받아 새로운 클래스를 만들 수 있습니다. 이를 통해 코드의 재사용성을 높일 수 있습니다.

자바에서 상속은 extends 키워드를 사용하여 구현합니다. 상속받는 클래스를 자식 클래스, 상속을 해주는 클래스를 부모 클래스라고 합니다.


class Car {
}

class SportsCar extends Car {
  // 필드
  // 생성자
  // 메서드
}

자식 클래스는 부모 클래스의 모든 필드와 메소드를 상속받습니다. 단, 생성자와 private 접근 제한자로 선언된 필드와 메소드는 상속되지 않습니다.


부모 생성자 호출

자식 클래스를 생성할 때는 부모 클래스의 생성자가 먼저 호출됩니다. 이때 super() 메서드를 통해 부모 클래스의 생성자를 명시적으로 호출할 수 있습니다. 만약 부모 클래스의 생성자를 호출하지 않으면 기본 생성자가 자동으로 호출됩니다.


메소드 재정의

자식 클래스에서 부모 클래스의 메서드를 동일한 시그니처로 재정의(Overriding)할 수 있습니다. 이때 접근 제한자는 부모 클래스의 메서드보다 좁지 않아야 합니다.

public class Calculator {
    double areaCircle(double r) {
        System.out.println("Calculator 객체의 areaCircle() 실행");
        return 3.14159 * r * r;
    }
}

public class Computer extends Calculator {
    @Override
    double areaCircle(double r) {
        System.out.println("computer 객체의 areaCircle() 실행");
        return Math.PI * r * r;
    }
}


final 클래스와 final 메소드

final 키워드를 사용하면 해당 클래스나 메서드를 상속 또는 재정의할 수 없습니다. final 클래스는 더 이상 상속될 수 없으며, final 메서드는 오버라이딩될 수 없습니다.

public final class Member {
    // 이 클래스는 상속될 수 없음
}

public class VeryImportantPerson extends Member {
    // Member를 상속할 수 없음
}




7-2 타입 변환과 다형성

자바에서는 상속 관계에 있는 클래스 간에 타입 변환이 가능합니다. 이를 통해 다형성을 구현할 수 있습니다.


자동 타입 변환

자식 클래스의 인스턴스는 부모 클래스의 타입으로 자동 변환될 수 있습니다. 이를 ‘업캐스팅(Upcasting)’이라고 합니다. 업캐스팅된 객체는 부모 클래스의 멤버만 접근할 수 있습니다.

Cat cat = new Cat();
Animal animal = cat;

Cat 클래스로부터 cat 객체를 생성하고 이것을 Animal 변수에 대입하면 자동 타입 변환이 일어납니다.


필드의 다형성

부모 클래스의 참조 변수로 자식 클래스의 인스턴스를 참조할 수 있습니다. 이때 필드에 대한 접근은 참조 변수의 타입에 따라 결정됩니다.


매개 변수의 다형성

메서드의 매개변수 타입을 부모 클래스로 선언하면 자식 클래스의 인스턴스도 전달할 수 있습니다. 이를 통해 다양한 타입의 객체를 처리할 수 있습니다.

class Driver {
    void drive(Vehicle vehicle) {
        vehicle.run();
    }
}

Driver driver = new Driver();
Vehicle vehicle = new Vehicle();
driver.drive(vehicle);

이 코드는 매개변수의 다형성을 보여줍니다. Driver 클래스의 drive() 메서드는 Vehicle 타입의 매개변수를 받을 수 있으며, Vehicle 클래스의 모든 하위 클래스 인스턴스를 처리할 수 있습니다.


강제 타입 변환

업캐스팅된 참조 변수를 다시 원래의 자식 클래스 타입으로 변환하는 것을 ‘다운캐스팅(Downcasting)’이라고 합니다. 다운캐스팅은 명시적으로 수행해야 하며, 형 변환 연산자 (자식클래스) 를 사용합니다.

Parent parent = new Child();  // 자동 타입 변환
Child child = (Child) parent;  // 강제 타입 변환


객체 타입 확인

instanceof 연산자를 사용하면 참조 변수가 참조하고 있는 객체의 실제 타입을 확인할 수 있습니다. 이를 통해 안전한 다운캐스팅을 수행할 수 있습니다.

public void method(Parent parent) {
    if(parent instanceof Child) {
        Child child = (Child) parent;
    }
}

위에 코드에서 Parent 매개 변수가 참조하는 객체가 Child 인지 확인할수 있습니다




7-3 추상 클래스

추상 클래스는 추상 메소드를 포함할수 있는 클래스입니다. 추상 클래스는 인스턴스화할 수 없지만, 상속받아 구체화할 수 있습니다.


추상 클래스의 용도

추상 클래스는 구체적인 객체를 생성할 수 없지만, 공통된 필드와 메서드를 가진 클래스들의 부모 클래스로 사용됩니다. 추상 클래스를 상속받은 자식 클래스는 추상 메서드를 반드시 구현해야 합니다.


추상 클래스 선언

abstract 키워드를 사용하여 추상 클래스를 선언합니다. 추상 클래스에는 일반 메소드와 추상 메서드를 모두 포함할 수 있습니다.

public abstract class 클래스 {
    // 필드
    // 생성자
    // 메소드
}


추상 메소드와 재정의

추상 메서드는 선언만 있고 구현 내용이 없는 메서드 입니다. 추상 클래스를 상속받은 자식 클래스는 반드시 추상 메서드를 오버 라이딩하여 구현해야 합니다.

public abstract class Animal {
    public abstract void sound();
}





기본 숙제(필수) : 클래스의 타입 변환에는 어떤 것이 있는지 정리하고 공유하기


클래스의 타입 변환에는 자동타입변환과 강제타입변환이 있습니다.


자동 타입 변환(promotion)은 상위 클래스 타입의 변수에 하위 클래스 타입의 객체를 대입할 때 발생합니다. 이를 업캐스팅(Upcasting)이라고 하며, 상위 클래스 타입의 변수가 하위 클래스 타입의 객체를 참조할 수 있도록 자동으로 형변환이 이루어집니다.

Cat cat = new Cat();
Animal animal = cat;

cat과 animal 변수는 동일한 Cat 객체를 참조합니다.


강제 타입 변환(casting)은 하위 클래스 타입의 변수에 상위 클래스 타입의 객체를 대입할 때 발생합니다. 이를 다운캐스팅(Downcasting)이라고 하며, 상위 클래스 타입의 객체를 하위 클래스 타입의 변수에 대입하려면 명시적으로 형변환을 해야 합니다.

Parent parent = new Child();    // 자동 타입 변환
Child child = (Child) parent;    // 강제 타입 변환

다운캐스팅 시 주의사항은 실제 객체의 타입과 변환하려는 타입이 일치해야 하며, 그렇지 않으면 ClassCastException이 발생할 수 있습니다.





추가 숙제(선택) : p.389 (07-3) 확인 문제 3번을 풀고 풀이 과정 설명하기


package sec07.exam07;

public abstract class HttpServlet {
    public abstract void service();
}

package sec07.exam07;

public class HttpServletExample {
    public static void main(String[] args) {
        method(new LoginServlet());     // 로그인합니다.
        method(new FileDownloadServlet());  // 파일 다운로드합니다.
    }

    public static void method(HttpServlet servlet) {
        servlet.service();
    }
}


위와 같이 교재에서 HttpServlet 추상 클래스와 HttpServletExample 메인 클래스를 주웠으니, LoginServlet 클래스와 FileDownloadServlet 클래스를 추가로 만들어 주면 오류 없이 정상적으로 출력이 됩니다.


package sec07.exam07;

public class LoginServlet extends HttpServlet {
    @Override
    public void service() {
        System.out.println("로그인합니다.");
    }
}


package sec07.exam07;

public class FileDownloadServlet extends HttpServlet {
    @Override
    public void service() {
        System.out.println("파일 다운로드합니다.");
    }
}


위에 구체적인 클래서 LoginServlet, FileDownloadServlet 클래스를 작성한 코드 입니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다