[Java] 객체 지향 - 클래스, 인스턴스, 생성자

2023. 8. 19. 17:54·개발 ━━━━━/Java
반응형

클래스 (Class)

클래스란 객체를 정의해놓은 것으로 객체를 생성하는데 사용된다.

 

객체와 인스턴스 (Instance)

정의

클래스로부터 만들어진 객체를 그 클래스의 인스턴스라고 한다.

 

클래스 인스턴스화 인스턴스 (객체)
-------------------------------------->

 

객체는 속성 (property) 과 기능 (function)으로 이루어져 있고 이를 그 객체의 멤버 (member) 라고 한다.

 

속성 - 멤버 변수(member variable), 특성(attribute), 필드(field), 상태(state)

기능 - 메서드(method), 함수(function), 행위(behavior)

 

* 멤버변수 (클래스변수, 인스턴스변수)

 

생성과 사용

클래스명 변수명;			// 클래스의 객체를 참조하기 위한 참조변수 선언
변수명 = new 클래스명;		// 클래스의 객체를 생성 후, 객체의 주소를 참조변수에 저장

Tv t;
t = new Tv();
인스턴스는 참조변수를 통해서만 다룰 수 있다.

 

객체 배열

참조변수들을 하나로 묶은 참조변수 배열

Tv tv1, tv2, tv3;

Tv[] tvArr = new Tv[3];

객체 배열을 생성하는 것은

객체를 다루기 위한 참조 변수들이 만드는 것일 뿐이라 초기화를 시켜주어야 한다.

 

// 객체 배열 선언
Tv[] tvArr = new Tv[3];

// 초기화 1번째 방법
TvArr[0] = new Tv();
TvArr[1] = new Tv();
TvArr[2] = new Tv();

// 초기화 2번째 방법
Tv[] tvArr = { new Tv(), new Tv(), new Tv() };

// 초기화 3번째 방법
Tv[] tvArr = new Tv[3];

for(int i=0; i<tvAtt.length; i++){
	tvArr[i] = new Tv();
}

 

변수와 메서드

변수의 종류

1. 인스턴스 변수 (instance variable)

- 클래스 영역에 선언되며, 클래스의 인스턴스를 생성할 때 만들어진다.

- 인스턴스마다 고유한 상태를 유지해야하는 경우, 선언한다.

- 인스턴스가 생성되었을 때 생성된다.

 

2. 클래스 변수 (class variable)

- 인스턴스 변수 앞에 static 을 붙이는 것으로 선언한다.

- 한 클래스의 모든 인스턴스들이 공통적인 값을 유지해야하는 속성의 경우, 선언한다.

- 인스턴스를 생성하지 않고 '클래스이름.클래스변수' 의 형식으로 언제든지 바로 사용할 수 있다.

- 클래스가 메모리에 올라갈 때 생성된다.

클래스 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로, 항상 공통된 값을 갖는다.
'인스턴스.클래스변수' 로도 표현 가능하지만 '클래스이름.클래스변수' 를 권장한다.
멤버 변수 (클래스 변수, 인스턴스 변수) 는 초기화 시켜주지 않아도 자동적으로 타입형의 기본값으로 초기화된다.

 

3. 지역 변수 (local variable)

- 메서드 내에 선언되어 메서드 내에서만 사용 가능하다.

 

class Variables{
	int iv;				// 인스턴스 변수
    static int cv;		// 클래스 변수
    
    void method(){
    	int lv = 0;		// 지역 변수
    }
}

 

메서드 (Method)

특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것.

반환타입 메서드이름 (매개변수 ...){			// 선언부
	메서드 호출시 수행될 코드				 // 구현부
}

 

기본형 매개변수와 참조형 매개변수

기본형 매개변수 (primitive type) : 변수의 값을 읽기만 할 수 있다.

참조형 매개변수 (reference type) : 변수의 값을 읽고 변경할 수 있다.

 

class Data{
     int x;
    }

public class Main {
    public static void main(String[] args){
        Data d = new Data();
        d.x = 10;
        System.out.println("Before : " + d.x);

        notChanged(d.x);
        System.out.println("Not changed result : " + d.x);
        changed(d);
        System.out.println("Changed result : " + d.x);
    }

