자바는 객체지향 언어로, 객체지향 프로그래밍을 설계할 때 지켜야 할 5대 원칙이 존재한다.

1.  Single Responsibility Principle

단일 책임 원칙이란 모든 클래스가 하나의 책임 만을 가져야 한다는 의미이다. 한 클래스를 만들 때, 여러 기능을 모아두지 말고, 각 목적과 취지에 맞게 속성과 method를 구성함으로 관련된 책임만 줄 것을 의미한다.

2. Open Closed Principle

개방 폐쇄 원칙은 유지 보수사항이 생겼을 때, 코드를 쉽게 확장할 수 있도록 하고, 수정할 때는 닫혀있어야 한다는 원칙이다.

3. Liskov Substitution Principle

리스코프 치환 원칙은 프로그램의 객체는 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다는 의미이다. 클래스는 상속을 통해 부모 자식의 계층관계가 만들어지는데, 부모 객체에 자식을 넣어도 문제 없이 돌어가게 만드는 것을 의미한다.

4. Interface Segregation Principle

인터페이스 분리 원칙은 하나의 일반적인 인터페이스보다 구체적인 여러개의 인터페이스를 만들어야 한다는 원칙이다. 

5. Dependency Inversion Principle

의존 역전 원칙은 추상화 된 인터페이스나 상위 클래스를 통해 변화에 영향받지 않도록 하는 것을 말한다. 즉, 상위 계층은 하위 계층의 변화에 대한 구현으로부터 독립해야 함을 의미한다. 

이번에 정리할 내용은 자바의 기본 개념인 oop의 특징 4가지 중 상속과 다형성에 관련된 내용이다. 추상화와 캡슐화는 이전 링크 참고!

https://bl-nk.tistory.com/113

 

[BackEnd]Java란 무엇인가: OOP(1) Abatraction&Encapsulation

Java: High level, Object-Oriented Language자바는 Sun Microsystem의 제임스 고슬링에 의해 1995 처음 개발한 언어로, 어떤 환경이든 JVM만 있으면 구동할 수 있게 만들어진 언어이다. 주로 큰 스케일의 엔터프라

bl-nk.tistory.com


(3) Inheritance

자바에서 상속이란 부모 클래스, 인터페이스의 내용을 자식이 물려받아 사용하는 것을 말한다. 상속을 통해 메서드 오버라이딩을 할 수 있고, 재사용을 통해 동일한 코드의 반복을 줄일 수 있다는 장점이 있다. 자바의 상속은 부모와 자식의 관계를 IS-A 관계로 설명한다. 자식은 부모가 가진 모든 것을 사용하고 재 정의할 수 있다. 자바에서는 복잡성을 줄이기 위해, 하나의 클래스는 하나의 클래스만 상속받게 되어 있다. 두개의 클래스를 하나의 클래스가 상속받으려고 하면 compile에러가 발생한다.

(4) Polymorphism

자바에서 다형성은 하나의 액션을 다른 방법으로 할 수 있게 하는 개념이다. 크게 compile-time 다형성과 run-time 다형성으로 구분된다. Runtime 다형성은 메서드 오버로딩을 말한다. 자식이 상속하고 있는 부모의 메서드를 사용하는 것을 메서드 오버로딩이라고 하는데, Upcasting으로 선언할 때 발생한다. 부모의 클래스를 자식 클래스로 선언했을 때, 해당 객체의 메서드는 오버로딩 된 자식의 메서드가 실행되는 것을 의미한다. 단, 변수의 경우는 override의 개념이 없기 때문에, upcasting을 한 경우, 부모와 자식이 동일한 이름의 변수를 가지고 있을 경우 부모 클래스의 변수를 읽어오게 된다.

Upcating: 부모클래스를 상속받은 자식 클래스로 선언하는 것을 의미한다.

class Test{
	class A{
    	int variable=12;
        void run(){
        	System.out.println("Hello");
        }
    }
	class B extends A{
    	int variable=9;
        @Override
        void run(){
        	System.out.println("Hello, It's blank");
        }
    }
	public static void main(String args){
	    A a = new B();//Upcasting의 예시
        System.out.println(a.variable);	//출력값: 12
        a.run();	//출력값: Hello, It's blank
        
        A realA = new A();
        System.out.println(a.variable);	//출력값:12
        realA.run();	//출력값: Hello
    }	
}

* Override와 Overload의 차이

Override는 자식이 부모의 메서드를 상속받아 재정의 하는 것을 의미한다. 파라미터의 개수, 자료형이 달라야 하고, 리턴형은 같아야 한다. Overload는 같은 이름을 가진 메서드이지만 다른 파라미터를 사용하는 경우를 의미한다. 리턴형은 같아도 되고 달라도 된다! 둘의 공통점은 Over로 시작한다. 같은 이름을 가진 메서드를 다른 방법으로 풀어낸다는 것이다.

Java: High level, Object-Oriented Language

자바는 Sun Microsystem의 제임스 고슬링에 의해 1995 처음 개발한 언어로, 어떤 환경이든 JVM만 있으면 구동할 수 있게 만들어진 언어이다. 주로 큰 스케일의 엔터프라이즈 애플리케이션 개발에 사용된다. 자바는 (1) 스스로 메모리 관리를 해주고, (2) 다양한 기본 라이브러리들을 제공해주고, (3) 강력한 보안 정책을 제공해준다는 특징이 있다. 


1. OOP

