독후감/Java의 정석-기초편

Java의 정석 기초편 독후감 (7) - 객체지향 프로그래밍 II

RUNnRUN 2025. 3. 9. 16:08
728x90
  • 상속이란 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것
  • 상속을 통해서 클래스를 작성하면 새로운 클래스를 작성할 때 더 적은 코드로 생성할 수 있고 코드를 공통적으로 관리할 수 있다는 장점이 있다.
  • 상속을 구현하는 법은 새로 작성하고자 하는 클래스의 이름 뒤에 상속받고자 하는 클래스의 이름을 'extends'와 함께 써 주기만 하면 된다.
  • 상속해 주는 클래스를 '부모 클래스', 상속받는 클래스를 '자식 클래스'라고 한다.
  • 부모클래스의 변경은 자식클래스에서 영향을 주지만, 자식 클래스의 변경은 부모클래스에게 아무런 영향을 주지 않는다.
  • 자식 클래스의 인스턴스를 생성하면 부모 클래스의 멤버도 함께 생성되기 때문에 별도로 부모클래스의 인스턴스를 생성하지 않고도 부모 클래스의 멤버를 사용할 수 있다.
  • 클래스를 재사용하는 또 다른 방법은 포함(Composite)이다.
    클래스 간의 포함관계를 맺어주는 것은 한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는 것을 뜻한다.
  • 하나의 클래스가 여러 부모클래스를 가지는 다중상속의 경우 부모클래스에 선언부가 같고 결과가 다른 두 메서드가 있을 때 이를 구별할 수 있는 방법이 없다. 때문에 자바에서는 단일 상속만을 허용한다.
  • 자식 클래스는 부모클래스의 멤버 변수와 메스드를 그대로 사용할 수 있다. 이때 메서드를 자식클래스에 맞춰서 수정할 수도 있는데 이걸 '오버라이딩'이라고 한다.
  • 오버라이딩 시 지켜야 할 조건은 아래와 같다.
    • 선언부가 부모 클래스의 메서드와 일치해야 한다.
    • 접근 제어자를 부모 클래스의 메서드보다 좁은 범위로 변경할 수 없다.
    • 예외는 조상 클래스의 메서드보다 많이 선언할 수 없다.
  • super는 자식 클래스에서 부모 클래스로부터 상속받은 멤버를 참조하는 데 사용되는 참조변수이다.
  • 생성자는 상속되지 않기 때문에 자식클래스를 호출하면서 부모의 멤버 변수를 초기화하는 생성자를 사용하고 싶다면 super()를 사용하면 된다.
  • 패키지란 클래스의 묶음을 뜻하며 물리적으로 하나의 디렉토리이다.
    같은 클래스 이름을 가지더라도 패키지가 다르면 다른 클래스로 인식된다.
    이게 가능한 이유는 클래스의 실제 이름(full name)은 패키지명까지 포함하기 때문이다.
  • 제어자는 클래스, 변수 또는 메서드의 선언부에 함께 사용되어 부가적인 의미를 부여한다.
    제어자의 종류는 크게 접근 제어자와 그 외의 제어자로 나눌 수 있다.
    • 접근제어자 - public, protected, default, private
    • 그 외 - static, final, abstract, native, transient, synchronized, volatile, strictfp
  • 하나의 대상에 여러 제어자를 조합하여 사용하는 것이 가능하다.
    하지만 접근제어자의 경우 네 가지 중 하나만을 선택하여 사용가능하다.
  • static은 '클래스의' 또는 '공통적인'의 의미를 가지고 있다. 변수에 사용할 경우 클래스변수가 되는데 클래스변수는 모든 인스턴스가 공유한다. 
  • final은 '마지막의' 또는 '변경될 수 없는'의 의미를 가지고 있다. 변수에 사용할 경우 값을 변경할 수 없는 상수가 되며 메서드에 사용하면 오버라이딩을 할 수 없게 된다. 클래스에 사용할 경우 자신을 확장하는 자식클래스를 정의하지 못하게 된다.
  • abstract는 '미완성'의 의미를 가지고 있다. 메서드의 선언부만 작성하고 실제 수행내용은 구현하지 않은 추상 메서드를 선언하는데 사용된다. 클래스에 선언하여 클래스 내에 추상메서드가 있음을 쉽게 알 수 있게 해 줄 수도 있다. 추상 클래스의 경우 인스턴스를 생성할 수 없다.
  • 접근제어자는 멤버 또는 클래스에 사용되며 외부에서 접근하지 못하도록 제어하는 역할을 한다.
    • public - 접근제한이 전혀 없다.
    • protected - 같은 패키지 내에서, 그리고 다른 패키지의 자식클래스에서 접근이 가능하다.
    • default - 같은 패키지 내에서만 접근이 가능하다.
    • private - 같은 클래스 내에서만 접근이 가능하다.
  • 접근제어자의 사용이유로는 아래와 같은 이유가 있다.
    • 외부로부터 데이터를 보호하기 위해서
    • 외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해서
  • 인스턴스를 생성하고 참조변수에 주소값을 저장할 때 인스턴스타입과 참조타입을 동일하게 하는 게 일반적이지만 인스턴스타입이 참조타입과 상속관계일 때 부모 클래스 타입의 참조변수로 자식 클래스의 인스턴스를 참조하는 게 가능하다.
    하지만 주의해야 할 것은 참조타입이 부모클래스 타입일 경우 부모클래스의 멤버들만 사용할 수 있다.
  • 역으로 자식타입의 참조변수에 부모타입의 인스턴스를 참조하는 것은 허용되지 않는다.
  • 서로 상속관계에 있는 클래스 사이에서는 형변환이 가능하다.
    이때 참조변수가 가리키는 인스턴스의 자식타입으로 형변환은 허용되지 않는다.
  • 참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해서는 'instanceof' 연산자를 사용하면 된다.
  • 부모타입의 참조변수 배열을 사용하면 공통의 부모를 가진 서로 다른 종류의 객체를 배열로 묶어서 다룰 수 있다.
  • 부모 클래스의 특정 메서드가 자식클래스마다 수행내용이 다르다면 부모클래스를 추상클래스로 선언하여 메서드가 구현되어야 함을 알려줄 수 있다.
  • 만약 자식클래스가 부모클래스의 추상 메서드 중 하나라도 구현하지 않았다면 자식클래스 또한 추상클래스로 지정해주어야 한다.
  • 인터페이스는 일종의 추상클래스이지만 추상화정도가 더 높기 때문에 상수와 추상메서드만을 가질 수 있다.
  • 인터페이스는 인터페이스로부터만 상속이 가능하며 클래스와 달리 다중 상속이 가능하다.
  • 인터페이스에 선언된 추상메서드의 구현부를 구현하기 위해선 클래스 이름 뒤에 'implements 인터페이스명'을 붙어서 사용하면 된다.
  • 이때 상속과 마찬가지로 메서드 중 일부만 구현된다면 추상클래스로 지정해줘야 한다.
  • 메서드의 반환타입이 인터페이스일 경우 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 의미이다.
  • 클래스 내부에 클래스를 선언할 수 있는데 이를 '내부 클래스'라고 한다.
  • 내부 클래스의 장점은 아래와 같다.
    • 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근할 수 있다.
    • 코드의 복잡성을 줄일 수 있다.(캡슐화)
  • 외부클래스와 내부클래스에 선언된 변수의 이름이 같을 때 변수 앞에 'this' 또는 '외부 클래스명. this'를 붙여서 서로 구분할 수 있다.