도서/스프링 입문을 위한 자바 객체 지향의 원리와 이해

[도서/스프링 입문] #3 자바와 객체 지향

yulee_to 2023. 1. 14. 18:20

스프링 입문을 위한 자바 객체 지향의 원리와 이해

✔️ 이 글은 [스프링 입문을 위한 자바 객체 지향의 원리와 이해 - 김종민] 도서를 바탕으로 정리한 글입니다. 


객체 지향은 인간 지향이다

객체 지향은 사람이 주변에서 사물을 인지 하는 방식대로 프로그래밍하기 위해 탄생한 개념이다.

 

객체 지향의 4대 특성 - 캡! 상추다

  • 캡슐화(Encapsulation) : 정보 은닉 (information hiding)
  • 상속(Inheritance) : 재사용
  • 추상화(Abstraction) : 모델링
  • 다형성(Polymorphism) : 사용 편의

 

클래스 vs. 객체

클래스는 같은 속성과 기능을 가진 객체를 총칭하는 집합의 개념이고, 객체는 세상에 존재하는 유일무이한 사물을 의미하고 객체는 클래스의 인스턴스라는 표현을 사용한다.

 

추상화 : 모델링

추상화는 모델링이다

객체 지향의 추상화란 구체적인 것을 분해해서 관심 영역인 애플리케이션 경계(Application Boundary)에 있는 특성만 가지고 재조합 하는 것으로 모델링이라고도 한다.

어플리케이션 경계란 만들고자 하는 애플리케이션이 사용되는 용도를 의미하는 것으로 Context라고도 부른다.

 

추상화와 데이터 저장 영역

클래스 설계 과정

  1. 추상화를 통해 애플리케이션 경계 내에서 필요한 특성들만 골라냄
  2. 논리적 설계를 물리적 설계로 바꿈
    • 논리적 설계는 개발 환경에 영향을 받지 않는 설계
    • 물리적 설계는 개발 환경에 맞춰진 설계

 

용어 정리

클래스 멤버 = static 멤버 = 정적 멤버

객체 멤버 = 인스턴스 멤버 = 오브젝트 멤버

필드 = 속성 = 프로퍼티(Property)

함수 = 메소드

변수 공간 = 메모리 공간


상속 : 재사용 + 확장

객체지향에서의 상속은 상위 클래스의 특성을 하위 클래스에서 상속(특성 상속)하고, 거기에 더해 필요한 특성을 추가해서 사용할 수 있다는 의미이다.

상위 클래스로 갈수록 추상화, 일반화 되었다고 말하며, 하위 클래스 쪽으로 갈수록 구체화, 특수화됐다고 말한다.

 

상속의 강력함

클래스 명은 분류스럽게, 객체 참조 변수명은 유일무이한 사물처럼 작명해야 한다.

하위 클래스에서는 상위 클래스의 메소드를 사용할 수 있어 toString() 메소드는 모든 클래스의 상위 클래스인 Object라는 클래스의 메소드라서 어떤 클래스의 인스턴스든 상관없이 사용이 가능하다.

 

상속은 is a 관계를 만족해야 한다?

is a 관계는 객체와 클래스의 관계를 나타내는 표현이 더 정확하고, 상속은 is a kind of로 나타내는 것이 더 알맞은 표현이다.

하위 클래스 is a kind of 상위 클래스

 

다중 상속과 자바

자바에서는 다중 상속을 지원하지 않는다.

그 이유는 다중 상속의 다이아몬드 문제를 자바에서는 아예 배제시켰기 때문이다. 대신에 자바는 인터페이스라는 개념을 도입했다.

다중 상속의 다이아몬드 문제란 어떤 부모의 메소드를 호출해야할지 모호해지는 문제가 발생하는 경우를 말한다.

 

상속과 인터페이스

인터페이스는 "구현 클래스 is able to 인터페이스"로 표현할 수 있다. 인터페이스는 "무엇을 할 수 있는"이라는 형태로 만드는 것이 좋다.

ex) Serializable, Closeable, Comparable, Runnable 등

 

상위 클래스는 LSP 원칙에 따라 물려줄 특성이 풍성할수록 좋고, 인터페이스는 ISP 원칙에 따라 구현을 강제할 메소드의 개수가 적을수록 좋다.

 

