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

nick·2024년 4월 5일
0

JAVA

목록 보기
10/13

이 내용을 정독하면 객체 지향의 4대 특성에 대한 오해가 풀리고 완벽히 이해할 수 있다
우리가 알고 있는 붕어빵틀과 붕어빵 비유, is a 관계잘못된 비유모호한 표현들을 바로 잡자!!!

객체 지향이란?

  • 기계에 맞춰 절차적으로 프로그래밍하지 않고 사물을 인지하는 방식대로 프로그래밍하는 것
  • 객체 지향의 4대 특성
    • 캡상추다
    • 캡슐화, 상속, 추상화, 다형성

1. 추상화 = 모델링

⭐ 추상화란?

  • 구체적인 것을 분해해서 관찰자가 관심 있는 특성만 가지고 재조합 하는 것
  • 즉, 현실 사물의 특성들 중 해당 애플리케이션의 context(경계)에 맞는 특성만 가지고 재조합하는 것 = 모델링
    • 추상화의 결과 = 재조합의 결과 = 모델링의 결과 = 모델 = Class

Application Context?

  • Application Boundary라고 생각할 수 있다
  • 같은 사물이라도 내 애플리케이션의 문맥, 즉 관심 영역이 무엇인지에 따라 관심있는 특성이 달라진다
    • 병원 애플리케이션 : 사람 → 환자
    • 은행 애플리케이션 : 사람 → 고객

📌 자바에서 추상화 지원하는 방법

  • class 키워드를 통해 지원

개발자가 class를 만드는 과정이 곧 모델링하는 과정이고 그게 곧 추상화를 하고 있는 것이다


클래스 ↔ 객체

구분 방법

  • 생물일 경우 → 나이 물어보기
  • 무생물일 경우 → 제조일자 물어보기

클래스

  • 분류에 대한 개념
  • 같은 속성과 기능을 가진 객체를 총칭하는 개념
  • 객체의 설계도

객체

  • 실체
  • 세상에 존재하는 유일무이한 객체

클래스, 메서드, 객체는 메모리 어디에 저장될까?

public class Mouse {
		public String name;
		public int age;
		public static int countOfTail = 1;
		
		public void sing() {
				System.out.println(name + " 찍찍!!");
		}
}

--------------------------------------------------
public class MouseDriver {
		public static void main(String[] args) {
				Mouse mickey = new Mouse();
				
				mickey.name = "미키";
				mickey.age = 50;
				
		}
}

클래스는 static 영역에

  • static 영역은 클래스들의 놀이터다
  • 기본적으로 클래스는 static 영역에 생성된다
  • main(), countOfTail과 같은 static 변수, static 메서드static 영역에 단 1개 생성된다
  • static 변수 : 같은 클래스의 모든 객체들이 같은 값을 가지고 있을 때 활용한다
    • static 멤버 = 클래스 멤버 = 정적 멤버
    • 그림을 잘보면 클래스 내부에 메모리 공간이 확보
      • 인스턴스 변수는 heap 영역에 객체 생성되면 각 객체 안에 메모리 공간 할당된다
  • static 메서드 : 객체들에 존재 여부에 관계 없이 쓸 수 있는 메서드
    • 주로 유틸리티성 메서드를 정적 메서드로 구성

