com.eomcs.oop.ex01.Exam0410.java

class Score가 main() 안에 있을 수도 있고

package com.eomcs.oop.ex01;

public class Exam0410 {
  
  public static void main(String[] args) {
    
    class Score {...};

main() 메서드가 소속되어 있는 public class Exam0410 안에 속해 있을 수도 있음

package com.eomcs.oop.ex01;

public class Exam0410 {
  
  class Score {...};
  
  public static void main(String[] args) {
    

또는 같은 파일에 속해 있을 수도 있음

package com.eomcs.oop.ex01;

class Score {...};

public class Exam0410 {
  
  public static void main(String[] args) {

근데 절대 잊지 말아야 할 게 있음
어디에 속해 있든

★ com.eomcs.oop.ex01.Exam0510.java
패키지 멤버 클래스와 중첩 클래스

클래스 블록과 .class 파일

03-OOP1 / 17 페이지

package com.eomcs;

public class A {
  class B {...};
  void m() {
    class C {...};
  }
}
class D {...};

소스 파일이랑 클래스 파일이랑 전혀 상관 없음
무조건 클래스 블록

메서드 안에 있는 변수를 "로컬 변수"라고 하듯이
메서드 안에 선언된 클래스를 "로컬 클래스"라고 한다.

로컬 클래스 : 메서드 안에 선언된 클래스

로컬 클래스인 경우는 '바깥쪽 클래스 이름'을 붙이고 '$' 하고 '몇 번째 로컬 클래스냐'

해당 이름을 가진 로컬 클래스 중에서 몇 번째냐

첫 번째면 1이 붙는다

A$1C.class

클래스 파일이 컴파일 될 때도 이 클래스가 어느 클래스 안에 선언됐던 클래스다 라는 걸 알려주기 위해서 바깥 클래스 이름이 붙고 로컬 클래스가 아닌 경우는 그냥 $하고 바로 해당 클래스 이름

A$B.class

A.class 파일이 만들어진다.

D.class 파일이 만들어진다.

소스파일 안에 클래스가 여러 개 있는데 상관없다. 각각 .class 만들어진다

보통 클래스가 특정 패키지에 종속된다. (package com.eomcs;)

package com.eomcs;

public class A {
  class B {...};
  void m() {
    class C {...};
  }
}
class D {...};

패키지 소속 클래스를 "패키지 멤버 클래스"라고 한다.

패키지 멤버 클래스 = Top level 클래스

다른 클래스 안에 있는 클래스를 "중첩 클래스"라고 한다.

중첩 클래스 (nested class)

중첩 클래스 중에서 메서드 안에 선언된 클래스를 "로컬 클래스"라고 한다.

로컬 클래스 : 메서드 안에 선언된 클래스

중첩 클래스 중에서 static이 안 붙은 클래스를 "non-static 중첩 클래스"라고 한다.

non-static 중첩 클래스 = inner class

• 패키지 멤버 클래스

• 중첩 클래스

• 로컬 클래스 (local class)
‐ 메서드 블록 안에 정의된 클래스
‐ 오직 그 메서드 블록 안에서만 사용된다.

• non-static 중첩 클래스 (inner class)
클래스 바로 밑에 선언된, 다른 메서드가 서로 공유할 수 있는, 인스턴스끼리 공유할 수 있는 인스턴스 중첩 클래스

소스파일이랑 클래스파일이랑 상관없음
소스파일 안에 들어 있는 클래스 블럭에 따라서 클래스파일이 만들어지고
클래스이름에 따라서 클래스파일 이름이 결정된다.
클래스 안에 클래스가 선언되어 있다고 하더라도
결국에는 각각의 .class로 컴파일이 된다

com.eomcs.oop.ex01.Score.java
패키지 클래스 = 패키지 멤버 클래스
다른 클래스 안에 선언되지 않고 별도로 선언된 클래스를 "패키지 클래스"라 부른다.
유지보수를 쉽게 하기 위해 보통 한 소스 파일에 한 클래스를 정의한다.

이전에 만든 Score 클래스는 main() 블록 안에 정의하였다. (로컬 클래스)
main() 블록 안에 정의한 클래스는 main() 블록 안에서만 사용할 수 있다.

이클립스가 컴파일을 대행
이클립스한테 대행해달라고 하지 말고 직접 컴파일해보자
이클립스는 컴파일러가 아니다!
우리를 대신해서 jdk가 설치된 폴더로 가서 javac.exe를 사용해서 컴파일을 해줄 뿐이지 이클립스가 컴파일러가 아니라는 걸 명심해라

cannot find symbol
클래스를 못 찾을 때 이 에러가 뜸

Score 클래스를 못 찾은 거

같은 폴더에 있어도 못 찾음
컴파일러는 다른 소스에 있는 클래스를 사용한다면 그 파일을 알려주지 않으면 못 찾는다고 에러 뜸

-sourcepath 라는 옵션을 통해서 0410이 사용하는 Score가 어느 소스파일에 있는지 어느 폴더에 있는지 알려줘라

javac -sourcepath src/main/java -encoding UTF-8 -d bin/main src/main/java/com/eomcs/oop/ex01/Exam0410.java

이클립스를 안 쓰면 소스파일이 뭘로 인코딩되었는지 알려줘야 되고,
혹시 이 클래스가 다른 클래스를 사용한다면 그 클래스가 있는 소스 파일 위치도 알려줘야 되고 등등 세세하게 알려줘야 됨
그걸 이클립스가 대신 해 준다.
통합 개발 환경 (IDE, integrated development environment)

com.eomcs.oop.ex01.Exam0510

static void m1()

static class B {}

static void m1() {
  B obj2 = new B();  // OK!!
}

class C {}

static void m1()

static void m1() {
  C obj3 = new C();  // 에러!!
}

m1은 static 멤버인데 C는 static이 안 붙었음
static 멤버는 non-static 멤버를 쓸 수 없다

m1도 static이고 B도 static
같은 static 끼리는 쓸 수 있음

다른 메서드에 선언된 로컬 클래스는

스태틱 중첩 클래스 (static nested class)
논-스태틱 중첩 클래스 (non-static nested class = inner class)

익명 클래스(anonymouse class)
‐ 클래스 이름이 없는 중첩 클래스이다.

static 멤버와 non-static 멤버간의 접근 규칙

03-OOP1 / 18 페이지

non-static 멤버.. instance 멤버 보다는 non-static 멤버 라고 한다.
static 멤버와 직관적으로 비교하기 위해서 non-static 멤버라고 표기함

static 멤버 ---- X ----> non-static 멤버
non-static 멤버를 사용하려면 반드시 인스턴스 주소를 지정해야 한다.

static 멤버 <---- O ---- non-static 멤버
non-static 멤버는 인스턴스 주소 없이 클래스 이름으로 접근 가능

com.eomcs.oop.ex01.X.java

com.eomcs.oop.ex01.Y.java

com.eomcs.oop.ex01.sub.X2.java

com.eomcs.oop.ex01.sub.Y2.java

com.eomcs.oop.ex01.Exam0610

public이 붙었을 때와 안 붙었을 때의 차이

com.eomcs.oop.ex01.Exam0610.java
public 클래스와 기본 클래스(default class = package private class)

패키지 멤버 클래스 : (default) vs public

03-OOP1 / 19 페이지

🔹 default class = package private class
비공개 패키지 멤버 클래스
같은 패키지에 소속된 클래스만이 이 클래스를 사용할 수 있다.

package com.eomcs.oop.ex01.sub;

// 패키지 멤버 클래스
// - 이 경우처럼 가능한 한 파일에 한 개의 클래스를 정의하라!
// - 그래야 클래스를 찾기 쉽다.
// - 즉 유지보수하기 쉽다.

// 비공개 패키지 멤버 클래스
// - 같은 패키지에 소속된 클래스만이 이 클래스를 사용할 수 있다.
class X2 {

}

X2 클래스는 public 이 아니다.
com.eomcs.oop.ex01.sub 패키지에 소속된 클래스만이 X2 클래스를 사용할 수 있다.
com.eomcs.oop.ex01 패키지의 클래스는 X2 클래스를 사용할 수 없다.
sub 안에 있는 클래스만이 X2 클래스를 사용할 수 있다.
상위 패키지는 하위 패키지에 있는 거 쓸 수 있고 그런 거 아님

🔹 public class = 공개 패키지 멤버 클래스
다른 패지키에도 공개한다

public이 안 붙으면 패키지 프라이빗 멤버
같은 패키지에 소속된 클래스만 사용할 수 있다.
그 패키지 안에서만 쓰이게 하고 싶으면 public을 붙이지 말기
다른 패키지에서도 쓰이게 하고 싶으면 public 붙여서 공개하기

com.eomcs.oop.ex01.Exam0710.java
import : 사용 전

다른 패키지에 있는 클래스를 사용할 때

현재 패키지를 기준으로 상대 경로를 사용할 수 없다.

반드시 절대 경로를 적는다.

정확하게 패키지 경로 전체를 다 적어야 됨
상대경로 안 됨!!!
반드시 절대경로
시작부터 끝까지 적어야 됨

이를 해결하기 위해 자바는 import 라는 명령을 제공한다.

import 명령은 package 명령 다음에 와야 한다.

import com.eomcs.oop.ex01.sub.Y2;

import 해놓으면 컴파일러가 경로를 자동으로 붙여준다.
컴파일할 때 자동으로 붙음

Y2 obj;

wildcard(*)

(주의!) 서브 패키지는 해당이 안된다.

가능한 wildcard(*)를 사용하지 않고 패키지명과 클래스명을 정확하게 명시한다.

가능한 import 문을 선언할 때 * 대신 구체적인 클래스명을 적어라!

com.eomcs.oop.ex01.Exam0740.java

java.lang 패키지에 있는 클래스는 패키지를 지정하지 않아도 된다.

java.lang 패키지에 소속된 클래스를 사용할 때는 패키지 이름을 명시하지 않아도 된다.

그 외 다른 모든 패키지의 클래스는 패키지명을 명시하지 않으면 컴파일 오류가 발생한다.

주의!
java.lang 패키지의 하위 패키지는 해당되지 않는다.
‐ 예) java.lang.annotation, java.lang.invoke

메서드 호출과 로컬 클래스 정의

03-OOP1 / 20 페이지

class A {
  public static void main(String[] args) {
    class Contact {
      String name;
      String tel;
    }
    Contact c = new Contact();
    c.name = "홍길동";
    c.tel = "010-1111-2222"
  }
}

컴파일하게 되면
메서드 안에 있는 클래스가 따로 떨어져 나온다
Contact.class ← 기계어 코드
A.class
컴파일될 때 Contact 클래스가 따로 분리되었기 때문에 A.class 파일에는 Contact 클래스가 없다. 컴파일된 코드에는 Contact 클래스가 없다.
A.class 파일에는 Contact를 사용하는 코드만 남아 있다.

main()을 호출할 때마다 Contact 클래스가 정의된다?
분리되었기 때문에 정의한 코드가 없음
메서드 안이나 클래스 안에 중첩 클래스가 있으면
메서드 안에 있으면 메서드가 호출될 때마다 클래스가 정의된다?
메서드를 10번 호출하면 클래스가 10번 정의된다?
호출될 때마다 클래스 파일이 컴파일되지는 않음
컴파일될 때 클래스 코드는 분리된다. 분리된 이후에 main() 메서드에는 클래스 코드가 없다.
그래서 메서드가 호출될 때마다 클래스가 정의된다는 건 말이 안 된다.

Exam0510.class 파일 보면 클래스를 사용한다고 되어 있지 클래스 자체는 없음
클래스는 별도로 파일로 분리됨

로컬 클래스 : 메서드 블록 안에 정의된 클래스
로컬 클래스는 정의된 메서드 블록 안에서만 사용된다.
그래서 static을 붙일 수 없다.
로컬 변수도 메서드 안에서만 사용할 수 있다.
로컬 변수 앞에도 static 못 붙인다.
static은 클래스 멤버에만 붙일 수 있다.

왜 메서드 안에 클래스를 선언했을까?
안에서만 쓰게끔 제한을 하고 싶었던 거
메서드 안에서만 그 클래스를 쓰고 메서드 밖에서는 모르길 원했던 거

다 사용 가능하게 하고 싶으면 바깥쪽에 선언

인스턴스가 없어도 쓸 수 있게 할 거냐
인스턴스가 있어야만 쓸 수 있게 할 거냐

oop.ex02

com.eomcs.oop.ex02.Exam0110.java
클래스에 데이터만 있음

com.eomcs.oop.ex02.Exam0120.java
그 데이터를 다루는 연산자도 추가
메서드를 이용하여 이 타입의 데이터를 다룰 수 있는 연산자를 정의한다

클래스 문법 - 사용자 정의 데이터 타입

로컬 변수는 자동 초기화 안 됨
초기화 안 시키면 컴파일할 때 에러남
The local variable 'a' may not have been initialized
인스턴스 변수는 에러 안 뜸
인스턴스 변수는 생성되면 기본값으로 초기화 됨

① 메모리 유형 설계
연속적으로 만들어짐
연속되지 않으면 못 만들어
연속적인 메모리가 없으면 못 만듦

Score 설계도에 따라 준비한 변수들
Score의 인스턴스(객체)

로컬변수는 자동으로 초기화가 안 됨
로컬변수 초기화 안 하면 컴파일 에러 발생함
인스턴스 변수는 생성되면 기본값으로 초기화되기 때문에 에러 안 남

② 데이터 구조를 설계하고 그 데이터를 다루는 연산자를 정의
그 데이터를 다루는 연산자 ⟹ 스태틱 메서드

메서드
설계 관점 → 연산자(operator)
언어 관점 → 메서드(method) = 함수(function)
설계 관점 → 메시지(message)

'메시지'라고 함
명령을 내린다 → 메시지를 전달하는 거 → 동사구

클래스에서
필드(변수) = Data 구조
메서드 = Data를 다루는 연산자
하나의 클래스에는 데이터와 그 데이터를 다루는 연산자를 함께 설계하는 거

이 데이터를 다루는 연산자인가
과연 이 클래스에 이 메서드에 있어야 하는가

이 타입의 데이터를 다루는 연산자를 정의한다.
메서드 : 데이터를 다루는 연산자를 정의할 때 사용하는 문법

new를 사용해서 메모리를 준비하고, 클래스에 선언된 그 메서드를 사용해서 그 메모리 값을 다룬다.

new를 사용해서 Score 설계도에 따라서 메모리를 준비
Score에 정의된 calculate 라는 연산자를 사용해서 Score 메모리 값을 다뤄라
그래서 메서드를 연산자라고 할 수 있다

메서드가 Score에 있다는 것은 Score 데이터를 다룬다는 뜻인데
남의 클래스의 데이터를 다룬다면 이 메서드가 여기 있을 이유가 없음
그 데이터를 다루는 클래스로 옮겨야지
이게 바로 리팩토링 기법 중 Move Method
한 번에 잘 짜는 게 아니라 짜놓고 다듬기 반복
소스 코드를 다듬는다 → 리팩토링

com.eomcs.oop.ex02.Exam0130.java
인스턴스 메서드

🔹 static 메서드

public static void calculate(Score score) {

클래스 메서드로 연산자를 정의하면
매번 파라미터로 인스턴스의 주소를 받아야 한다.

🔹 non-static 메서드 (인스턴스 메서드)

public void calculate() {
  this.sum = this.kor + this.eng + this.math;

static 지우기
‐ 파라미터 지우기
‐ 파라미터를 안 받는 대신, 내장 변수 this를 사용하면 된다.

인스턴스 주소를 메서드에 전달 → 메서드의 내장 변수 this에 저장됨

s.calculate();
↑ 인스턴스 주소를 메서드에 전달

a++;
피연산자 연산자
마치 변수 뒤에 연산자를 놓는 a++의 예와 비슷하다.
⟹ 기존의 연산자를 사용하는 방법과 더 비슷하다.

인스턴스 메서드를 사용하면 인스턴스 주소를 넘기기가 더 편하다.
메서드 호출 앞에다 둔다.
소스 코드의 목적을 이해하는데 더 직관적이다.

클래스 정의

클래스를 정의한다는 것은 "인스턴스 필드 선언" + "메서드 정의"한다는 것이다.

메모리 구조 설계 + 연산자 정의

데이터를 저장할 메모리 구조 설계 (인스턴스 필드 선언) + 새 데이터 유형을 다룰 연산자 정의 (메서드 정의)

modifier

final int i = 100; ← 상수
static ← 클래스 필드
private ← 내부에서만 쓰는 거

앞에 무엇을 첨가하느냐에 따라 뒤에 선언한 변수/메서드/클래스의 성질(특성)을 바꾼다.

변경을 가하는 명령 (modifier=변경자/한정자/제한자/제어자)

com.eomcs.oop.ex02.Exam0130

클래스 메서드 vs 인스턴스 메서드

com.eomcs.oop.ex02.Exam0110 ~ 130
사용자 정의 데이터
필드 선언 데이터를 저장할 메모리 구조 정의
메서드라는 문법을 사용해서 그 데이터를 다룰 연산자를 정의

120
static 메서드
연산자를 만드는 방법
static으로 연산자를 정의

130
non-static 메서드
연산자를 만드는 방법
non-static으로 연산자를 정의

세세하게 들어가지 말고 큰 그림, 윤곽 보기!
디테일한 건 나중 얘기!

인터넷 서점이라고 예를 들면

class Book
class Order
class Author

데이터를 다루는 class를 만들게 될 거

210부터는 서로 관련된 메서드를 묶는 용도

com.eomcs.oop.ex02.Exam0210.java
관련된 기능(메서드)을 묶어 분류하기 : 분류 전

메서드를 묶는 용도

setter getter도 연산자

메서드를 한 클래스를 다 넣으면 유지보수하기 힘듦
배열을 다루는 메소드는 ArrayList 클래스로 분리
연락처 정보 요청을 처리해주는 메서드는 ContactController 클래스로 분리
Todo 리스트 요청을 처리해주는 메서드는 TodoController 클래스로 분리
게시글 요청을 처리하는 메서드는 BoardController 클래스로 분리
이걸 TotalController 클래스 하나에 다 때려넣지 않고 분리시킴
한 클래스에 다 때려넣으면 유지보수가 어려움

클래스 이름 지을 때 명사 / 명사구 형태

계산 결과를 담을 변수를 밖에 선언하지 말고
Calculator 클래스 안에 result 변수 선언
static int result = 0;
메서드들의 작업 결과를 보관할 때 사용할 변수이다.
"스태틱 변수"라고도 부른다.
클래스에 소속된 변수. 클래스 변수. 스태틱 변수.
클래스 메서드. 스태틱 메서드.
인스턴스 변수 = 논-스태틱 변수
인스턴스 메서드 = 논-스태틱 메서드

클래스 변수는 new 명령으로 생성하지 않는다.
클래스가 메모리에 로딩될 때 자동으로 "Method Area" 영역에 생성된다.

계산 결과를 보관할 변수는 더이상 필요가 없다.
Calculator 내부에서 계산 결과를 관리한다.

결과를 알고 싶으면 Calculator.result

이게 "클래스 필드"의 필요성이다.

com.eomcs.oop.ex02.Exam0240.java
클래스 변수의 한계

클래스 변수는 클래스가 로딩될 때 한 번 생성된다.

클래스에 result 변수가 하나밖에 없기 때문에
두 개의 식을 동시에 계산할 수 없음

다른 식을 계산하기 전에 기존의 계산 결과를 갖고 있는 result 변수를 0으로 초기화시켜야 한다.

클래스 변수는 클래스가 로딩될 때 자동 생성됨
클래스 파일이 메모리에 올라오는 순간 자동 생성됨
클래스 변수는 다 같은 변수를 가리키는 거

계산기 결과를 따로 따로 유지하고 싶음
static으로 된 변수는 쓸 수 없음

그래서 등장한 게 non-static 변수 (인스턴스 변수)

com.eomcs.oop.ex02.Exam0250.java
인스턴스 변수

non-static 변수는 클래스가 로딩될 때 안 만들어짐
new 라는 명령으로 만들어진다.

인스턴스 변수는 클래스가 로딩될 때 만들어지지 않는다.

변수 선언 앞에 static이 붙지 않는다.

작업 결과를 개별적으로 관리하고 싶을 때 인스턴스 변수로 선언한다.

new 명령을 사용해서 만들어야 한다.

인스턴스 주소가 리턴된다

계산을 동시에

매번 인스턴스 주소를 전달하는 건 불편함

com.eomcs.oop.ex02.Exam0260.java

인스턴스 변수를 다룰 때는 인스턴스 메서드를 사용하는 것이 편하다!

인스턴스 메서드는 인스턴스의 주소를 this라는 내장 변수에 자동으로 받는다.

계산을 수행할 때 계산 결과를 보관할 메모리를 메서드 호출 앞에서 전달하라!

com.eomcs.oop.ex02.Exam0270.java

Calculator 클래스가 어딨는지 찾기 힘듦

plus, minus, multiple, divide 메서드는 인스턴스 변수를 사용함
this 라는 변수가 필요함
그래서 인스턴스 메서드로 만듦

abs는 파라미터가 주어지면 그걸 양수로 바꿔서 리턴

메서드에 static을 붙여야 할까요?
인스턴스에 들어 있는 변수를 사용해야 되는 상황이라면
인스턴스 주소가 필요하면 인스턴스 메서드
non-static으로 만들어라

인스턴스에 들어 있는 변수를 사용하지 않으면 static 붙이기

이 메서드가 인스턴스가 있어야 동작을 하는 거면 non-static

인스턴스에 있는 변수를 아무것도 안 쓰면 static
외부에서 값을 받아서 끝내는 건 static을 붙인다

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Math.html

Math 클래스 메서드 앞에는 다 static이 붙음
메서드 사용할 때 인스턴스 안 만들어도 된다는 거
인스턴스 변수를 쓰지 않는다

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Integer.html

static 메서드
클래스이름.
int result = Integer.compare(100, 120);
앞에 값이 뒤에 값보다 크면 1
앞에 값이 뒤에 값보다 작으면 -1
같으면 0
인스턴스 변수를 쓰지 않는 메서드
외부에서 값을 받아서 메서드
이 메서드에 static을 붙일 것인가 말 것인가
이 메서드가 인스턴스 변수를 쓰냐 안 쓰냐
쓰지 않으면 static
인스턴스 변수 쓰지도 않는데 static 안 붙이면 뭐라고 함
클래스이름으로 바로 호출하는 static 메서드
인스턴스 주소가 있어야만 호출하는 non-static
static 메서드는 인스턴스 만들 필요 없음

Integer i1 = new Integer(100);
Integer i2 = new Integer(120);

i1.
점 찍는 순간
S 없는 메서드 나옴
물론 S가 붙은 거 호출할 수 있음
아까는
지금은 S가 안 붙은 것도

클래스를 타입이라고 함

int result2 = i1.compare(100, 200); // 이렇게 쓰지 말기
static way → 스태틱의 방식으로

원래 static 메서드는 클래스 이름으로 호출해야 되는데
레퍼런스를 통해서 호출하더라도 컴파일 오류 안 남
문제가 없는데 잘못된 거
컴파일 오류는 안 띄우는데 바람직하지 않다고 경고는 띄움
레퍼런스로 static 메서드를 호출하는 일이 가끔 있기 때문
그것 때문에 문법을 약간 느슨하게 만듦
특별한 경우 아니면 레퍼런스로 호출하지 말기

메서드가 작업하는데 인스턴스 주소를 쓰는지

레퍼런스 주소가 있으면 인스턴스 메서드라고 오해함
static 메서드를 호출할 때는 쓸데없이 인스턴스 주소로 호출하지 말기
static 메서드는 클래스이름으로 쓰자

그래서 자바에서도 경고를 띄우는 거
static 메서드를 레퍼런스로 호출할 때는 경고를 띄운다
야 이러지마... 이거 static 메서드야... static 메서드 호출하는 방식으로 호출해...
static way 스태틱 방식으로

int result2 = Integer.compareTo(100); // 에러
100과 뭘 비교하라는 거야!!!

나 인스턴스 메서드야...
int result2 = i1.compareTo(i2);

static 메서드는 인스턴스를 사용하지 않는 메서드
파라미터로 받은 값만 사용함

non-static 메서드는 인스턴스를 사용하는 메서드
인스턴스에 있는 값과 파라미터 값을 가지고 작업을 하는 메서드

Calculator.java
메서드에 static 안 붙어 있음
인스턴스에 들어 있는 result 라는 변수를 써야 되기 때문에

abs() 메서드는 인스턴스 변수를 안 쓰니까 static 붙임
파라미터로 받은 값만 씀
특정 인스턴스를 사용하지 않기 때문에 static으로 함

메서드 앞에 static을 붙일까 말까 고민할 때 판단 기준이 뭐다?
이 메서드는 인스턴스에 들어 있는 변수를 쓰느냐 안 쓰느냐
쓴다면 non-static 메서드 (인스턴스 메서드)
안 쓴다면 static 메서드 (클래스 메서드)

‐ 추상 메서드
‐ 만들어진 메서드

Concrete Methods 콘크리트 메서드
만들어진 메서드, 완성된 메서드
추상 메서드가 아닌 완성된 메서드

지금까지 만든 게 concrete method (완성된 메서드)

완성되지 않은 메서드
abstract void m();

abstract 클래스만이 abstract 메서드를 가질 수 있다

인스턴스 변수를 직접 접근할 필요 없이 메서드를 통해서 접근한다.

  public int getResult() {
    return this.result;
  }

패키지가 달라지면 public을 붙여준다.

1) 관련 메서드를 클래스로 묶는다.
2) 메서드에서 계산한 결과를 클래스 변수에 저장한다.
3) 인스턴스 변수로 바꿔서 결과를 개별적으로 관리한다.
4) 인스턴스 메서드로 바꿔서 인스턴스 주소를 this 변수에 받는다.
5) 클래스를 별도의 소스 파일로 분리한다.
6) 클래스를 패키지로 분류한다.

com.eomcs.oop.ex03.Exam0110.java
인스턴스 변수 (인스턴스 필드, non-static)

new 라는 명령으로 만들어진다.

A obj1 = new A();
A 클래스에서 변수 선언 명령을 실행한다.
주의! 메서드 정의는 실행하지 않는다!
메서드 정의는 new 명령의 실행 대상이 아니다.

인스턴스가 생성될 때 만들어지는 v1, v2를 "인스턴스 변수"라 부른다.
인스턴스는 변수들을 통칭해서 부르는 거고
인스턴스 안에 있는 각각의 변수를 가리킬 때는 "인스턴스 필드"

인스턴스 변수는 new 명령을 실행할 때 마다 생성되기 때문에
각각 구분되는 개별 데이터를 저장할 때 사용한다.

com.eomcs.oop.ex03.Exam0120.java

Score s1 = new Score();
Score 설계도에 선언된 변수들을 Heap에 준비한다.

NullPointerException ← 레퍼런스에 주소가 안 들어 있다는 거

접근하려면 주소가 있어야 됨

com.eomcs.oop.ex03.Exam0130.java
클래스 변수 (스태틱 변수, static)

클래스 변수는 new 명령으로 생성하지 않는다.
클래스가 메모리에 로딩될 때 자동으로 "Method Area" 영역에 생성된다.

클래스를 로딩하는 순간 자동 생성된다.
클래스와 함께 "Method Area" 영역에 존재한다.

static이 붙은 변수이기 때문에 "스태틱 변수"라고도 부른다.

$ java -cp bin/main com.eomcs.oop.ex03.Exam0130
① JVM으로 Exam0130.class 실행
② (Method Area) Exam0130 클래스 파일을 메모리에 올린다(loading).
③ main() 호출
④ (JVM Stack) main() 메서드의 로컬 변수 준비
⑤ (Method Area) A.class가 로딩된다. (클래스 로딩)
클래스를 사용하는 순간 클래스가 로딩된다.
⑥ A의 스태틱 변수 준비
v1, v2가 만들어진다.
기본값으로 초기화됨
v1 = 0
v1 = false
⑦ A.v1 = 100;
⑧ A.v2 = true;

클래스 변수는 클래스가 로딩될 때 한 번만 만들어진다.

0개의 댓글