13일차(4)/java(5) : class, static
- 새 프로젝트 안에 패키지 2개 만들기 (test.main / test.mypac)
- heap 영역 안에 만들어지는 것은 객체이고,
이 객체는 저장소(field) + 기능(method) 으로 이루어져 있다.
- class 란 객체의 설계도 역할을 하며, 객체가 어떤 필드와 어떤 메소드를 가질지 설계한다!
- 지금까지 사용한 메소드 length, replace, startWith ... 등은
전부 이미 클래스로 설계가 되어있기 때문에 그런 기능을 가지는 것!
- 아래에서는 설계도를 직접 만들어서 원하는 필드, 메소드를 가지는 객체를 만들어볼 예정!
→ 설계도를 어떻게 만드는지 / 만든 설계도로 객체를 어떻게 만드는지 실습
- MainClass 파일은 메인메소드를 만들기위해서 만들었던 클래스. java에서 메소드는 단독으로 존재할 수 없다.
- javascript에서는 함수가 단독으로 존재할 수 있었다.
→ 하지만 자바에서는 메소드를 단독으로 만들 수 없다. 반드시 클래스 안에 정의해야 한다!
- 그 클래스를 사용해 객체를 만들었을 때 어떤 메소드와 어떤 필드를 가질지 설계하고,
설계된 대로 객체를 실체화시키는 연습을 하기
- '설계도'와 '실체'를 별도로 생각하기! ex) 아이폰의 설계도 / 아이폰
mypac 안에 <Car> class 생성
package test.mypac;
/*
* class의 역할
*
* 1. 객체의 설계도 역할
* 2. data type 역할
* 3. static 필드와 메소드를 포함하는 역할
*/
public class Car {
//저장소(field)
public String name;
//달리는 기능(method)
public void drive() {
/*
* 이 클래스로 객체가 생성된다면 바로 그 객체의 참조값을 가리키는 예약어가 this이다.
*/
System.out.println(this.name+" 이(가) 달려요!");
}
//멈추는 기능(method)
public void stop() {
System.out.println("멈춰요!");
}
}
<MainClass01>
package test.main;
import test.mypac.Car;
public class MainClass01 {
public static void main(String[] args) {
//test.mypac 패키지에 있는 Car 클래스로 객체를 생성해서 참조값을 얻어냈지만 사용하지 않고 버리기
new Car();
//test.mypac 패키지에 있는 Car 클래스로 객체를 생성해서 참조값을 얻어내서 car1이라는 지역변수에 담기
Car car1=new Car();
//필드에 값 대입하기
car1.name="소나타";
//메소드 호출하기
car1.drive();
car1.stop();
Car car2=new Car();
car2.name="람보르기니";
car2.drive();
car2.stop();
}
}
- new(예약어)에서 객체가 만들어진다. (new 총 3번)
→ 1은 버려지고 (참조값을 불러왔지만 어디에도 대입하지 않음)
2는 car1이라는 객체에 값이 들어감
3은 car3이라는 객체에 값이 들어감
[ class의 역할 ]
1. 객체의 설계도 역할
2. data type 역할
3. static 필드와 메소드를 포함하는 역할
- Car이라는 클래스를 만들어 MainClass에서 import시켜 실행시켜보기!
- Car이라는 클래스는 name이라는 필드와 drive, stop 이라는 메소드를 가진다.
(car이라는 가상의 설계도를 만들어볼 것)
[자동 import 하는 방법 2가지]
1) 클래스명을 작성하고 ctrl+space
2) ctrl+shift+o
- import는 패키지가 다르면 꼭 해야하는 것!
상단에 패키지명.폴더명.클래스명 으로 표기하면 된다.

- javascript에서는 function drive(){} 비슷한 느낌
- javascript에서는 함수가 단독으로 존재할 수 있고 drive() 로 호출이 가능했음.
but java에서는 함수가 단독으로 존재하지 못함. class로 만들어주어야 한다.