    static void notChanged(int x){                     // 기본형 매개변수 (primitive)
        x = 1000;
        System.out.println("Not changed : " + x);
    }

    static void changed(Data d){                        // 참조형 매개변수 (reference)
        d.x = 1000;
        System.out.println("Changed : " + d.x);
    }
}

 

참조형 반환타입

class Data {
    int x;
}

public class Main {
    public static void main(String[] args) {
        Data d = new Data();
        d.x = 10;
        
        Data d2 = copy(d);
        System.out.println("d.x = "+d.x);
        System.out.println("d2.x = "+d2.x);
    }
    
    static Data copy(Data d){
        Data tmp = new Data();
        tmp.x = d.x;
        
        return tmp;
    }
}
반환타입이 참조형 이라는 것은 메서드가 객체의 주소를 반환한다는 것을 의미한다.

 

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

- 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통적으로 사용해야하는 것에 static 을 붙인다.

- 클래스 변수는 인스턴스를 생성하지 않아도 사용할 수 있다.

- 클래스 메서드는 인스턴스 변수를 사용할 수 없다. (인스턴스 변수, 메서드에서는 static 이 붙은 멤버들을 사용할 수 있다.)

- 메서드 내에서 인스턴스 변수를 사용하지 않는다면 static 을 붙이는 것을 권장한다.

 

class MyMath{
    long a, b;

    long add(){
        return a+b;
    }

    // 매개변수만으로 작업이 가능, a, b = 지역변수
    static long add(long a, long b){
        return a+b;
    }
}

public class Main {
    public static void main(String[] args) {
        // 인스턴스 생성 없이 클래스 메서드 호출
        System.out.println(MyMath.add(200L, 100L));

        // 객체 생성 후, 인스턴스 메서드 호출
        MyMath mm = new MyMath();
        mm.a = 200L;
        mm.b = 100L;

        System.out.println(mm.add());
    }
}
call c = new call();
int result = c.instanceMethod();

// 한 줄로 가능
int result = new call().instanceMethod();

// 하지만 참조변수를 선언하지 않았기 때문에 생성된 call 인스턴스는 재사용 불가

 

오버로딩 (Overloading)

한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것

 

조건

1. 메서드 이름이 같아야 한다.

2. 매개변수의 개수, 타입이 달라야 한다. (반환 타입은 영향 x)

 

int add(int a, int b);

int add(int x, int y);		// 성립 x
int add(long a, long b);	// 성립 o
long add(int a, int b);		// 성립 x

 

가변 인자 (varargs / variable arguments)

- '타입... 변수명' 의 형식으로 선언

- 매개변수 중에서 가장 마지막에 선언해야 한다.

- 인자의 개수를 가변적으로 할 수 있다. (아예 없어도 되고 배열도 가능)

 

 

String str(String s1, String s2, String s3 ...){ ... }

// 가변 인자 사용
String str(String... str) { ... }
매개변수를 가변 인자가 아닌 배열 (String[] str) 로 하는 것과의 차이 :
반드시 인자를 지정해 줘야하기 때문에 null 이나 길이가 0인 배열을 인자로 지정해줘야 한다.
가능한 가변 인자를 사용한 메서드는 오버로딩하지 않는다. (메서드가 구분되지 않아 컴파일 에러 발생)

 

생성자 (Constructor)

인스턴스가 생성될 때 호출되는 인스턴스 초기화 메서드 이다.

( ≒ 메서드)

 

- 생성자의 이름은 클래스의 이름과 같아야 한다.

- 클래스 내에 선언된다.

- 모든 생성자는 리턴값이 없다.

- 오버로딩이 가능하여 한 클래스 안에 여러 개의 생성자 존재 가능하다.

 

class Card{
    Card(){						// 매개변수가 없는 생성자
        
    }
    Card(String k, int num){	// 매개변수가 있는 생성자
        
    }
}

 

기본 생성자 (Default Constructor)

- 클래스에 생성자가 하나도 정의되지 않은 경우 생성되는 기본 생성자

 

