[OOP] OOP 4가지핵심개념

김명래·2022년 9월 7일
0

OOP

목록 보기
1/4
post-thumbnail

OOP

OOP 란 객체 지향 프로그래밍(Object-Oriented Programming)을 줄여서 흔히들 OOP라고 부른다.
OOP란 현실 세계를 프로그램 설계에 반영한다는 개념을 기반으로 접근하는 방법이다. OOP는 90년대 초반부터 유명해지기 시작했지만 전 세계의 많은 개발자들이 사용하고 있는 설계 패턴 중 하나이다.

OOP의 핵심 4가지

1.캡슐화

데이와 데이터를 활용하는 함수를 캡슐(class) 혹은 컨테이너에 넣는것을 이야기한다.

캡슐화를 하는 가장 큰 이유는 정보은닉에 있다.
캡슐화를 통해 외부에서 내부의 정보에 접근하거나 변경할 수 없게 직접적인 접근을 막고 객체가 제공하는 필드와 메소드를 통해서 접근이 가능하다.

이렇게 접근을 제한함으로써 유지보수나 확장 시 오류의 범위를 최소화할 수 있고 객체 내의 정보 손상과 오용을 방지하고 데이터가 변경되어도 다른 객체에 영향을 주지않아 독립성이 좋다.

아니 근데 독립적인게 장점인건 class의 장점이지 캡슐화의 장점은 아니지 않나?

예제)

package encapsualtion;

public class BeforeEncapsualtion {	
	public static void main(String[] args) {
		Calculator c = new Calculator();		
		c.num1 = 20;
		c.num2 = 30;
		c.sum();
		//여기까지는 문제가 없을 수도 있다. 하지만 사용자가 sum 의 접근이 가능하다면 ?		
		c.sum = 20;		
		//사용자가 마음대로 필드에 접근하여 값을 수정할 수 있음. 즉, 원하지 않는 결과를 얻어낼 수 있다.		
		System.out.println(c.sum);
		
	}
}
class Calculator{
	public int num1;
	public int num2;
	public int sum;
	public void sum() {
		this.sum = this.num1 + this.num2;
	}
};

2.상속

(출처 : https://sujl95.tistory.com/32)
상속은 무언가로부터 물려 받다는 개념이다. 현실 세계에서 부모의 재산을 자식이 물려받는것과 비슷하다.
객체 지향에서의 상속은 inheritance(상속)이 아닌 extends(재사용과 확장)으로 이해하는것이 좋다.

  • 클래스가 상속을 위해 특별히 설계되었거나 구조화가 잘 된 클래스를 확장의 목적으로 상속하는것이 안전하다.
  • 동일 개발자가 하위 클래스와 상위 클래스의 통제하는 경우 같은 패키지내에서 상속하는 것이 안전하다.


위 사진은 현실세계의 상속이다 하지만 객체지향에서의 상속은 이와 조금 다르다.

업로드중..
위 관계는 상속의 관계가 아니다. 동물은 포유류와 조류의 부모가 아니며 고래 또한 부모가 포유류가 될수는 없다.

자바상속의 특징

  • 다중 상속을 지원하지 않는다.
  • 상속 횟수 제한이 없다.
  • 자바의 최상위 부모는 Object이다.
  • 상속시 물려줄 특성이 풍부하면 좋고 인터페이스는 구현을 강제할 메소드가 적으면 좋다.

그래서 상속 왜하는건대 ??

  • 유지보수가 쉽다
  • 중복이 적어진다
  • 통일성이 있다
  • 확장성이 용이해진다
  • 모듈화를 통해 재사용이 가능해진다
  • 코드가 간결해진다
  • 개발시간을 단축할 수 있다

상속의 단점

  • 상속을 사용하면 기능 추가/ 변경시에 예외나 버그가 발생하게 되면 어디에서 발생한지 예측을 하기가 힘들다.
  • 상속 구조가 복잡하면 더욱 예측하기 힘들어진다
    불필요한 기능을 원치 않는다 해도 상속해야한다
    자료구조에서 Stack은 Vector를 상속하고 있는데 Vector의 단점을 모두 상속 받는다.
    Vector 단점
    ArrayList를 상속 받아 사용하고 synchronized가 걸려있다(thread-safe)
  • 캡슐화 원칙을 위반한다
    상위 클래스의 구현이 하위 클래스에게 노출되는 상속은 캡슐화를 깨뜨린다. 캡슐화가 깨짐으로서 하위 클래스가 상위 클래스에게 강하게 결합, 의존하게 되고 강한 결합, 의존은 변화에 유연하게 대처하기 어려워진다.

예제)

