[Java] 객체지향 프로그래밍 3

iiueon·2023년 7월 6일

상속(inheritance)

기존 클래스를 재사용하여 새로운 클래스를 작성하는 것

  • 생성자와 초기화 블럭은 상속되지 않는다. 멤버만 상속된다.
  • private 또는 default인 멤버들은 상속되지 않는다기보다 상속은 받지만 자손 클래스로부터의 접근이 제한되는 것이다.

클래스간의 관계 결정

상속 관계 : '~은 ~이다.(is-a)'
포함 관계 : '~은 ~을 가지고 있다.(has-a)'

단일 상속(single inheritance)

자바에서는 오직 단일 상속만을 허용
다중상속은 클래스간의 관계가 매우 복잡해지고, 서로 다른 클래스로부터 상속받은 멤버간의 이름이 같은 경우 구별할 방법이 없는 단점이 있기 때문

Object 클래스

모든 클래스 상속계층도의 최상위에 있는 조상클래스



오버라이딩(overriding)

조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것

오버라이딩 조건

  1. 조상 클래스의 메서드와 이름이 같아야 한다.
  2. 조상 클래스의 메서드와 매개변수가 같아야 한다.
  3. 조상 클래스의 메서드와 반환 타입이 같아야 한다.
  4. 조상 클래스의 메서드보다 접근 제어자를 좁은 범위로 변경 할 수 없다.
  5. 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.
  6. 인스턴스메서드를 static메서드로 또는 그 반대로 변경할 수 없다.

오버로딩(overloading) : 기존에 없는 새로운 메서드를 정의하는 것(new)
오버라이딩(overriding) : 상속받은 메서드의 내용을 변경하는 것(change, modify)

super와 super()

super : 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조변수
상속받은 멤버와 자신의 멤버와 이름이 같을 때 super를 붙여서 구별할 수 있음
super() : 조상 클래스의 생성자를 호출하는데 사용

Object클래스를 제외한 모든 클래스의 생성자 첫 줄에 this() 또는 super()를 호출해야 함. 그렇지 않으면 컴파일러가 자동적으로 'super();'를 생성자 첫 줄에 삽입



제어자(modifier)

접근 제어자 : public, protected, default, private
그 외 : static, final, abstract, native, transient, synchronized, volatile, strictfp

static - 클래스의, 공통적인

사용되는 곳 - 멤버변수, 메서드, 초기화 블럭

제어자대상의미
static멤버변수- 모든 인스턴스에 공통적으로 사용되는 클래스변수가 된다.
- 클래스변수는 인스턴스를 생성하지 않고도 사용 가능하다.
- 클래스가 메모리에 로드될 때 생성된다.
메서드- 인스턴스를 생성하지 않고도 호출이 가능한 static 메서드가 된다.
- static메서드 내에서는 인스턴스멤버들을 직접 사용할 수 없다.

final - 마지막의, 변경될 수 없는

사용되는 곳 - 클래스, 메서드, 멤버변수, 지역변수

제어자대상의미
final클래스변경될 수 없는 클래스, 확장될 수 없는 클래스가 된다.
그래서 final로 지정된 클래스는 다른 클래스의 조상이 될 수 없다.
(=자신을 확장하는 자손클래스 정의 X)
메서드변경될수 없는 메서드
final로 지정된 메서드는 오버라이딩을 통해 재정의 될 수 없다.
멤버변수/지역변수변수 앞에 final이 붙으면, 값을 변경할 수 없는 상수가 된다.

abstract - 추상의, 미완성의

사용되는 곳 - 클래스, 메서드

제어자대상의미
abstract클래스클래스 내에 추상 메서드가 선언되어 있음을 의미한다.
메서드선언부만 작성하고 구현부는 작성하지 않은 추상 메서드임을 알린다.

접근 제어자(access modifier)

멤버 또는 클래스를 외부에서 접근하지 못하도록 제한하는 역할

사용되는 곳 - 클래스, 멤버변수, 메서드, 생성자

private : 같은 클래스 내에서만 접근이 가능
default : 같은 패키지 내에서만 접근이 가능
protected : 같은 패키지 내에서, 그리고 패키지에 관계없이 상속관계에 있는 자손클래스에서 접근이 가능
public : 접근 제한이 전혀 없음

public > protected > (default) > private

접근제어자를 사용하는 이유

  • 외부로부터 데이터를 보호하기 위해
  • 외부에는 불필요한, 내부적으로만 사용되는, 부분을 감추기 위해서

생성자의 접근 제어자 (Singleton)

public class Singleton {
	
    // 2. 내부에서는 private 접근 가능하므로 직접 객체 생성, 객체가 한개만 생성되게 제한되어야 함
    // 4. static에서 인스턴스 바로 접근 못하니까 getInstance()에서 접근할 수 있도록 static으로
    private static Singleton s = null; // 중복 객체 생성을 막기 위해 null로 초기화
    
    // 1. 외부에서 생성자 접근하지 못하게 하기 위해 생성자의 접근 제어자를 private으로
    private Singleton(){}
    
    // 3. 외부에서 private 멤버에 접근 못하기 때문에 getter 생성
    // 4. 외부에서 접근 못하니까 객체 없이 외부에서 접근할 수 있도록 static으로
    public static Singleton getInstance() {
    	if(s == null) { // 객체가 이미 생성되었는지 판단
    		s = new Singleton();
    	}
    	return s;
    }
}

대상에 따라 사용할 수 있는 제어자

대상사용가능한 제어자
클래스public, (default) / final, abstract
메서드public, protected, (default), private / final, abstract, static
멤버변수public, protected, (default), private / final, static
지역변수/ final

제어자를 조합해서 사용할 때 주의사항

  1. 메서드에 static과 abstract를 함께 사용할 수 없다.
    static메서드는 몸통이 있는 메서드에만 사용할 수 있기 때문이다.

  2. 클래스에 abstract와 final을 동시에 사용할 수 없다.
    클래스에 사용되는 final은 클래스를 확장할 수 없다는 의미이고 abstract는 상속을 통해서 완성되어야 한다는 의미이므로 서로 모순되기 때문이다.

  3. abstract메서드의 접근 제어자가 private일 수 없다.
    abstract메서드는 자손클래스에서 구현해주어야 하는데 접근 제어자가 private이면, 자손클래스에서 접근할 수 없기 때문이다.

  4. 메서드에 private과 final을 같이 사용할 필요는 없다.
    접근 제어자가 private인 메서드는 오버라이딩될 수 없기 때문이다. 이 둘 중 하나만 사용해도 의미가 충분하다.



참고 자료

  • 자바의 정석 3판
profile
지연_로딩

0개의 댓글