class Data1{
    int value;
}

class Data2{
    int value;
    Data2(int x){
        value = x;
    }
}

public class Main {
    public static void main(String[] args) {
        Data1 d1 = new Data1();
        Data2 d2 = new Data2();     // 컴파일 에러
    }
}

Data2 클래스에는 Data2(int x) 라는 생성자가 정의되어 있어 기본 생성자가 자동으로 추가되지 않았다.

 

해결방법
1. Data2 d2 = new Data2(10); 으로 인스턴스 생성
2. Data2 클래스에 Data2() 생성자 정의

 

매개변수가 있는 생성자

Car c = new Car();
c.color = "white";
c.gearType = "auto";
c.door = 4;

// 한 번에 초기화 가능
Car c = new Car("white", "auto", 4);

 

this(), this

this this()
인스턴스 자신을 가리키는 참조 변수
(인스턴스의 주소가 저장되어 있다.)
생성자
모든 인스턴스 메서드에 지역 변수로 숨겨진 채 존재한다. 같은 클래스의 다른 생성자를 호출할 때 사용한다.

- 생성자의 이름으로 클래스이름 대신 this 를 사용한다.

- 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다.

 

class Car{
    String color;
    String gearType;
    int door;

    Car(){
        this("white", "auto", 4);
    }
    Car(String color){
        this(color, "auto", 4);
    }
    Car(String color, String gearType, int door){
        this.color = color;
        this.gearType = gearType;
        this.door = door;
    }
}

class Main {
    public static void main(String[] args) {
        Car c1 = new Car();
        Car c2 = new Car("blue");
    }
}

 

인스턴스 복사

class Car{
    String color;
    String gearType;
    int door;

    Car(){
        this("white", "auto", 4);
    }
	
    // 인스턴스 복사
    Car(Car c){
        this(c.color, c.gearType, c.door);
//        color = c.color;
//        gearType = c.gearType;
//        door = c.door;
    }
}

class Main {
    public static void main(String[] args) {
        Car c1 = new Car();
        Car c3 = new Car(c1);

        System.out.println(c1.color + c1.gearType + c1.door);
        System.out.println(c3.color + c3.gearType + c3.door);
    }
}

 

인스턴스 복사가 진행되엇지만 서로 독립적인 메모리 공간에 존재하는 별도의 인스턴스이므로 c1 의 값이 변경되어도 c3 의 값이 변경되진 않는다.

 

변수의 초기화

멤버 변수 (클래스 변수, 인스턴스 변수) 초기화 선택적, 초기화 안할 시 자동적으로 타입형의 기본값으로 초기화 됨
지역변수 초기화 필수적

 

멤버 변수의 초기화 방법

명시적 초기화 (Explicit Initialization)

변수를 선언과 동시에 초기화하는 것

class Car{
	int door = 4;				// 기본형 변수 초기화
    Engine e = new Engine();	// 참조형 변수 초기화
}

 

생성자

 

초기화 블럭 (Initialization Block)

복잡한 초기화 작업이 필요할 때 초기화 하는 방법

class InitBlock{
	static {
    	// 클래스 초기화 블럭
    }
    
    {
    	// 인스턴스 초기화 블럭
    }
}

 

1. 클래스 초기화 블럭

- 메모리에 처음 로딩될 때 한 번만 수행

 

2. 인스턴스 초기화 블럭

- 인스턴스를 생성할 때 마다 수행

- 생성자보다 인스턴스 초기화 블럭이 먼저 수행

인스턴스 변수의 초기화는 주로 생성자를 사용하고,
인스턴스 초기화 블럭은 모든 생성자에서 공통으로 수행돼야 하는 코드를 넣는데 사용된다.
class Car{
    String color;
    String gearType;
    int count;
    int serialNo = count;
    
    // 인스턴스 초기화 블럭
    // 중복된 인스턴스 초기화 코드를 넣어준다.
    {
        count++;
        serialNo = count;
    }
    
    Car(){
//        count++;
//        serialNo = count;
        color = "white";
        gearType = "Auto";
    }
    