- Car 이라는 클래스 안에 가상의 달리는 기능 drive를 만들었다고 하자.
객체를 사용해서 heap 영역의 drive라는 기능을 불러올 수 있다.
→ 사물함 키 값만 가지고 있으면 언제든 drive라는 기능을 사용할 수 있다.

name: 필드, 저장소
drive/stop: 메소드, 기능
- 클래스란 설계도이기 때문에, 동일한 저장소와 기능을 여러 개 만들 수도 있다. 설계도니까!
객체를 원하는만큼 만들어낼 수 있다.(이 때, 호출할 때마다 다른 사물함 key를 가진다.)
- 키만 있으면 언제든 저장소 참조와 기능 사용이 가능.

- new 클래스(); : 클래스의 호출은 new라는 예약어와 함께 사용한다!
- class 자체가 데이터 타입의 역할도 한다.
→ Car 클래스로 변수를 새로 만든다면 새로 만든 변수의 데이터타입은 Car type 이다.
- car1 변수를 보면 사전에 만든 필드(name), 메소드(drive, stop) 를 갖고있는 것을 볼 수 있다.

Car car1=new Car(); : Car() 를 호출하여 리턴값을 car1이라는 변수에 대입해준 상태
- 디버깅해보면 name이라는 필드에 null이 들어있다.
(public string name; 이라고 필드를 선언만 하고 값을 넣어두지 않았기 때문에)
- 지역변수는 선언만 하면 만들어지지도 않지만, 필드는 선언만 해도 null이 들어간다.

car1.name="소나타";
- 한줄을 추가해 준 후에 다시 디버깅해보면 null이었던 곳에 값이 들어가는 것을 볼 수 있다!

- 필드에 있는 값을 참조할 때는 this 사용

- 같은설계도로 실행했는데, 내용이 다르게 나온다.
- 동일한 설계도라도 필드에 있는 내용이 다르기 때문에 결과가 다르게 나온 것.
→ 필드의 내용이 다르면 메소드의 동작이 다르게 나타날 수 있다.
Q) 객체의 필드와 메소드를 활용해서 프로그래밍을 하는데
동일한 기능을 가진 객체가 여러 개 있을 필요가 있을까??
A) 객체에 한명의 회원정보 / 하나의 글정보 / 하나의 상품정보 등을 담을 예정
만약 회원이 여러명이고, 글이 여러개고, 상품이 여러개라면?
→ 객체 하나만 생성해서는 안된다. 객체가 회원의 개수만큼 필요할 것!
→ 동일한 기능을 가진 여러개의 객체가 필요한 이유이다.

- java의 '객체'를 javascript에서 대응시킨다면 object라고 생각하면 된다.
car = {name:"xxx", drive:function(){}, stop:function(){} }; 인 것!

- this라는 예약어는 heap영역의 객체 안에서 자기자신의 참조값을 가리키는 것이다.
똑같은 클래스로 객체를 생성했다면 객체마다 똑같은 name이라는 필드가 있다.
- this.name이란 객체 안에서 자신의 참조값을 가리키는 것으로 위 그림에서는 24, 25에 해당한다.
- 설계 단계에서는 this가 무엇을 가리킬 것인지 모른다.

- 각각의 객체마다 this가 다르다. this는 참조값이다!
- 28번 사물함 안에서 this는 28, this.name="소나타"
29번 사물함 안에서 this는 29, this.name="람보르기니"
static method ↔ non-static method
- 어떤 파일을 run 하려면 아주 특별한 static main method 가 필요하다. (static: 고정된, 정적인)
run하면 해당 main method 부터 실행이 시작된다.
- static 메소드와 non-static 메소드는 실행 방법이 다르다.
- static 메소드의 기능, non-static 메소드와의 차이 구분
test.main 안에 MainClass02 / test.mypac 안에 MyUtil이라는 새 클래스 생성.
<MyUtil>
package test.mypac;
public class MyUtil {
//필드
public static String version;
//메소드
public static void send() {
System.out.println("전송합니다.");
}
}
<MainClass02>
package test.main;
import test.mypac.MyUtil;
public class MainClass02 {
public static void main(String[] args) {
//static 메소드는 클래스명에 . 찍어서 바로 호출할 수 있다.
MyUtil.send();
//static 필드는 클래스명에 . 찍어서 바로 호출할 수 있다.
MyUtil.version="1.0";
}
}
- static field 와 static method를 가진 클래스 MyUtil의 사용법

