▶CodeStates Back-End/Section 1

TIL [0512] 객체 지향 프로그래밍 - 상속, 캡슐화

휴학생감자 2022. 5. 16. 11:34

 

상속, Inheritance

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

공통적인 속성과 기능을 상위 클래스로부터 확장하여 하위 클래스에 나타낸다.

새로 작성하는 클래스의 이름 뒤에 상속받고자 하는 클래스의 이름을 'extends'와 같이 써주면 된다.

 

(자바의 클래스 상속계층도의 최상위에 위치한 상위 클래스는 Object클래스이며,

아무 상속을 받지 않는 클래스에 자동적으로 컴파일러가 extends Object를 추가하여 상속받도록 한다.)

 

※ 생성자와 초기화 블럭은 상속되지 않고, 멤버만 상속된다.

※ 하위 클래스의 멤버 개수는 상위 클래스보다 항상 같거나 많다.

 

#상속을 사용하는 이유

코드를 재사용하여 적은 양의 코드로 새로운 클래스를 작성할 수 있어 코드의 중복을 제거할 수 있다.

 

 

포함 관계(Composite)

상속과 같이 클래스를 재사용하는 방법 중 하나로, 한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는 것이다.

 

Ex) Class Circle {

               Point point = new Point();

               int r;

        }

 

 

클래스 간의 관계를 설정할 때... 포함 관계? 상속 관계?

→ '~은 ~이다(IS-A)'이면 상속 관계, '~은 ~을 가지고 있다(HAS-A)'이면 포함 관계

원은 점이다. Circle is a Point. (X)

원은 점을 가지고 있다. Circle has a Point. (O)

이 경우 두 번째 문장이 성립하므로 포함 관계를 맺어 주면 된다.

 

 


 

자바의 상속은 단일 상속만 가능하며, 다중 상속은 인터페이스를 활용하면 가능하다.

하위 클래스는 상위 클래스로부터 메서드를 상속받아 오버라이딩 할 수 있다.

오버라이딩을 할 때는..

1. 메서드의 선언부가 상위클래스의 것과 완전히 일치해야 한다.

2. 접근 제어자의 범위가 상위 클래스의 메서드보다 같거나 넓어야 한다.(public > protected > default > private)

3. 예외는 상위 클래스의 메서드보다 많이 선언할 수 없다.

 

 

super와 super( )

super : 상위 클래스로의 객체를 참조하는데 사용하는 참조변수

→ super를 붙이지 않으면 컴파일러는 자신이 속한 인스턴스 객체의 멤버를 먼저 참조한다.

super( ) : 상위 클래스의 생성자

→ 모든 생성자의 첫 줄에는 반드시 this( ) or super( )가 선언되어야 하나, 없을 경우 컴파일러가 자동으로 삽입한다.

      이때, 상위 클래스에 기본 생성자가 없다면 에러가 발생하게 되므로 주의해야 한다.

 


 

캡슐화, Encapsulation

특정 객체 안에 관련된 속성과 기능을 하나의 캡슐로 만들어

데이터를 외부로부터 보호하는 것을 말한다.

 

# 캡슐화의 목적

데이터의 보호 & 내부 데이터에 대한 불필요한 외부 노출을 방지

 

- 외부에서 객체의 속성과 기능을 변경하지 못하도록 함.

- 데이터가 변경되더라도 다른 객체에 영향을 주지 않음으로써 독립성을 확보

- 유지 보수와 코드 확장 시에도 오류의 범위를 최소화하여 효과적으로 관리할 수 있다.

 

 

접근 제어자(Access Modifier)

캡슐화를 구현하기 위한 방법으로 4가지가 있다.

접근범위는 public > protected > (default) > private 순서로 좁아 진다.

default는 아무 접근 제어자도 붙이지 않은 경우를 의미한다.

  같은 클래스 내 같은 패키지 내 다른 패키지의
하위 클래스
패키지 외
private O X X X
(default) O O X X
protected O O O X
public O O O O

 

 

# 데이터의 변경이 필요한 경우 → getter/setter 메서드 이용

public class Main {
    public static void main(String[] args) {
        Student student = new Student();
        student.setName("홍길동");
        student.setAge(20);

        System.out.println("이름 : " + student.getName());
        System.out.println("나이 : " + student.getAge());
    }
}

class Student {
    private String name;
    private int age;

    public String getName() { 
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

[실행 결과]