티스토리 뷰

저번에는 추상화, 상속, 다형성, 캡슐화에 관한 4대 객체지향의 특성을 알아보았고, 이제 자바에서 객체 지향을 확장하는 키워드를 알아보겠습니다.

 

 

1) Abstract 

 

구현부가 없는 추상 메서드나 추상 클래스. 이것들을 왜 ? 정의할까요?

 

책에 있는 내용을 인용하자면,

 

동물이라는 클래스에 하위 고양이와 강아지가 있다고 가정하겠습니다. 그러면 강아지와 고양이가 울 때 멍멍, 야옹이라고 울겠죠? 그렇다면 동물 클래스는 어떻게 울어야할까요? 난해할 뿐만 아니라 답도 없습니다.

 

즉 이런 본질 클래스에는 추상이라는 키워드를 붙여서 추상 메서드를 재정의 하도록 하고, 본질 클래스는 쓰여지지 않도록하는데 객체로는 받을 수 있게 한 것이 자바의 기본 규칙입니다.

 

왜? 객체로는 받을 수 있게 할까요?

 

동물  동물객체 = new 동물( );

 

애초에 이렇게 쓰려고 만든게 아닙니다.

 

동물 배열[0] = new 고양이 ( );

동물 배열[1] = new 강아지 ( );

 

오버라이딩 된 메서드가 있으면 동물.cry( )를 통해 재사용성과 추상화 효과를 극대화 시킬 수 있습니다. 즉 본질 abstract 클래스 객체는 관상용/본질/개념/길잡이 입니다.

 

+ 생성자는 오버로딩을 통해 다형성을 넓히는 역할을 하죠! (협소한 내용이라 한줄로만... )

 

 

2) 클래스 생성 시의 실행 블록, static 블록

 

public class 동물{

 

      static int age = 0;

 

       static{

            System.out.println("동물 클래스 온!");

       }

 

}

 

 

main( ){

    System.out.println("main start!");

    System.out.println("동물.age");

}

 

결과는 어떻게 될까요?

 

결론부터 말하자면, 

 

main start!

동물 클래스 온!

0

 

그렇다면? static 블록은 main이 실행되고 출력되는 것인가요? 전혀 아닙니다.

static 블록은 단 한번 실행되는데 클래스의 정적 속성을 사용했을 때(위의 예시), 클래스의 정적 메서드를 사용했을 때, 클래스의 인스턴스를 최초로 만들 때 3가지의 경우 입니다.

 

그럼 메모리 관리도 생각을 해봐야 하는데, 위의 3가지 경우가 안뜬다면 애초에 만들어지지도 않는다는 소리입니다. 그렇다는 것은 스태틱 메모리에 형성이 처음에는 안된다는 소리죠.

 

그럼 왜? static 메모리에 바로 저장하지 않을까요?

메모리의 정석은 최대한 늦게 사용하고 빨리 반환하는 것입니다. 스태틱 메모리는 한번 올라가면 프로그램이 종료될 때 까지 내려가진 않지만 최대한 늦게 사용해 메모리 낭비를 줄이려고 합니다.

 

하지만 실무에서는 거의 안쓴다는.....

 

 

3) final

 

변하지 않는 거야! 라는 의미를 부여하는 키워드입니다.

클래스에 부여하면 부여한 클래스에 밑에는 상속을 할 수 없습니다. 변수에 부여하면 상수가 되며 상수가 된 녀석을 바꿀려고 하면 에러가 납니다. final 메서드는 오버라이딩 금지를 하는 역할을 하게 됩니다.

 

4) instance of

 

객체 참조 변수 instance of 클래스명 => 클래스 명에 객체 참조 변수의 클래스가 동격이거나 하위 클래스면 true 아니면 false를 반환합니다. 만약 상위 클래스로 선언된 변수에 동격이 아닌 하위 클래스가 들어있다고 해도 결과도 같습니다. 다만 LSP 설계 원칙이 위반 가능성이 있기에... 조심해야합니다.

 

5) package

 

다른 부서에서 개발된 같은 이름의 클래스가 있다면 프로그램은 혼동할 수 밖에 없습니다. 그러면 부서의 이름을 따로 넣어서 클래스를 만든다면 혼동이 없겠죠? 이러한 생각으로 나온 게 package입니다. (별개로 가즈아!)

 

6) interface, implements

 

인터페이스에 선언된 변수나 메서드에 디폴트 선언을 했을 때 변수에는 public static final이, 메서드에는 public abstract가 붙여집니다. 이 키워드는 위에 설명이 되어있으니 따로 설명하지 않겠습니다.

 

 이 밖에도 this, super 키워드를 통해 자기자신, 상위클래스에 접근하는 방법도 있습니다.

 

7) 더 나아가서

 

class 펭귄{

      void test( ){ ... }

}

 

펭귄 뽀로로 = new 펭귄 ( );

뽀로로.test( );

 

----------->

 

스택 메모리에는 어떻게 배치가 될까요?

 

스택 메모리에는 뽀로로.test( )와 메인 함수가 있을까요?

 

답은 NOOOOOOOOOO!

 

스택 메모리에는 펭귄.test( )와 메인 함수가 있습니다.

 

아니 서로 같은 것 아니냐? 말을 하실 수 있는데 완전 다릅니다.

뽀로로는 뭐죠? 인스턴스입니다. 펭귄은 클래스입니다. 여기까진 뭐 다른 것은 알겠는데 왜 생성한 객체 이름의 메서드가 아니라 클래스의 메서드가 스택메모리에 있는가에 대한 의구심이 생기실 것입니다.

 

만약 펭귄 인스턴스를 몇 백, 천개를 만든다고 한다면 메모리가 매우 부족한 현상이 발생할 수 있습니다. 자바 JVM에서는 이런 현상을 막기위해 갬체 멤버 메서드 test( )를 스태틱 영역에 단 하나만 보유하게 됩니다. 그리고 눈에 보이지는 않지만 test( ) 메서드를 호출할 때 객체 자신을 나타내는 this 객체 참조 변수를 넘깁니다. 즉 멤버속성이 다른 인스턴스를 찾아가도록 하는 것이죠.

 

이해가 안되신다면 메모리의 절약성을 위해 객체의 메서드는 스태틱 메모리에 단 하나로 저장된다라고 생각하시면 됩니다. 

 

여기까지 4강 자바가 확장한 객체 지향에 대해 알아봤습니다. 다음에는 SOLID 객체지향5원칙에 대해 알아보겠습니다!!!

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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 31
글 보관함