[Java] Class

jy9922·2022년 7월 11일
0

Java

목록 보기
2/13
post-thumbnail

💡Java language spec

→ 자바스크립트와 거의 유사하다.

변수

  • 변수를 만들 때 식별자를 사용한다.
  • 식별자에 대한 Naming Rule은 동일하다.
  • Naming Convention 역시 유사하다.
  • 정적 type언어라서 값 뿐만 아니라 변수에도 data type이 붙는다. (할당 전에 반드시 명시)

💡데이터 타입(data type)

Primitive type (원시타입) - 8개

(정수형)

  • byte - 1byte
  • short - 2byte
  • int - 4byte (정수 기본 타입)
    cpu가 memory를 읽을 때 4byte 단위로 읽기 때문에 속도면에서 이점이 있다.( -21억 ~ +21억 )
  • long - 8byte

(실수형)

  • float - 4byte
  • double - 8byte (실수 기본 타입)

(문자형)

  • char - 2byte

(논리형)

  • boolean - 1byte (*다른 값으로 변환 안된다, true => 1 (x) )

reference type

  • class (ADT, 추상 데이터 타입) (사용자가 원하는대로 만들 수 있다)

상수

변수 앞에 final이 붙으면 상수가 된다.

final int MY_SCORE = 100;
  1. 재할당이 불가하다.
  2. 선언과 동시에 초기화가 이루어져야 한다.
  3. 상수는 기본적으로 모두 대문자로 작성해야 된다.
    (naming convention은 snake case를 따른다)

형변환 (Type casting)

묵시적 형 변환 & 명시적 형 변환

Type casting => " ( ) " 괄호를 이용해서 형변환을 한다

💡Class

✔️ class의 구조

  • fields, 생성자(constructors), methods의 순서로 구성한다.

✔️ constructor(생성자)

  • class 내부에 생성자를 작성할 때 생성자의 이름은 class의 이름과 동일해야 한다.
  • 인스턴스를 생성하고 초기화하려는 목적으로 사용한다.
  • method는 반드시 이름 앞에 return type을 기술해야 한다.
    (생성자는 return 구문이 존재하지 않는다)
  • default constructor 외에 여러개의 생성자가 존재할 수 있다.
    (default constructor는 없으면 자동 삽입된다)

✔️ class의 사용 목적

  1. 객체 모델링의 수단
  2. instance를 파생 ( new 키워드 )
  3. ADT(abstract data type) -> reference data type
package com.kakao.test;
public class Student{
	// fields (변수들)
    String stuName; //string -> class -> reference type -> 문자열
    String stuNum; //학번 - 연산을 하지 않는 숫자는 문자열 처리가 좋다
    int stuAge; // 나이 - 숫자
    String stuDept; // 학과
    
    Student(){
    
    }
    
    // methods (함수들)
    public static void main(String[] args){
   		System.out.println("안녕하세요");
class {
	1. fields
    2. constructor
    3. methods
 }

💡JVM이 관리하는 Memory 구조

  1. Register
    프로그램의 실행 포인터를 관리하는 영역
    (JVM에 의해서만 관리된다)
  2. Runtime constant pool
    정해져 있는(만들어진) 상수값들이 여기에서 관리된다.

  1. Method Area
  • class 자체에 대한 정보가 들어간다.
  • 해당 class를 처음 사용하는 시점에 memory에 올라간다.
    1 ) class variable - class 안의 static field
    2 ) method의 실행 bytecode
  1. Heap
  • new 키워드를 통해 만들어진 모든 인스턴스가 관리되는 영역이다.
  • String pool도 가지고 있어 문자열을 관리한다.
  1. Call Stack
  • 메서드가 호출되면 해당 메서드를 위한 공간이 stack에 잡히고 관리되는 영역이다.
  • 스택 구조로 아래서부터 일정양의 메서드가 잡히게 된다.
    1 ) 메서드 안에서 사용하는 local 변수