메서드는 stack 영역에

  • stack 영역은 메서드들의 놀이터다
  • 여는 중괄호({)를 만나면 stack 영역에 스택 프레임이 생성된다
    • 분기 처리되는 { 이건 해당 메서드 안에 생성된다
  • 닫는 중괄호(})를 만나면 스택 프레임 사라진다
  • Mouse mickey = new Mouse(); 에서 Mouse객체의 참조 변수인 mickey는 이 스택 프레임안에 존재함
    • mickeyheap에 생성되어 있는 Mouse 객체의 참조값(주소값)을 갖고 있다 (포인팅하고 있다고 생각하면 됨)

객체는 heap 영역에

  • heap 영역은 객체들의 놀이터다
  • Mouse mickey = new Mouse();를 통해 객체가 생성되면 Mouse 객체는 heap 영역에 생성된다

정리

이름다른 이름서식지
static 변수클래스 속성(멤버), 정적 변수 …static 영역
인스턴스 변수객체 속성(멤버), 객체 변수, …heap 영역
local 변수지역 변수stack 영역(해당 스택 프레임 내부)

2. 상속 = 재사용 + 확장

⭐ 정의

  • 객체 지향에서 상속은 상위 클래스의 특성을 하위 클래스에서 상속하고 거기에 더해 필요한 특성을 추가, 즉 확장해서 사용할 수 있다는 의미
    • 즉, 상속이라는 워딩보단 재사용 & 확장이 더 맞는 워딩
  • 상위 클래스쪽으로 갈수록 추상화, 일반화됐다고 말함
  • 하위 클래스쪽으로 갈수록 구체화, 특수화됐다고 말함

상속 관계에서 반드시 만족해야하는 문장

  • 하위 클래스는 상위 클래스다
    • 포유류동물이다 → OK
    • 고래포유류다 → OK
    • 고래동물이다 → OK ⇒ 객체 지향 설계 5원칙 LSP(리스코프 치환 원칙)

⭐ 상속 관계는 is a 관계다? → 아님!!

  • 하위 클래스는 하나의 상위 클래스다
    • 명확하지 않은 표현이다
  • is a 대신에 is a kind of 관계가 더 명확한 표현이다
    • 하위 클래스 is a kind of 상위 클래스
    • 포유류 is a kind of 동물 → 포유류는 동물의 한 분류다

⭐ 기억해야할 3문장!!!

  1. 객체 지향의 상속은 상위 클래스의 특성을 재사용하는 것이다
  2. 객체 지향의 상속은 상위 클래스의 특성을 확장하는 것이다
  3. 객체 지향의 상속은 is a kind of 관계를 만족해야 한다

자바가 다중 상속을 지원하지 않는 이유

  • 만약 다중 상속을 지원한다면, 인어가 사람과 물고기를 확장하고 있다고 할 때,
    • swim() 메서드를 수행하면 사람의 swim()을 실행해야할지 물고기의 swim()을 실행해야 할지 모호해진다 → 다중 상속의 다이아몬드 문제
  • 다중 상속을 지원하지 않는 대신 인터페이스를 도입다중 상속의 득은 취하고 실은 버림

인터페이스란?

  • 인터페이스는 클래스가 ‘무엇을 할 수 있다’라고 하는 기능을 구현하도록 강제하는 것이다
  • 구현 클래스 is able to 인터페이스
    • 구현 클래스는 인터페이스 할 수 있다
    • 고래는 헤엄칠 수 있다

상속과 인터페이스 특징

  • 상위 클래스는 물려줄 특성이 많을수록 좋음
  • 인터페이스는 구현을 강제할 메서드가 적을수록 좋음
    • ISP(인터페이스 분할 원칙) 때문에

상속과 메모리

public class Animal {
		public String name;
		
		public void showName() {
				System.out.println(name + "입니다");
		}
}

public class Whale {
		public String habitat;
		
		@Overriding
		public void showName() {
				System.out.println("overriding: " + name + "입니다");
		}
		
		public void showHabitat() {
				System.out.println(habitat + "에 살아요");
		}
		
		//Overloading
		public void showHabitat(String param) {
				System.out.println(habitat + "에 살아요" + param);
		}
}

public class Driver {
		public static void main(String[] args) {
				Whale theWhale = new Whale();
				
				theWhale.name = "고래고래1";
				theWhale.habitat = "남극";
				
				theWhale.showName();
				theWhale.showHabitat();
				
				Animal aWhale = new Whale();
				
				aWhale.name = "하나의 고래";
				// aWhale.habitat = "북극";
				
				aWhale.showName();
				// aWhale.showHabitat(); 
				
		}
}
  • 하위 클래스의 인스턴스(Whale)를 생성하면 자동으로 먼저 상위 클래스들의 인스턴스부터 생성된다
    • Whale theWhale = new Whale(); 을 실행하면 Heap 영역에 **Whale 클래스의 인스턴스Animal 클래스의 인스턴스Object 클래스의 인스턴스**도 생성된다
  • awhale 객체 참조 변수사실은 Whale이지만 자신은 Whale인지 모르고 Animal이라고만 알고 있다 ( → 암묵적 형변환)
    • 그래서 aWhale 참조 변수는 habitat 관련된 것들을 수행할 수 없다

3. 다형성 : 사용 편의성

정의

  • Polymorphism
  • 객체 지향에서 다형성이란 오버라이딩오버로딩이라고 할 수 있다

Overriding

  • 상위 클래스의 메서드를 재정의

Overloading

  • 같은 메서드 이름, 다른 인자 목록으로 다수의 메서드를 하나의 이름으로 **중복 정의**

여기서 다형성이란?

  • AnimalshowName()Whale에서 Overriding한 경우, 상위 클래스 타입의 객체 참조 변수를 사용하더라도 자동으로 하위 클래스에서 overriding한 메서드가 호출된다
    • Animal aWhale = new Whale();
    • 이 경우, aWhale.showName() 호출할 때 AnimalshowName()이 호출되지 않고 WhaleshowName()이 호출된다

만약 다형성이 지원되지 않는다면?!

  • 오버로딩이 지원되지 않아 인자의 조합마다 메서드를 각각 선언해야 한다면 매우 많은 메서드를 작성해야 한다
    • addIntDouble(int, double)
    • addDoubleInt(double, int)
  • 하지만 하나의 메서드명을 가지고 여러 인자 목록을 허용하면 매우 편리해진다 → 사용 편의성이 좋다
    • add(int, double)
    • add(double, int)
  • 오버라이딩의 경우에도 하위 클래스가 재정의한 메서드를 자동으로 알아서 호출해준다 → 사용 편의성 좋다

4. 캡슐화 : 정보 은닉

정의

  • 자바에서 정보 은닉은 접근 제어자private, default, protected, public 을 통해 가능하다

기억해야할 2가지

  • 상속받지 않았다면 인스턴스 변수객체 생성한 후 객체 참조 변수를 이용해 접근해야 함
  • 클래스 변수클래스명.클래스 변수명 형식으로 접근하는 것을 권장

⭐ Reference Type은 Call By Reference일까? → 아님!!!!!!

  • 자바는 무조건 Call By Value
  • 다만, 그 Value를 어떻게 해석하는지 기본형인지 참조형인지에 따라 다른 것 뿐이다!!!!!
    • 기본 자료형 변수는 변수가 저장하고 있는 값을 그 값 자체로 해석
    • 참조 자료형 변수는 저장하고 있는 값을 주소로 해석
    • 결국 참조 자료형도 객체를 넘기는게 아니라 주소값을 넘기는것!!!!!!
Animal ref_a = new Animal();
Animal ref_b = ref_a;

ref_a.age = 10;
ref_b.age = 20;

System.out.println(ref_a.age);    // 20
System.out.println(ref_b.age);    // 20

  • 그림과 같이 실제 객체를 넘기는게 아닌 ref_a가 저장하고 있는 Animal 객체의 주소값을 넘기는거다 → 그래서 자바는 Call By Value
  • 참조 자료형이기 때문에 ref_a 의 value인 100주소값으로 해석하는 것이고
  • 만약 기본 자료형이였다면 이 100을 그 값 자체인 100이라고 해석했을 것이다

⭐ 정리

  • 기본 자료형 변수는 값을 값 자체로 판단 (편견없이)
  • 참조 자료형 변수는 값을 주소, 즉 포인터로 판단
  • 기본 자료형이든 참조 자료형이든 변수를 복사할 때 일어나는 일은 같다!!!!!!!
    • 해당 변수가 가지고 있는 값을 그대로 복사해서 넘겨준다
profile
티스토리로 이전 : https://andantej99.tistory.com/

0개의 댓글