클래스 객체명 = new 클래스();
에서 클래스 → 붕어빵틀, 객체 → 붕어빵으로 치환시켜 보자.
붕어빵틀 붕어빵 = new 붕어빵틀();
이상하다. 붕어빵틀을 하나 만들었는데 그것이 붕어빵에 대입이 된다는 것인데, 논리에 맞지 않다.
따라서 필자는 클래스 → 붕어빵틀, 객체 → 붕어빵이라는 기존에 우리들이 많이 배워왔던 관념을 부정하고 있다.
간단하게 나이를 물어보자.
ex ) 사람의 나이는 몇 살인가 ? (답변이 안됨 → 클래스)
구범모의 나이는 몇 살인가 ? (26살. 답변이 되므로 객체.)
필자가 주장하는 바는, 클래스 : 객체는 붕어빵틀 : 붕어빵이 아닌, 분류 : 실체로 구분짓는 것이 좋다고 한다.
추상 : 여러 가지 사물이나 개념에서 공통되는 특성이나 속성 따위를 추출하여 파악하는 작용.
추상화란?
객체 : 세상에 존재하는 유일무이한 사물
클래스 : 분류, 집합. 같은 속성과 기능을 가진 객체를 총칭하는 개념.
클래스 객체명 = new 클래스(); 라는 코드의 의미는,
클래스(분류)를 이용해 유일무이하고 새로운 하나의 객체를 만들어 객체명이라는 이름을 지어주는 하나의 과정.
이렇게 클래스를 이용해 객체를 만들었다는 것을 강조할 때는, object가 아닌 instance라는 표현을 쓴다.
🤓 속성 : 시력, 몸무게, 나이 등등 명사로 표현되는 특성 메서드 : 먹다, 자다, 일하다 등등 동사로 표현되는 특성 (기능 / 행위라고 표현되며, 절차 혹은 로직을 가진다.)위의 추상화의 정의를 좀 더 구체화 시켜보자.
추상화란?
따라서 모델(클래스)은 실제 사물을 정확히 복사하는 것이 아니라, (애플리케이션의)목적에 맞게 관심 있는 특성(ex : 병원 애플리케이션이라면 사람의 시력, 청력 등등..)만 추출해서 표현하는 것.
이것은 즉 모델은 추상화를 통해 실제 사물을 단순하게 묘사한다는 것이다.
이런 모델링은 클래스를 설계할 때 필요하고, 정말 많이 중요하다고 한다.
책에서 소개한 countOfTail같이, 모든 인스턴스가 같은 속성을 가질 경우 해당 속성을 static으로 선언함으로써 메모리를 아낄 수 있다.(매번 인스턴스를 생성할 때 마다 해당 공간을 추가적으로 할당해줄 필요가 없으므로.)
이때 static멤버는 역시 static 영역의 클래스 내에 할당된다.
메모리 관점에서 static멤버와 인스턴스 멤버를 살펴보면,
static멤버는 클래스가 static 영역에 올라올 때 동시에 클래스 내부에 공간이 확보되지만,
동시에 인스턴스 멤버는 멤버명만 있고, 실제 메모리 공간은 실제로 힙 영역에 객체가 생성되면 그때 객체 안에 멤버 속성을 위한 메모리 공간이 할당된다.
(이는 변수, 메서드 모두에 해당되는 이야기이다.)
따라서 추상화를 통해 모델링을 하게 되면 아래와 같이 설계를 하는 것이다.
| 클래스 설계 | 클래스(정적) 멤버 | static | 클래스 멤버 속성 |
|---|---|---|---|
| 클래스 멤버 메서드 | |||
| 객체 멤버 | 객체(인스턴스) 멤버 속성 | ||
| 객체(인스턴스) 멤버 메서드 |
정적 멤버 : 해당 클래스의 모든 객체가 같은 값을 가질 때 사용하는 것이 좋다.
정적 메서드 : 객체의 존재 여부에 관계 없이 사용할 때(유틸리티성 메서드), 정적 변수를 다루는 메서드일 때
먼저 멤버변수, 클래스 변수는 프로그램 내에서 다양한 곳에서 접근이 가능한 공유변수이다.
따라서 공유 변수를 누가 초기화해야 한다고 규정하기가 힘들기 때문에, 별도로 초기화를 하지 않더라도 각 타입에 맞는 기본값으로 초기화를 해 둔다.(런타임 에러 방지용으로 이해했다.)
하지만 지역변수는 해당 지역 내에서만 사용되고 소멸되는 변수이므로, 초기화의 주체가 해당 지역으로 강제되기 때문에 따로 기본값으로 초기화가 되지 않는다고 이해했다.
객체 지향에서의 상속이란?
기존에 사용하던 부모 - 자식 클래스로 연관짓는 것 보단, 상위 - 하위 클래스 혹은 슈퍼 - 서브 클래스로 정의하는 것이 실제 객체지향에서의 상속의 의미와 부합한다.