코드와 JVM Memory 구조 설명

  • 코드가 실행되면 method area에 Student class에 대한 정보가 들어간다.
    (필드, 메소드, constructor의 명세에 대한 정보가 들어간다)
  • main( ) 메소드가 stack에 들어간다.
    (지역변수가 들어감)
  • new 키워드가 등장함과 동시에 heap에 인스턴스가 생성된다.
    (거기에 class에서 만들어놓은 fields에 대한 공간이 instance 내부에 잡힌다)
  • stu 변수는 stack에 존재하고 Heap에 존재하는 instance를 참초하고 있다.
    이는 stack에 들어가게 되고, 이때 stu는 heap에 있는 instance를 참조한다.
  • stu.stuName은 홍길동이 들어가게 된다.
  • main 메소드가 끝나면 stack에서 pop( )한다.
  • garbage collector가 heap에서 참조되고 있지 않은 인스턴스를 찾아서 정리한다.
  • method area가 비워진다.

Static

field variable

  • instance variable, instance 내에 공간이 생긴다.

class variable

  • class variable에 해당되며, method area 안 class 정보 안에 별도의 공간이 생성된다.
  • class에 대한 정보가 method area에 올라갈 때 생성된다.
  • 모든 instance에 의해서 공유되는 field이다.
  • static은 인스턴스가 없어도 사용이 가능하다.

코드로 보는 static

package com.kakao.test;

public class Student {
	
	// fields (변수들)
	// instance variable -> instance내에 공간이 생성
	String stuName; // String -> class -> reference type -> 문자열
	String stuNum; // 학번 - 연산을 하지 않는 숫자는 문자열처리가 좋다
	
	// class variable => method area 안에 class 정보 안에 공간이 생성
    //                   class에 대한 정보가 method area에 올라갈때 생성
	//                   모든 instance에 의해서 공유되는 field
	static String univName;
	
	// 생성자들
	// 인스턴스를 초기화해주는 역할
	// default constructor
	Student(){
		
	}
	
	// methods (함수들)
	public String getName() { // instance method
		return this.stuName;
	}
	public static String getUnivName() { // class method
		return univName;
	}
	
	public static void main(String[] args) {
		Student stu = new Student(); // instance 생성
		// . operator (. 연산자)
		stu.stuName = "홍길동"; // 문자열은 ", 문자는 ' 구분이 필요함
		stu.univName = "한국대학교"; // 가능
		Student.univName = "미국대학교"; // 가능
		
		stu.getName();
		stu.getUnivName();
		Student.getUnivName();		
	}
}

  1. method area에 class에 대한 정보가 들어간다.
  2. univName에 대한 공간이 따로 생긴다.
    (static 키워드가 붙음)
  3. getName( )과 getUnivName( )에 대한 메소드 실행 코드가 들어간다.
  4. main( )에 대한 메소드 실행 코드가 들어간다.
  5. stack에 main이 들어간다.
  6. new라는 키워드로 인스턴스가 생성되면 그와 동시에 heap에 인스턴스에 대한 정보들이 들어간다.
  7. static 키워드가 붙은 univName도 실제로 공간을 가리키고 있다.
  8. 단, heap에 있는 univName은 Method Area에 있는 univName을 가리키고 있다.
  9. getName 메소드에 대한 실행 포인트가 들어간다. 즉, method를 인스턴스가 들고 있지 않다.
  10. getUnivName 메소드에 대한 실행 포인트가 들어간다. 이 또한 method를 인스턴스가 직접 들고있지 않다.

Static block

  • default constructor를 사용하더라도 자동으로 주입시키는 것보다 직접 기재하는 것을 권장한다.
  • main( )이 실행되기 직전에 프로그램에서 필요한 다른 library 등을 loading할 필요가 있을 때 사용된다.