Object-Oriented Programming의 약자인 OOP는 Object라는 개념에 기반한 프로그래밍 패러다임을 의미한다. Object는 데이터(ex. 변수)와 코드(ex. 메서드)를 포함한다. OOP에서 컴퓨터 프로그램은 서로 상호작용할 수 있게 만들어져 있다.

Object 란 state와 behavior, Identity를 가진 실제 세상의 객체를 의미한다.
  - State: Object의 가치

  - Behavior: 출금, 예금과 같은 행동
  - Identity: 다른 Object와 구분할 수 있는 id와 같 특별한 값
이런 Object를 논리적 개체로 만든 것이 Class!

다시 OOP로 돌아와서, OOP의 기본 원칙은 (1)추상화 Abstraction (2) 캡슐화 Encapsulation (3) 다형성 Polymorphism (4) 상속Inheritance으로 구성되어 있으며 Java는 이에 더해 (5)Association (6)Aggregation (7)Composition 의 원칙을 더 가지고 있다.

(1) Abstraction

간단하게 추상화란 Object와 관련있는 특성들만 보여주고, 필요없는 디테일들을 숨기는 것을 말한다. 불필요한 부분을 생략하고, 객체 속성 중 중요한 것에 중점을 두어 모델화를 함으로써 데이터의 공통된 성질을 추출할 수 있다. 예를 들어, 우리가 자동차를 운전할 때 차에 시동을 거는 것, 엑셀을 밟는 것은 신경쓰지만 어떤 원리로 차가 앞으로 가고 멈추는 지에 대해서는 궁금해하지 않는다. 추상이라는 개념은 이처럼 end-user가 애플리케이션을 사용할 때, 그 구체적인 특징에 대해 신경쓰지 않을 수 있도록 하는 것이다. Thereby the user will only know "what is does" rather than "how it does".

OOP에서 추상화는 크게 두가지 유형으로 분류된다. 1) Data Abstraction, 2) Control Abstraction.
1) Data Abstraction을 통해 우리는 객체가 내부적으로 데이터를 어떻게 저장하고 처리하는지를 감추고 외부에 필요한 기능만 제공하게 된다. 자동차를 예로 들었을 때, GV80-> SUV-> 현대차 -> 자동차로 데이터의 공통적인 특성을 묶어 이름붙이는 것을 말한다.
2)Control Abstraction은 프로그램의 흐름이나 제어 구조를 추상화하는 것을 의미한다. 복잡한흐름을 단순화하고, 반복적이거나 복잡한 로직을 한번에 처리할 수 있도록 직관적으로 코드를 작성하는 것을 말한다. 메서드, 반복문, 조건문이 대표적인 제어 추상화이다.

그렇다면 우리는 자바에 어떻게 추상화를 적용할 수 있을까? 자바는 non-access modifier "abstract"를 제공한다. abstract modifier는 class나 method에서는 사용되나 변수에서는 사용할 수 없다.  Interface는 구현없이 프로토타입의 메서드만 제공한다. Abstract class는 최소 1개의 구현되지 않은 메서드를 포함하고 있는 클래스를 의미한다. 추상 클래스와 관련된 내용은 다음에 더 자세히 알아보는 것으로 하자.

(2) Encapsulation

캡슐화는 한 클래스 안에 관련이 있는 변수와 메서드를 만들고, 외부에서 접근하거나 수정하는 것을 막는 것을 의미한다. 캡슐화를 하는 이유 중 하나는 관련 필드와 메서드를 함께 둠으로써 코드를 더 깔끔하고 읽기 쉽게 만들 수 있다는 것이다. 변경 가능성이 높은 부분은 내부에 숨기고, 외부에는 안정적인 부분만 공개함으로써 외부에 영향을 주지 않고 객체 내부의 구현을 변경할 수 있다. getter나 setter를 이용해서 read-only, write-only 접근을 제공한다. 

Data hiding은 데이터의 디테일한 구현을 숨김으로써 데이터에 대한 접근을 제한하는 방법이다. 외부에서의 접근을 제어하여 변수 값을 변경하지 못하게 하여 객체 내 정보 손상, 오용을 방지할 수 있다. 또한 데이터가 변경되었을 때에도 다른 객체에 영향을 주지 않아 독립성이 좋다는 장점이 있다. 접근제어자를 통해 data hiding을 하는 경우도 있다.

자바의 접근제어자는 크게 private, package(default), protected ,public로 나누어진다. private은 해당 클래스에서만 접근이 가능하고, 외부에서는 불가능하며 상속도 할 수 없다. package는 같은 패키지에서 접근이 가능한 경우를 말한다. protected는 같은 패키지에서 뿐 아니라, 상속받은 클래스에서도 접근 가능한 경우이다. 마지막으로 public은 모든 객체에서 접근 가능한 경우를 말한다.

다시 캡슐화로 돌아와서, 변수나 메서드가 private 접근제어자로 작성되었을 경우, getter와 setter 메서드를 통해 해당 변수에 접근할 수 있어서 정보를 은닉하고 보안을 높일 수 있다는 장점이 있다. setter에서는 주로 변수에 대한 제약 조건을 걸어주어 사용할 수 있다.

* Abastraction과 Encapsulation의 차이

  • Abstraction is a design-level process, but encapsulation is an implementation process.

앞서 설명했듯 추상화는 데이터의 기능적 요소를 취하여 일반화를 하는 것이고, 캡슐화는 데이터를 패키지화하여 외부로부터 보호하는 역할을 한다고 이해할 수 있다.

 


참고자료

+ Recent posts