문법/Java

[Java] 추상화(Abstraction)

jungmin.park 2023. 10. 31. 10:26

추상화 : 구체적인 것을 분해해서 관찰자가 관심 있는 특성만 가지고 재조합하는 것

 

클래스(class) : 같은 특성을 지닌 여러 객체를 총칭하는 집합의 개념

객체(instance) : 유일무이(unique)한 사물, 클래스의 인스턴스

 

클래스:객체 = 사람:김연아 = 사람:홍길동

 

ex) 사람 클래스를 만들기 위해 주변에 보이는 공통적인 특성

 시력, 몸무게, 혈액형, 키, 나이 등 명사로 표현되는 것 -> 속성(값)

 먹다, 자다, 일하다 , 침 뱉다. -> 기능 행위(함수)

class 사람 {
       float 시력;
       int 몸무게;
       int 키;
       void 먹다{...}
       void 일하다{...}

 

만약 애플리케이션을 만들었는데 사람에 대한 클래스를 이용해 객체를 만들때 필요없는 속성과 기능들이 있을 것이다.

병원 애플리케이션과 은행 애플리케이션으로 예시를 들어보면

병원 어플리케이션 은행 어플리케이션
class 사람 { class 사람 {
       float 시력;
       int 몸무게;
       int 키;
       int 나이;
       String 직업;
       String 연봉;
       float 시력;
       int 몸무게;
       int 키;
       int 나이;
       String 직업;
       String 연봉;
       void 먹다{...}
       void 일하다{...}
       void 입금하다{...}
       void 출금하다{...}
       void 먹다{...}
       void 일하다{...}
       void 입금하다{...}
       void 출금하다{...}

 

추상화는 모델링이다. 라고 하는데 모델은 추상화를 통해 실제 사물을 단순하게 묘사하는 것

 

추상화의 개념을 넓게 보자면

  • 상속을 통한 추상화, 구체화
  • 인터페이스를 통한 추상화
  • 다형성을 통한 추상화

 

클래스 객체_참조_변수 =  new 클래스();

Person 학생 = new Person();

 

 

미키마우스 제리
성명 : 미키마우스
국적 : 미국
나이 : 87
종교 : 무교
신장 : 70cm
체중 : 11.5 kg
성명 : 제리
국적 : 미국
나이: 75
종교 : 기독교
친구 : 톰
여자친구: null
달리다()
먹다()
휘파람 불다()
데이트하다()
울다()
달리다()
먹다()
장난치다()

추상화

성명
나이
달리다()
먹다
public class Mouse{
	public String name;
    public int age;
    
    public void sing(){
    	System.out.println(name + "찍찍"!!");
    }​

 

public class MouseDriver{
	public static void main(String[] args){
    	Mouse mickey = new Mouse();
        mickey.name = "미키";
        mickey.age = 85;
        mickey.countOfTail = 1;
        
        mickey.sing();
        
        Mouse jerry = new Mouse();
        
        jerry.name = "제리";
        jerry.age = 73;
        jerry.countOfTail = 1;
        
        jerry.sing()
   }
}

main 메서드 실행되기 직전에 메모리

스태틱 영역 

함수 정보, 속성 정보만 저장
name
age
sing()
 

이 때 name, age 속성은 Mouse 클래스에 속한 속성이 아닌 Mouse 객체에 속한 속성이기 때문에 객체가 생성되야만 값을 저장하기 위해 스태틱 영역이 아닌 힙 영역에 할당된다.

 


Static 

  • 스태틱 영역에 올라간 정보는 main() 메서드가 시작되기 전에 올라가서 main() 메서드가 종료된 후에 내려올 정도로 스태틱 영역에 고정되어 있다.
  • 다음과 같은 질문을 던져본다.
    • 미키마우스의 꼬리는 몇개인가?
    • 제리의 꼬리는 몇개인가?
    • 쥐의 꼬리는 몇개인가?

-> 답은 1개이다.

만약 이것을 static 이 아닌 객체의 속성으로 구현하게 된다면 각각 메모리에 하나씩 잡히게 된다.

Mouse
name
꼬리 
Mouse(micky)
name : micky
꼬리: 1 
Mouse(jerry)
name: jerry
꼬리: 1

스태틱을 구현하게 된다면 스태틱 영역에 단 하나의 저장 공간을 갖게 되는 것이다.

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

 

클래스로 선언된 속성은 객체.속성이 아닌 Mouse.countOfTail 로 접근이 가능하다

 

클래스 멤버 = static 멤버 = 정적 멤버

객체 멤버 = 인스턴스 멤버

 

정적 멤버 속성은 클래스의 모든 객체들이 같은 값을 가질 때 사용하는 것이 정석.

또한 정적 멤버/메소드는 객체가 아닌 클래스에 속해 있으며, 클래스는 JVM 구동 시 메모리의 스태틱 영역에 바로 배치되기 때문에 객체의 존재 여부와 상관없이 쓸 수 있다.

 

정적 변수에 대한 접근 지정자 접근 메소드(getter)와 설정 메서드(setter)로 사용되어진다.

 

정적 속성은 스태틱 영역에 클래스가 배치될 때 클래스 내부에 메모리 공간을 확보하고 있지만

객체 속성(이름, 나이)는 속성명만 있고 실제 메모리 공간은 확보해 놓지 않는다. 힙 영역에 객체가 생성되면 그때 각 객체안에 멤버 속성을 위한 메모리 공간이 할당된다.

 

  non - static 멤버 = 객체용 멤버 static 멤버 = 클래스용 멤버
공간적 특성 멤버들은 객체마다 독립적으로 별도 존재 클래스 당 하나마 생성/ 객체 내부가 아닌 별도 공간에 생성
시간적 특성 속성과 메소드는 객체 생성 후 사용 가능 클래스가 로딩될 때 공간 할당
객체가 사라져도 멤버는 사라지지 않음
프로그램 종료 시 사라짐
공유 특성 멤버들은 다른 객체에 의해 공유되지 않음(비공유적) 동일한 클래스의 모든 객체에 의해 공유
class StaticSample{
	int n;
    void g() {...}
    static int m;
    static void f() {...}
  • 함수 g()는 non-static이기 때문에 어떤 객체가 호출했는지 암 -> this 사용가능
  • 속성 m과 함수 f()는 static 이기 때문에 누가 호출했는지 모름 -> this 사용 불가 / 클래스이름.m 으로 호출 해야함

 

static 메소드의 제약조건

  • static 메소드는 non-static 멤버(일반 객체 맴버)에 접근할 수 없음
    • 객체가 생성되지 않는 상황에서 해당 메소드는 실행 될 수 없기 때문
  • non-static 메소드는 static 멤버 사용 가능
    • 모든 객체가 공유하기 때문
  • this 사용 불가
    • 어떤 객체가 가르키는 지 this 래퍼런스를 사용 할 수 없음.

 

지역 변수 vs 멤버 변수

지역 변수 : 스택 영역에 저장 / 한 지역에서만 쓰는 변수로 초기화가 반드시 필요하다. 초기화가 없으면 쓰레기 값을 가짐 / 한 지역에서 사용되고 소멸되기 때문에 초기화 하는 것이 논리적으로 맞다.

멤버 변수 : 객체 메서드가 공유하는 변수 / 초기화 없이 자동으로 초기화가 된다.