- MyUtil은 static field 와 static method를 가진다.(아이콘 위에 S가 붙어있다)
각각 string 타입, void 로 정의되어 있다.

- Car은 car1이라는 변수에 클래스를 대입해두고 그 참조값(key)을 사용해서 호출한다.
- 하지만 MyUtil은 클래스명에 . 을 찍어서 바로 쓴다.
바로 static때문에!! static 예약어가 있으면 new를 쓸 필요가 없다.
- 필드와 메소드를 선언할 때 static이 붙었느냐 안붙었느냐는 큰 차이가 있다!!
* static, stack, heap의 3가지 영역이 존재한다고 생각해야 한다.
static | stack | heap |
static 자원이 만들어지는 영역 | 지역변수가 만들어지는 영역 | 객체가 만들어지는 영역 |
class 안에 static 필드, static 메소드가 만들어진 채로 클래스가 올라간다. 클래스명으로 구분되는 영역 |
객체 안에 필드, 메소드가 만들어지고 참조값(사물함 번호)로 구분되는 영역 |
- static 영역은 객체와 상관이 없다.
여러개의 클래스가 올라가게 된다. (각각의 클래스는 클래스명으로 구분된다.)
- heap은 실체(객체)를 만들어낸 다음, 그 실체를 참조하는 것이다.
new로 새롭게 호출할 때마다 객체를 여러 번 만들어낸다.(똑같이 호출하나 다른 참조값을 가지는 객체를 만듦!)
ex) static에서는 MyUtil.XX 로 찾는다. (바로 클래스명으로!)
heap영역은 참조값 대입해서 car1.XX, car2.XX, ... (car1에는 참조값이 대입된다)
- 필드를 만들거나 메소드를 만들 때 static을 붙여주면 클래스와함께 static영역에 올라간다.

- heap영역에서 불러오는 모양! (24, 25라는 참조값을 사용해서 접근한다.)
- 지역변수는 stack영역에서 만들어짐. 참조값을 지역변수에 담아두고 필요할때 쓰는 것.
- static이냐, non-static이냐에 따라 사용법이 다르다. 잘 구분하기!

- static은 번호로 구분되는 사물함이 아니다. 당연히 클래스명으로 접근한다. (A, MyUtil을 사용해서 접근)
(static은 오직 하나, only one, single이라는 의미도 있다.)
- static이라는 메소드를 만들면 그 메소드는 오직 하나밖에 만들어지지않는다.
(왜냐하면 클래스당 하나씩만 올라가니까!)
- MyUtil안에는 version이란 이름의 필드와 send라는 이름의 메소드가 있다.
- static 영역에 만들어진 필드, 메소드를 사용할때에는 class명을 사용해서 접근한다.
'국비교육(22-23)' 카테고리의 다른 글
14일차(1)/java(7) : class / static, non-static / eclipse에서 git으로 관리하기 (0) | 2022.10.25 |
---|---|
13일차(5)/java(6) : 객체의 field, method 호출 실습 (0) | 2022.10.24 |
13일차(3)/java(4) : Operator (0) | 2022.10.24 |
13일차(2)/java(3) : DataType, 객체지향 언어 (0) | 2022.10.24 |
13일차(1)/java(2) : eclipse export, import, delete (0) | 2022.10.24 |