package lecture0712;
public class MyClass{
	int aaa;
    static int bbb = staticCall();
    public MyClass(){
    }
    static {
    	System.out.println("static block");
    }
    static int staticCall(){
    	System.out.println("호출되었어요");
        return 100;
    }
    public static void main(String[] args) {
    System.out.println("main 호출");
    }
}

다음 코드의 출력 순서는 어떻게 될까?

package com.kakao.test;

public class Student {
	static int a = staticCall("1번"); // 첫번째로 찍힘
	// static area에 공간 할당이 먼저 이루어짐 
	int b = staticCall("2번"); // 
	// 인스턴스가 만들어져야 작동된다
	
	public static int staticCall(String msg) {
		System.out.println(msg);
		return 100;
	}
	
	// 인스턴스 초기화
    // 생성자에게 초기화하기 위해서는 
    // b가 먼저 생성되어야 하므로 
    // 2번이 먼저 출력된다
	// 공간이 만들어지면 초기화 할 수 있다
	public Student() {
		this.b = staticCall("3번");
	}
	
	public static void main(String[] args) {
		System.out.println("4번");
		int c= staticCall("5번"); 
		Student s = new Student();
	}
}

// 1번 -> 4번 -> 5번 -> 2번 -> 3번

잠깐! 주의해야할 코드

위와 같이 k를 전역변수로 생각해 다음과 같이 코드를 작성하면 안된다.
👌k는 instance variable!

class variable & instance variable

class variable

  • static variable : 모든 instance가 공유하는 공유 변수

instance variable

  • 일반 field : 독립적인 공간에 생성 ( Heap )

Constructor (생성자)

  • 인스턴스를 생성하고 초기화하려는 목적으로 사용한다.
  • Java의 모든 class는 적어도 한 개 이상의 생성자를 가진다.
    만약 constructor을 명시적으로 작성하지 않으면 Javac 컴파일러에 의해 default constructor가 자동 삽입된다.
  • 이름이 class명과 동일하다.
  • return 구문이 따로 존재하지 않는다.
    return 구문이 따로 존재하지 않기 때문에 return 타입도 명시하지 않는다.
    ( method와의 대표적인 차이점 )

Method Overloading

인자의 개수와 타입만 다르다면 똑같은 이름의 메소드가 존재할 수 있다.
생성자에게도 적용이 가능하다 → constructor overloading

package com.kakao.test;

// 메소드 오버로딩 (인자개수)
public class Student {
	
	public void getScore() {
		
	}
	
	public void getScore(int k) {
		
	}
}

package com.kakao.test;

// 메소드 오버로딩 (인자타입)
public class Student {
	
	public void getScore(String k) {
		
	}
	
	public void getScore(int k) {
		
	}
}

// 생성자 오버로딩
package com.kakao.test;

public class Student {
	
	Student(){
		
	}
	Student(int k){
		
	}
}

Operator

Class의 재활용

package

자바의 모든 class는 특정 package에 포함된다.
package는 class의 유지보수 및 관리를 위해 class를 논리적으로 묶어두는 기법이다.

  • 많은 class를 만들어 낼 수 있으며, 많은 class들을 관리하고 재사용할 수 있어야한다.
  • 가장 원시적인 방법 → class file이나 source 파일을 우리 project의 같은 폴더 내에 위치시키는 것이다.
  • 여러개의 copy본을 유지하게 되어서 결국은 유지보수에 문제가 발생하게 된다.
  • 이를 해결하기 위해, package라고 불리는 논리적인 단위로 관련있는 class들을 묶어서 사용한다.
  • package는 놀리적인 단위 => 물리적으로 folder로 표현한다.
  • package 구문을 사용하지 않으면 default package에 포함된다.
  • class의 이름이 같아도 package가 다르면 다른 class다.
  • package 이름의 folder가 생성되고 그 안에 class를 위치한다.
    (import를 이용해서 축약해서 표현할 수도 있다)
  • 패키지명은 기본적으로 소문자로 써야한다.
