안녕하세요! 쏘코입니다.
오늘은 조금 까다로운 개념인 인스턴스와 static에 대해서 공부해보도록 하겠습니다.
목차
0. Instance
인스턴스는 클래스의 복제본이라고 할 수 있습니다.
클래스는 틀이고, 그 틀을 이용해서 찍어낸 냉장고가 바로 인스턴스라고 할 수 있죠.
클래스를 인스턴스로 만들기 위해서는 앞에 new를 붙여주면 됩니다.
OOP의 첫 시간에 만들었던 OthersOPP.java에서 우리는 FileWriter 클래스를 복제해서 f1에 담아서 사용했었습니다.
복제한 f1이 바로 인스턴스가 되는 것이죠.
지난 포스팅에서 만들었던 MyOOP에서는 delimiter라는 변수를 만들어서 변수를 바꿔가면서 출력했었습니다.
하지만 이 방법도 delimiter를 계속해서 바꿔야 하는 상황에서는 불편함이 따르게 됩니다.
delimiter 바꾸고 A 실행하고 delimiter 바꾸고 B 실행하고 ...
이걸 좀 더 스마트하게 사용하기 위해서 바로 인스턴스를 사용할 수 있습니다!!
new를 이용하여 Print라는 데이터형(클래스)를 가진 p1라는 이름의 인스턴스를 만듭니다.
그리고 인스턴스로 사용하기 위해 Print 클래스의 변수와 메소드들에서 static을 지워줍니다.
이제 delimiter를 설정하고 "----"이 필요한 인스턴스의 경우 p1.A() 혹은 p1.B() 형식으로 사용할 수 있습니다.
만약 delimiter가 "****"가 되어야 한다면 새롭게 p2라는 인스턴스를 만들고, delimiter를 설정한 후에
p2.A() 혹은 p2.B() 형식으로 사용하면 됩니다.
이렇게 내부적으로 다른 데이터를 유지함으로써 코드를 깔끔하게 만들고 중복을 제거할 수 있습니다.
이 내용은 충분히 어려운 내용이니 시간을 두고 천천히 이해하시면 됩니다.
클래스와 인스턴스의 차이를 명확하게 구분하실 수 있으시다면 여러분은 이미 자바 중급자가 되신겁니다!
1. Static
Instance를 배웠으니 이번에는 Static을 배워볼까요?!
StaticApp 클래스를 만들어줍니다.
그리고 StaticApp 클래스 위에 Foo라는 새로운 클래스를 하나 만들어줍니다.
그 안에는 static형태의 String 변수와 일반 String 변수가 하나씩 들어갑니다.
이제 main 안에서 Foo.classVar와 Foo.instanceVar를 출력하려고 시도해봅니다.
classVar는 사용이 가능하지만 instanceVar는 사용이 불가능합니다!
static이 붙으면 class의 변수/메소드가 되는 것이고, static이 붙지 않으면 instance의 변수/메소드가 되는 것이라고 배운 적이 있죠?
기억이 나지 않는다면 다시 한번 떠올려봅시다.
static이라는 키워드가 붙은 메소드는 클래스의 메소드입니다.
static이라는 키워드가 붙지 않은 메소드는 인스턴스의 메소드입니다.
아직도 기억이 나지 않으신다면 아래 링크를 참조하세요!
[생활코딩 자바] 16. 메소드 부록 - 접근제한자와 static
안녕하세요! 쏘코입니다. 오늘은 메소드를 배우면서 무턱대고 사용했던 Public과 Static에 대해서 간단하게 알아보도록 하겠습니다. (객체 지향을 모르는 지금 단계에서는 이해가 어려운 것이 당연
ssocoit.tistory.com
클래스에서 static 변수에 접근했기 때문에 classVar는 사용이 가능하고, 클래스에서 일반 변수(instance 변수)에 접근했기 때문에 instanceVar는 오류가 발생하게 됩니다.
빨간 밑줄 보이시죠?!
이번엔 클래스 메소드와 인스턴스 메소드를 만들어봅시다.
클래스 메소드에서는 classVar를 가져오는 것은 가능하지만 instanceVar를 가져오는 것은 불가능합니다.
instanceVar는 인스턴스에서만 사용이 가능합니다!
인스턴스 메소드에서는 classVar과 instanceVar를 모두 사용 가능합니다.
어.. 인스턴스 메소드에서 어떻게 클래스 변수를 사용할 수 있을까요?!
좀 더 엄밀하게 말하면 static이 붙은 요소는 한 클래스에 단 하나만 존재하는 것입니다.
instanceVar는 어느 한 클래스에 종속된 요소가 아니기 때문에 인스턴스가 만들어졌을 때만 정상적으로 사용할 수 있습니다.
따라서 클래스 메소드에서는 instanceVar를 사용할 수 없는 것이죠.
하지만 인스턴스 메소드에서는 하나뿐인 classVar과 instanceVar를 모두 사용해도 무방합니다.
인스턴스를 생성할 때 정상적으로 instanceVar가 만들어지고, classVar 역시 Foo 클래스에 이미 존재하기 때문입니다.
main 메소드 내에서 클래스 변수와 인스턴스 변수들을 다양하게 출력해 보았습니다.
각 인스턴스를 생성하고 그 인스턴스 내부에서 값을 바꾸면
classVar의 변경은 모든 인스턴스에 적용이 되는 반면
instanceVar의 변경은 특정 인스턴스에만 적용이 됩니다.
이것을 그림으로 표현하면 아래와 같습니다.
각 인스턴스는 인스턴스 변수와 인스턴스 메소드를 각자 가지고 있게 되고,
클래스 변수와 클래스 메소드는 class와 연결됩니다.
즉, f1에서 클래스 변수나 클래스 메소드를 변경하게 되면 연결된 그 클래스의 값이 변화하기 때문에 모든 인스턴스에서 바뀌게 되는 것이죠.
반면 인스턴스값은 각 인스턴스별로 다르게 메모리 공간을 가지고 있기 때문에 다른 인스턴스에 영향을 끼치지 않습니다.
좀 어려운 부분이지만, 예전 포스팅에서도 다뤘었기 때문에 그 때보다는 지금 더 잘 이해하실 수 있을 것이라 생각합니다.
클래스와 인스턴스를 구분하여 사용할 수 있다면 훨씬 더 자유자재로 요소들을 복제하고 다룰 수 있게 됩니다.
여러분들도 충분히 할 수 있어요!
다음 포스팅에서는 예전에 살짝 다뤘던 생성자와 this, 그리고 지금까지 배운 내용을 종합하여 활용하는 시간을 가져보도록 하겠습니다!
오늘도 읽어주셔서 감사합니다 :)
최근댓글