상속과 UML 표기법

두 클래스간 상속은 하위 클래스에서 상위 클래스 쪽으로 속은 비어있고 닫힌 삼각형 머리에 실선 꼬리를 가진 화살표를 그려준다.

인터페이스를 구현한 경우에는 구현한 클래스에서 인터페이스 쪽으로 꼬리가 점선인 화살표를 그려준다.

 

상속과 데이터 저장 영역

하위 클래스의 인스턴스가 생성되면 상위 클래스의 인스턴스도 함께 생성된다.

 

다형성 : 사용편의성

오버라이딩과 오버로딩

  • 오버라이딩 - 재정의 : 상위 클래스의 메소드와 같은 메소드 이름, 같은 인자 리스트
  • 오버로딩 - 중복정의 : 같은 메소드 이름, 다른 인자 리스트

 

상위 클래스 타입에 하위 클래스 객체를 넣어줘도 잘 동작한다.

 

캡슐화 : 정보 은닉

자바에서의 정보 은닉(information hiding)은 접근 제어자로 설정해줄 수 있다.

 

객체 멤버의 접근 제어자

UML 표기법에서 -는 private, +는 public, #은 protected, ~은 default 접근 제어자를 의미한다.

 

접근 제어자

  • public : 모두 접근 가능
  • protected : 상속/같은 패키지 내 클래스 접근 가능
  • default : 같은 패키지 내 클래스 접근 가능
  • protected : 본인만 접근 가능

 

참조 변수의 복사

  • Call by Value : 값이 복사되어 두 변수는 서로 영향을 줄 수 없음
  • Call by Reference : 객체를 저장하고 있는 객체 참조 변수 자체를 넘겨줘 서로 영향을 줄 수 있음

 

실제로 자바에서는 Call by Value만 가능하다?

자바에서는 Pass by Value로 인자를 매개변수로 전달한다.

매개변수로 전달된 건 실제 오리지널이 아닌, 복사된 값으로 호출된 메소드 내에서 어떠한 변경이 이루어져도 해당 메소드를 호출한 caller method 내에서의 원본 파라미터들에는 어떠한 영향도 주지 않는다.

 

만약 안의 데이터가 1인 객체 A, B가 선언되어 있는 함수1에서 함수2에 A, B를 넘겨줘서 호출한다고 하자. 

그럼 함수2의 파라미터 a,b에는 각각 함수1에 선언된 객체 A,B의 참조값이 들어 있을 것이다. 

a객체의 어떤 데이터를 3으로 바꿔준뒤, b=a;라는 코드를 수행하면 b가 가리키던 객체가 B에서 A로 바뀔 것이다. 

그럼 b객체의 데이터는 몇일까? 가리키던 객체가 바뀌었으니 3이다.

함수2가 종료되고 함수1로 넘어왔을 때 객체 A,B를 확인해보면 A에는 데이터가 3, B에는 데이터가 1인 것을 확인할 수 있다.

이처럼 호출된 함수2에서는 객체의 참조값만 받아왔기 때문에 b=a;를 해줘도 b가 가리키는 객체가 바뀔 뿐 함수1의 객체 B가 바뀌진 않는다. 여기서 참조값은 주소값으로 생각하면 쉽지만 자바에는 객체의 주소값이라는 개념이 없기 때문에 hashcode() 결과값이라고 생각하는 것 타당하다.

 

그럼 Call by Refrence는 어떻게 작동할까?

C++는 매개 변수로 주소를 넘겨주면 Call by Reference로 동작하는데 위의 경우처럼 함수2에서 a의 데이터를 3으로 바꿔주고, b=a;를 수행하면 b가 가리키는 객체가 A로 바뀐다. 함수2가 종료되고 함수1로 넘어오면 A의 데이터도 B의 데이터도 모두 3인 것을 확인할 수 있다. Call by Refrence는 매개 변수로 객체를 전달 할때 그 객체 자체를 전달하기 때문에 호출된 함수에서 객체 자체를 다룰 수 있다.

 

참고 자료:

https://deveric.tistory.com/92

728x90