package test;
import com.kakao.test;
public class Maon {
	public static void main(String[] args){
    	//com.kakao.test.Student s = new com.kakao.test.Student();
        // 반드시 해당 패키지가 어디에 있는지 명시해야 함
        Student s = new Student();
    }
}

Access Modifier( 접근제어자 )

public

  • (패키지에 상관없이) 제약없이 사용 가능하다.
    같은 패키지 내에선 맘대로 사용할 수 있다.

  • class가 public이라고 하더라도, 그 안에 있는 필드나 메소드, 생성자 모두가 접근이 가능해지는 것은 아니다.

  • 따라서 다음 코드에 생성자가 외부 패키지에서 접근하기 위해서는 Student() 앞에 public이 붙어야 한다.

protected

  • 같은 package인 경우 사용이 가능하고, 다른 package라도 상속관계에 있으면 사용이 가능하다.

package(default)

  • 키워드가 없다.
    ( 키워드를 명시하지 않으면 package 혹은 default 접근 제어자라고 한다 )

  • 같은 패키지 내에서만 사용 가능하다

  • class Student는 다른 패키지에서 import 하더라도 사용할 수 없다

private

  • 같은 클래스 안에서만 사용이 가능하다.
  • 클래스 내부에 보호해야 하는 중요한 데이터가 있을 경우 사용한다.
  • 같은 패키지 내 다른 클래스에서 접근하지 못 한다.
    이는 information hiding (정보은닉)을 나타낸다.

  • field는 특별한 경우를 제외하곤 모두 private으로 설정해야 한다. (외부에서 직접적인 access를 할 수 없도록)

  • method는 행위를 하는 작업이기 때문에 특별한 이유가 없는 한 외부에서 사용할 수 있도록 public으로 설정한다.

package com.kakao.test;

public class Student {
	// class내부의 field는 보호해야하는 정보
	// 결론적으로 field는 특별한 경우를 제외하곤 싹다 private(외부에서 직접적인 access를 할 수 없도록)
	private String stuName; // information hiding(정보은닉)
	public String stuNum;
	
	// (default) 생성자
	public Student(){
		
	}
	
	// method는 행위를 하는 작업이기 때문에 특별한 이유가 없는 한
	// 외부에서 사용할 수 있도록 public으로 설정한다.
}

class Main{
	public static void main(String[] args) {
		Student s = new Student();
		s.stuName = "홍길동";
	}
}

/* getter/setter */
package com.kakao.test;

public class Student {
	// class내부의 field는 보호해야하는 정보
	// 결론적으로 field는 특별한 경우를 제외하곤 싹다 private(외부에서 직접적인 access를 할 수 없도록)
	private String stuName; // information hiding(정보은닉)
	private String stuNum;
	
	// Source - generate getter/setter
	public String getStuNum() {
		return stuNum;
	}
	public void setStuNum(String stuNum) {
		this.stuNum = stuNum;
	}
	public String getStuName() {
		return this.stuName;
	}
	public void setStuName(String stuName) {
		this.stuName = stuName;
	}
	
	// (default) 생성자
	public Student(){
		
	}
	
	// method는 행위를 하는 작업이기 때문에 특별한 이유가 없는 한
	// 외부에서 사용할 수 있도록 public으로 설정한다.
}

접근제어자의 적용

class

class 앞에는 public 혹은 아예 안 붙거나

field, constructor, method

다 붙을 수 있음

정리

class 안에는 ( package로 묶여있다 )

  1. private field들이 들어온다.

  2. static field가 들어온다.

  3. constructor가 여러개 나온다.

    (constructor overloading)

  4. 일반적인 business 메소드는 모두 public으로 설정한다.

  5. private field에 대한 getter/setter 메소드가 나온다. (왜? 필드에 접근할 수 있도록)

  6. (optional) main 메소드 (main 메소드가 여러개 있어도 상관없다 - 단위 테스트를 위해서)

0개의 댓글