    Car(String color, String gearType){
//        count++;
//        serialNo = count;
        this.color = color;
        this.gearType = gearType;
    }
}

 

실행 순서

class BlockTest{
    static{
        System.out.println("static {}");
    }

    {
        System.out.println("{ }");
    }

    public BlockTest(){
        System.out.println("생성자");
    }

    public static void main(String[] args) {
        System.out.println("BlockTest bt = new BlockTest(); ");
        BlockTest bt = new BlockTest();

        System.out.println("BlockTest bt2 = new BlockTest); ");
        BlockTest bt2 = new BlockTest();
    }
}

// 출력 결과
// static {}
// BlockTest bt = new BlockTest();
// { }
// 생성자
// BlockTest bt2 = new BlockTest);
// { }
// 생성자

1. BlockTest 가 메모리에 로딩될 때, 클래스 초기화 블럭이 가장 먼저 수행된다.

2. main 메서드가 수행된다.

3. BlockTest 인스턴스 bt 가 생기면서 인스턴스 초기화 블럭이 실행되고 그 다음에 생성자가 수행된다.

4. 그 다음 bt2 인스턴스가 생성되면서 반복된다.

 

class InitTest{
    static int cv = 1;
           int iv = 1;

    static { cv = 2; }
    { iv = 2; }

    InitTest(){
        iv = 2;
    }

    public static void main(String[] args) {
        new InitTest();
    }
}
클래스 초기화 인스턴스 초기화
기본값 명시적 초기화 클래스 초기화블럭 기본값 명시적 초기화 인스턴스 초기화블럭 생성자
cv = 0 cv = 1 cv = 2 cv = 2 cv = 2 cv = 2 cv = 2
      iv = 0 iv = 1 iv = 2 iv = 3
1 2 3 4 5 6 7

클래스 변수 초기화 : 클래스가 처음 메모리에 로딩될 때 차례대로 수행됨

인스턴스 변수 초기화 : 인스턴스를 생설할 때 차례대로 수행됨

클래스 변수는 항상 인스턴스 변수보다 항상 먼저 생성되고 초기화 된다.

 

( 참고 서적 : Java의 정석 )

반응형

'개발 ━━━━━ > Java' 카테고리의 다른 글

[Java/Algorithm] List 오름차순  (0) 2023.08.24
[Java] 객체 지향 - 상속, 오버라이딩  (1) 2023.08.24
[Java] 기초 문법 - 컬렉션 (Collection)  (0) 2023.08.16
[Java] 기초 문법 - 배열  (0) 2023.08.16
[Java] Input 값 입력 받는 방법 ① - Scanner 클래스  (0) 2023.08.16
'개발 ━━━━━/Java' 카테고리의 다른 글
  • [Java/Algorithm] List 오름차순
  • [Java] 객체 지향 - 상속, 오버라이딩
  • [Java] 기초 문법 - 컬렉션 (Collection)
  • [Java] 기초 문법 - 배열
GukJang
GukJang
•  ⌘ ⌥ •
    반응형
  • GukJang
    SPACE
    GukJang
  • 전체
    오늘
    어제
    • Blog (73)
      • 개발 ━━━━━ (68)
        • Java (14)
        • C++ (1)
        • HTML (1)
        • Spring(boot) (7)
        • Dev (9)
        • SQL (1)
        • CS (2)
        • Git (1)
        • Troubleshoot (14)
        • Algorithm (2)
        • Definition (1)
        • Dev Life (2)
        • TIL (7)
        • 항해 (6)
      • 공돌 ━━━━━ (4)
        • 플젝 (2)
        • 장비 (1)
        • 부품 (1)
      • 독서 ━━━━━ (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    mysql
    docker
    electron-builder
    AWS
    CI CD
    오픈소스 기여
    자바
    spring
    Python
    github actions
    사전 스터디
    Java
    SpringBoot
    알고리즘
    EC2
    docker volume
    micropython
    마이크로파이썬
    백준
    항해99
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
GukJang
[Java] 객체 지향 - 클래스, 인스턴스, 생성자
상단으로

티스토리툴바