3.추상화(Abstraction)

공통의 속성이나 기능을 묶어 이름을 붙이는 것
객체 지향적 관점에서 클래스를 정의하는 것을 바로 추상화라고 정의 내릴 수 있다.

예시를 들자면 영재, 유리, 유미, 장민, 명래 라는 객체를 하나로 묶으려고 할때 사람 또는 포유류 라고 묶는것을 추상화 라고한다.

C++의 아버지는 추상화를 "구현 세부 정보를 숨기는 일반 인터페이스를 지정하는 행위" 라고 정의했다.
뭔 개소리야

4.다형성(Polymorphism)

다형성(polymorphism)이란 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미합니다.

자바에서는 이러한 다형성을 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하여 구현하고 있습니다.

다형성은 상속, 추상화, 캡슐화와 더불어 객체 지향 프로그래밍을 구성하는 중요한 특징 중 하나입니다.

사용이유

예제1)

package encapsualtion;

public class BeforeEncapsualtion {	
	public static void main(String[] args) {
		Youngjae j = new Youngjae();
		Company c = new Company();
		
		c.pass(j);
		
	}
}
class Human{
	private String language;
	
	public Human() {
		super();
	}

	public Human(String language) {
		super();
		this.language = language;
	}

	public String getLanguage() {
		return language;
	}

	public void setLanguage(String language) {
		this.language = language;
	}
	public String hello(){
		return "hello";
	}
};

class Company{
	public void pass(Human m) {
		if(m instanceof Myeongrae) {
			System.out.println("명래님 합격이에요 ! ");
		}else {
			System.out.println("영재님 합격이에요 ! ");
		}
	}
}

class Myeongrae extends Human{
}
class Youngjae extends Human{	
}

별 문제없어보이는 코드지만 Human 을 상속하는 class 가 많아질수록 if 문을 추가해야하기 때문에 좋지않다 다음처럼 pass 인터페이스를 작성하고 인터페이스를 구현하도록 변경해보자.

package encapsualtion;

public class BeforeEncapsualtion {	
	public static void main(String[] args) {
		Youngjae j = new Youngjae();
		Company c = new Company();
		
		c.pass(j);
		
	}
}

interface Passable{
	void pass();
	
}
class Human{
	private String language;
	
	public Human() {
		super();
	}

	public Human(String language) {
		super();
		this.language = language;
	}

	public String getLanguage() {
		return language;
	}

	public void setLanguage(String language) {
		this.language = language;
	}
	public String hello(){
		return "hello";
	}
};

class Company{
	public void pass(Passable p) {
		p.pass();
	}
}

class Myeongrae extends Human implements Passable{
	public void pass() {
		System.out.println("명래님 합격이에요 ! ");
	}
}
class Youngjae extends Human implements Passable{
	public void pass() {
		System.out.println("영재님 합격이에요 !");
	}
}

이렇게 되면 human 을 상속받는 class 가 늘어나더라도 pass method의 수정을 하지않아도 된다.

이렇게 하나의 객체가 여러개의 자료형을 가질 수 있는것을 객체지향에서 다형성 이라고 한다.

즉 Youngjae class 의 객체는 다음과 같이 표현될 수 있다.

Youngjae j = new Youngjae();
Human a = new Youngjae();
Passable b = new Youngjae();

profile
독자보다 필자를 위해 포스팅합니다

0개의 댓글