반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 연습문제
- depromeet
- 디프만16기
- flutter
- 자료구조
- 코드 트리
- dip
- java
- Spring
- exception
- Kafka
- AOP
- nGrinder
- 부하 테스트
- pub.dev
- kakao
- Kotlin
- 디프만
- Sharding
- OAuth
- 코딩 테스트
- Oidc
- Scaffold
- c
- 코딩
- C언어
- 운영체제
- 코딩테스트
- Redis
- 코드트리
Archives
- Today
- Total
Nick Dev
[JAVA] 객체 지향의 4대 특성 - 캡!상추다 본문
반응형
이 내용을 정독하면 객체 지향의 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
는 이 스택 프레임안에 존재함mickey
는 heap에 생성되어 있는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문장!!!
- 객체 지향의 상속은 상위 클래스의 특성을 재사용하는 것이다
- 객체 지향의 상속은 상위 클래스의 특성을 확장하는 것이다
- 객체 지향의 상속은 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
- 같은 메서드 이름, 다른 인자 목록으로 다수의 메서드를 하나의 이름으로
**중복 정의**
여기서 다형성이란?
Animal
의showName()
을Whale
에서 Overriding한 경우, 상위 클래스 타입의 객체 참조 변수를 사용하더라도 자동으로 하위 클래스에서 overriding한 메서드가 호출된다Animal aWhale = new Whale();
- 이 경우,
aWhale.showName()
호출할 때Animal
의showName()
이 호출되지 않고Whale
의showName()
이 호출된다
만약 다형성이 지원되지 않는다면?!
- 오버로딩이 지원되지 않아 인자의 조합마다 메서드를 각각 선언해야 한다면 매우 많은 메서드를 작성해야 한다
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이라고 해석했을 것이다
⭐ 정리
- 기본 자료형 변수는 값을 값 자체로 판단 (편견없이)
- 참조 자료형 변수는 값을 주소, 즉 포인터로 판단
- 기본 자료형이든 참조 자료형이든 변수를 복사할 때 일어나는 일은 같다!!!!!!!
- 해당 변수가 가지고 있는 값을 그대로 복사해서 넘겨준다
반응형
'Java' 카테고리의 다른 글
[JAVA] volatile ⁉ (0) | 2024.12.11 |
---|---|
[JAVA] Thread vs Process (0) | 2024.12.11 |
[JAVA] HashMap의 내부 구현 방식 (0) | 2024.12.11 |
[JAVA] ArrayList의 내부를 뜯어보자 (0) | 2024.12.11 |
[JAVA] try-with-resources 써야 돼? (0) | 2024.12.11 |