본문 바로가기
자바의 정석

vol6 1.객체지향 언어

by 백엔드 개발자 2021. 7. 19.

객체지향이론: 실제 세계는 사물(객체)로 이루어져 있으며, 발생하는 모든 사건들은 사물간의 상호작용이다.

따라서 실제 사물의 속성과 기능을 데이터(변수)와 함수로 정의하여 컴퓨터속으로 옮겨 가상세계를 구현한다.

 

객체지향 프로그래밍 : 프로그래밍에서 필요한 데이터를 추상화(공통된 속성이나 기능을 묶어 이름을 붙이는것. 클래스를 정의하는것.) 시켜 변수와 메소드를 가진 객체를 만들고 그 객체들 간의 상호작용을 통해 로직을 구성하는 프로그래밍 방법


장점 

 

1. 코드의 재사용성이 높다.

기존의 코드를 이용해서 새코드를 쉽게 작성가능.

 

2.유지보수가 용이하다.

코드간의 관계를 이용해서 적은 노력으로 코드 변경 가능

 

3.신뢰성이 높은 프로그래밍이 가능하다.

제어자와 메소드로 데이터 보호 및 올바른 값유지 및불필요한 중복을 제거.

 

단점:1. 처리속도가 느리다.2. 객체가 많으면 용량이 커진다.3. 설계시 시간과 노력이 더 많이 든다.

 

 

 

2. 클래스와 객체

클래스 : 객체를 정의해 놓은것. 객체를 생성하기 위해 사용된다.데이터를 추상화를 통해 변수와 메소드로 정의해 놓은것이 클래스다.객체를 생성하기 위한 틀이라고 볼 수도 있다.

 

객체 : 실제로 존재하는것. 프로그래밍 관점에서는 클래스의 내용대로 실제 메모리에 할당된것

 

클래스를 정의하고 클래스를 통해서 객체를 생성하는 이유 :한번 만들어 놓으면 다음에 객체를 생성할 때 편하게 생성할 수 있으므로

 

인스턴스화 : 클래스로 객체를 만드는 과정.인스턴스 : 어떤 클래스로부터 만들어진 객체를 지칭.

 

객체는 속성과 기능으로 이루어져 있다.멤버 : 객체가 가지고 있는 속성과 기능

 

같은 뜻의 용어들

속성 : 멤버변수, 특성, 필드, 상태

 

기능 : 메소드, 함수, 행위

 

 

2.4 인스턴스 생성, 사

 

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

인스턴스는 참조변수를 통해서만 다룰 수 있고, 인스턴스와 참조변수의 타입은 서로 같아야 한다.

 

 

같은 클래스에서 생성되어도 다른 참조변수로 인스턴스가 각각 생성된다면 각 인스턴스의 멤버변수값은 서로 다른값을 유지할 수 있다.

 

- 다른 참조변수로 1개의 인스턴스 참조하기.

 

 

2.5 객체 배열

Tv [] t= new Tv[3]; 

처럼 참조변수에 객체의 배열을 선언해서 참조할 수 있다.

각각의 인덱스들은 인스턴스들이다.

 

2.6 클래스의 또 다른 정의 - 1.클래스는 데이터와 함수의 결합 , 2.사용자 정의타입

1. 클래스 는 데이터와 함수의 결합이다. (프로그래밍 관점)

데이터 처리를 위한 데이터 저장형태의 발전과정

 

변수: 1개의 데이터를 저장할 수 있는 공간

배열: 같은 종류의 여러 데이터를 하나의 집합으로 저장할 수 있는 공간

구조체: 관련된 여러 종류의 데이터를 하나의 집합으로 저장할 수 있는 공간

클래스 : 데이터와 함수의 결합 (구조체+함수)

 

2. 클래스- 사용자 정의 타입

:프로그래머가 서로 관련된 변수들을 묶어서 하나의 타입으로 새로 추가하는 것.

객체지향언어에서 클래스가 곧 사용자 정의 타입이다.

 

 

 

 

3. 변수와 메서드

3.1 선언 위치에 따른 변수의 종류

변수의 종류 : 클래스 변수 , 인스턴스 변수, 지역변수.  변수의 선언된 위치를 기준으로 구분된다.

멤버변수 : 클래스 내부의 변수.

 

지역변수: 멤버변수를 제외한 나머지 변수들

클래스변수: 멤버변수중 static이 붙은것

인스턴스 변수: 멤버변수중 static이 붙지 않은것

 

class Variables

{

 int iv;     // 멤버변수중 static이 없으므로 인스턴스 변수.

 static int cv; //멤버변수중 static이 붙었으므로 클래스 변수

 void method()

{

  int lv=0;  // 멤버변수를 제외한 지역변수.
}
}

 

변수 종류 선언 위치 생성시기
클래스변수 클래스 영역 클래스가 메모리에 올라갈 때
인스턴스 변수 인스턴스가 생성되었을 때
지역변수 클래스 영역 이외의 영역
(메서드, 생성자, 초기화 블럭 내부)
변수 선언문이 수행되었을 때

인스턴스 변수 :

-클래스 영역에 선언되고, 클래스의 인스턴스를 생성할 때 (객체가 생성될 때) 만들어진다. (static이 없는 멤버변수)

-이 변수를 제어하려면 먼저 인스턴스가 생성되어야 한다. Variable a=new Variable()처럼.

-인스턴스는 독립적인 저장공간을 가져서 인스턴스마다 다른값을 가질 수 있다.

-인스턴스마다 고유한 상태를 유지해야 될 때 사용한다.

 

클래스 변수 :

-클래스 영역에 선언되고, 인스턴스를 생성 안하고도 언제라도 사용할 수 있다. 클래스이름.클래스변수  형식으로.

-클래스가 메모리에 로딩될 때 생성되고 프로그램 종료시까지 유지됨.

-인스턴스 변수앞에 static을 선언하면 되고, 모든 인스턴스가 공통된 저장공간(변수)을 공유하므로 

한클래스의 모든 인스턴스들이 공통된 값을 가지고 싶으면 클래스변수로 선언한다.

a2의 cv를 설정 안했는데도 1로 나온다. 초기값은 int형이라서 0이었다.

지역 변수 :

-메서드 내에서만 사용 가능하고, 메서드 종료시 자동소멸됨.

-지역변수는 지역변수가 선언된 블럭에서만 사용가능하다.

 

 

 

 

 

 

2021.7.21 17:00~19:21

 

3.2 클래스 변수와 인스턴스 변수

카드를 클래스로 정의했을 때

속성: 무늬, 숫자, 폭, 높이

인스턴스 변수 : 무늬 숫자 -> 왜냐하면 카드마다 고유한 값이 필요하므로. ex)하트 5, 스페이드2

클래스 변수: 폭,높이 -> 카드들이 다 같은 값을 공유해야 하므로.

 

클래스 변수를 사용할 때는 클래스이름.클래스 변수  로 쓰는게 안헷갈리기 좋다.

인스턴스 변수: 인스턴스가 생성될 때마다 생성되므로 인스턴스마다 각각 다른값

클래스 변수: 모든 인스턴스가 공통된 저장공간을 공유하므로 하나의 값.

무늬와 숫자는 인스턴스로, 폭과 높이는 static을 붙여 클래스 변수로 만들었다.

3.3 메서드

메서드 : 특정 작업을 수행하는 일련의 문장들을 하나로 묶은것. 블랙박스라고도 함.

 

메서드 사용 이유 :

1) 높은 재사용성

   메서드를 한번 만들어 놓으면 마음대로 호출가능하고, 다른 프로그램에서도 사용가능

   다시말해서 한번 만들어 놓으면 두고두고 쓸 수 있다.(우려먹을 수 있다)

2) 중복 코드 제거

   중복된 코드를 메서드 한줄로 바꿔쓸 수 있어서 코드길이도 줄고 수정할 곳도 줄어서 오류수정하기도 쉽고, 발생 가       능성도 더 낮다.

3) 프로그램의 구조화

큰 규모 프로그램을 한눈에 보기위해서, 그리고 문제를 더 쉽게 해결하기 위해서

문장들을 작업단위로 메서드 여러개로 나누어서 구조를 단순화 시킨다.

 

3.4 메서드의 선언과 구현

메서드는 선언부와 구현부로 이루어져 있다.

선언부는 여러곳을 수정해야하니 신중히 작성할 것.

 

메서드 이름

기능을 쉽게 알 수 있도록 함축적이면서도 의미있는 이름이 좋다.

다만 길더라도 내용을 알 수 있도록 적는게 좋다. 약어를 쓰면 협업할 때 의미알아내기 시간 걸린다.

 

return문

반환 타입과 일치하거나 자동형변환이 가능하도록.

 

지역변수 

메서드 내에 선언된 변수. 그메서드 안에서만 사용 가능하다.

 

 

3.5 메서드의 호출

메서드 이름(값1,값2,...); 형식.

인자의 타입은 매개변수의 타입과 일치하거나 자동형변환이 가능해야 한다.

메서드가 반환한 결과를 변수에 저장하는게 보통이나 저장안해도 문제되지 않는다.

 

메서드의 실행흐름

같은 클래스 내의 메서드끼리는 참조변수를 사용하지 않아도 서로 호출이 가능한데,

static 메서드는 같은 클래스 내의 인스턴스 메서드를 호출할 수 없다.

 

MyMath mm=new MyMath();

long value=mm.add(1L,2L);

에서 add메서드 호출결과가 바로 value로 들어가는 것처럼 보이지만, 호출한 자리를 반환값이 대신하고 대입연산자를 통해 value에 이값이 저장된다.

long value=3L;

 

3.6 return문

원래 모든 메서드에는 하나이상 return문이 있어야 한다.

void일 때는 컴파일러가 자동으로 return;을 넣어줘서 안써도 됐었다.

 

조심해야할 부분은 조건문에서 return문을 쓸 때, 항상 결과값이 반환되야 한다는 것이다.

조건부로 결과값이 반환되면 에러가 뜬다.

 

int max(int a, int a)

{

 if (a>b)

    return a;

 else 

    return b;
}

 

반환값

보통 변수가 오지만, 수식으로도 반환가능하다.(수식의 결과가 계산되어 반환된다.)

int add(int a, int a)

{

 return a+b;

}

부호 연산자로도 가능하다.

public int add(int x,int y)
{
return x>=0 ? x: x-1 ;  // x가 >=0이면 x, 아니면 x-1반환
}

 

매개변수의 유효성 검사

매개변수 구현부를 작성할 때는 매개변수의 값이 적절한 것인지 확인해야 한다.

사용자가 알아서 적절한 값을 넣어주길 기대하지 말고 

가능한 모든 경우의 수에 대해서 고민하고, 그에 대비한 코드를 추가해야 한다.

예외경우를 생각하라는 뜻같다.

 

 

3.7 JVM 메모리 구조

응용프로그램 실행시 JVM은 프로그램 수행에 필요한 메모리를 할당받고, 용도에 따라 여러 영역으로 나누어 관리한다.

3가지 주요영역 ( 메서드 영역, 호출 스택영역, 힙 영역 )

메서드 영역 :

어떤 클래스가 사용되면 JVM이 해당 클래스의 클래스 파일을 읽어 클래스에 대한 정보 (클래스 데이터) 및 클래스 변수를 이 영역에 생성한다.

쉽게 말해 클래스의 모든 정보를 메서드 영역이 갖고 있다고 볼 수 있다.

클래스 내용 + 클래스 변수 가 메서드 영역에 메모리가 할당됨.

 

힙 영역:

프로그램 실행중 생성되는 모든 인스턴스들이 이곳에 생성된다.

 

호출스택 영역:

호출된 메서드의 작업에 필요한 메모리 공간을 제공한다.

메서드가 작업을 실행하는 동안 지역변수,매개변수와 연산의 중간 결과등을 저장하는데 사용된다. 

메서드가 작업을 마치면 할당된 메모리 공간은 반환되어 삭제된다.

 

 

-메서드가 호출되면 수행에 필요한만큼의 메모리가 스택에 할당된다.

-수행이 끝나면 스택에서 사용했던 메모리를 반환하고 제거된다.

-맨위가 현재 수행중인 메서드이다.

-그 아래가 바로 위 메서드를 호출한 메서드이다.

 

호출 과정을 보면 메인이 호출되고 first()를 호출해서 위에 쌓인다.

그 후 first()에서 second()를 또 호출해서 스택에 생성되고, println()을 호출해서 또 스택에 쌓인다.

그다음 순서대로 출력후 반환되어 second()로 넘어가고, second()가 반환되면 first()로,

first()가 반환되면 main(), 그다음 전부 반환된다.

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

메서드가 호출되서 매개변수로 지정된 값을 매서드의 매개변수에 복사해서 넘겨준다.

기본형 매개변수 : 매개변수의 타입이 기본형(ex: int, float)인 매개변수이다.

오로지 읽을 수만 있다.

참조형 매개변수 : 매개변수의 타입이 참조형인것. 즉 클래스일 때.

읽고 변경이 가능하다.

 

현재 매개변수가 기본형인 상태라서, change클래스로 값만 복사되므로 

메인의 d.x는 변하지 않는다.

 

d.x를 change의 매개변수가 참조하고 있지 않으므로 지역변수로 간주되어 스택의 change 메모리 영역에서

그냥 사라진다.

 

 

 

 

 

이번에는 Data라는 참조형 매개변수를 사용했기 때문에 change의 매개변수에 메인의 d 객체 주소를 넘겨준다.

그래서 change에서 객체 d의 x값에 접근이 가능하고 변경이 가능하다.

 

change의 객체 d(x 오타)의 주소를 메인에서 복사받아서 d.x에 접근하는 모습이다.

 

 

 

 

 

2021 7 22 4:23 ~

 

3.9 참조형 반환타입

반환타입이 참조형이면 , 메서드가 객체의 주소를 반환한다는 것을 말한다.

메인에서 객체의 주소를 반환받아서 참조변수에 저장하면

그 객체를 접근하고 제어할 수 있다.

 

3.10 재귀호출

메서드 내부에서 자기 자신을 다시 호출하는 것.

코드가 재귀 호출만 있으면 무한루프에 빠지므로, 조건문은 필수다.

재귀 호출을 사용하는 이유:

코드의 간결함이 호출에 드는 비용(비효율성)보다 더 이득일 때만 사용하는게 좋다.

 

팩토리얼

f(n)=n* f(n-1) f(1)=1

 

 

3.11 클래스 메서드(static메서드)와 인스턴스 메서드

변수와 마찬가지로 메서드도 static이 붙으면 클래스 메서드, 안붙으면 인스턴스 메서드가 된다.

 

어느 경우에 메서드를 static을 사용해서 클래스 메서드로 정의하는게 좋을까 고민이 필요하다.

 

인스턴스 메서드: 인스턴스 변수와 관련된 작업을 하는 메서드로써 , 메서드를 실행하는데 인스턴스변수를 필요로

하는 메서드이다.

클래스 메서드: 인스턴스와 관계없는( 인스턴스 변수나 메서드를 사용하지 않는) 메서드를 static으로 정의해준다.

 

인스턴스와 관계가 있냐 없냐의 차이다.

 

1. 클래스 설계시 멤버변수중 모든 인스턴스에 공통적인 것에 static붙이기

 

모든 인스턴스에 대해서 같은 값을 가져야 되면 static을 붙여 클래스변수로 만드는것이 좋다.

 

2.클래스 변수는 인스턴스를 생성안해도 사용가능

 

클래스가 메모리에 올라갈 때 자동적으로 생성된다. (메서드 영역에 올라갈 때)

 

3.클래스 메서드는 인스턴스 변수 사용불가능

 

인스턴스 변수는 인스턴스가 힙영역에 생성되어야 사용가능한데, 클래스 메서드는  인스턴스 생성 없이도 호출이 가능하다.

그래서 클래스 메서드가 호출되었을 때 인스턴스가 존재하지 않을 수도 있으므로 사용을 금지한다.

반대로 인스턴스 변수나 메서드에서는 클래스 변수,메서드 항상 사용가능

4.메서드 내에서 인스턴스 변수를 사용안하면, static붙이는 것 고려.

 

클래스 변수: 인스턴스내에서 공통적으로 사용하는가 여부로 결정

클래스 메서드: 내부에 인스턴스 변수를 사용하지 않으면 static을 붙일 지 고려해볼만 하다.

static을 붙이면 메서드 호출시간이 줄어드므로.

 

 

3.12 클래스 멤버와 인스턴스 멤버간의 참조와 호출

요약: 인스턴스 멤버(변수, 메서드)는 클래스 멤버와 인스턴스 멤버를 자유롭게 참조하고 호출할 수 있으나,

클래스 멤버는 클래스멤버만 자유롭게 호출가능하고, 인스턴스 멤버는 객체를 생성해야지만 사용 가능하다.

why? 클래스 멤버가 생성돼있을 때 인스턴스 멤버는 존재하지 않을 수도 있기 때문에.

 

인스턴스 변수 : 클래스 변수, 메서드, 인스턴스 멤버 전부 사용가능

인스턴스 메서드: 클래스 변수, 클래스 메서드, 인스턴스 멤버(변수,메서드) 전부 사용가능

 

클래스 변수, 메서드 : 인스턴스를 생성해야지만 인스턴스 변수와 인스턴스 메서드를 사용할 수 있음. 클래스 멤버는 사용가능.

 

 

4. 오버로딩

4.1 오버로딩이란

오버로딩: 한클래스 내에 이름은 같지만 매개변수의 개수 또는 타입이 다른 메서드를 여러개 정의하는 것이다.

 

4.2 오버로딩의 조건

1. 메서드 이름이 같아야 됨

2. 메서드의 개수 및 타입이 달라야 함

 

반환타입은 아무런 영향이 없다.

 

4.3 오버로딩의 예

대표적으로 println이 있다.

매개변수로 지정하는 값의 타입에 따라 호출되는 println메서드가 달라진다.

 

void println()

void println(boolean x)

void println(char x)

void println(char[] x)

void println(double x)

void println(float x)

void println(int x)

void println(long x)

void println(Object x)

void println(String x)

등등

매개변수로 넘겨주는 값의 타입에 따라 위 오버로딩된 메서드중 하나가 선택되서 실행된다.

 

매개변수의 순서만 다르게 해서 오버로딩을 구현하면 매개변수 순서를 외우지 않아도 되는 장점이 있지만

단점이 될 수도 있으니 주의할 것.

 

 

 

 

4.4 오버로딩의 장점

1.하나만 정의하면 되므로 기억하기 쉽고 오류가능성 낮음

2.메서드 이름만 보고도 같은 이름이니 같은기능을 한다는 것을 알기 쉬움

3.이름 짓는 고민 안해도 된다. 이름을 절약할 수 있다.

 

 

4.5 가변인자와 오버로딩

가변인자: 매개변수의 개수를 동적으로 지정해주는 방법

형식: 타입... 변수명 

 

가변인자 외에도 매개변수가 더 있다면 , 가변인자를 매개변수중 가장 마지막에 선언한다.

가변인자인지 아닌지 구분할 수 없기 때문에

 

장점: 불필요한 오버로딩을 줄일 수 있음.

string test(String s1)

string test(String s1,String s2)

string test(String s1,String s2,String s3)

이렇게 할거를 가변인자를 사용하면

String test(String... args)

이걸로 대체 가능하다.

 

가변인자는 내부적으로 배열을 이용하는 것이라 인자가 없어도 되고 배열도 인자로 가능하다. (대신 비효율적임)

 

가변인자와 매개변수의 타입을 배열로 하는것의 차이

반드시 인자를 지정해 줘야해서 인자를 생략할 수 없고, null이나 길이가0인 배열을 인자로 지정해줘야 한다.

좀더 불편하다.

 

가변인자를 선언한 메서드를 오버로딩하면 메서드를 호출했을 때 구별하지 못하는 경우가 발생하기 쉬워서

되도록 가변인자 선언 메서드는 오버로딩을 안하는게 좋다.

 

 

 

 

 

 

2021 7.26 15:53~ 1750

5.생성자

5.1생성자란

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

인스턴스 생성시 변수의 초기화 작업이나 반드시 실행되어야 할 작업을 위해서도 사용된다.

 

생성자의 조건

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

2.생성자는 리턴값이 없다.

 

클래스 이름(타입변수명,.....)

오버로딩이 가능해서 여러개의 생성자 존재 가능

 

생성자는 인스턴스를 생성하는게 아니다. new연산자가 인스턴스를 생성한다.

 

수행과정:

 

Card c=new Card();

 

1)연산자 new에 의해 메모리의 힙영역에 Card클래스의 인스턴스가 생성된다.

2)생성자 Card()가 호출되어 수행된다.

3)연산자 new로 인해 생성된 Card인스턴스 주소가 참조변수c에 반환되어 저장된다.

 

인스턴스를 생성하기 위해 사용해왔던 클래스이름()= 생성자 였다.

인스턴스 생성시 반드시 클래스 내에 정의된 생성자 중 하나를 선택해서 지정해주어야 한다.

 

 

5.2 기본 생성자

기본 생성자 : 소스파일의 클래스에 생성자가 1개도 없을 경우 컴파일러가 자동으로 추가해주는 생성자.

 

형식 : 클래스이름( ){ }

 

모든 클래스에는 반드시 1개이상의 생성자가 정의되어 있어야 한다.

인스턴스 생성시 그동안 컴파일러가 생성한 기본 생성자를 사용하고 있었다.

 

만약 클래스 내에 다른 생성자가 1개라도 정의되어 있으면 기본생성자는 추가되지 않는다.

 

class data2(){

int value;

Data2(int x)

{

 value=x;

}

}

이렇게 생성자가 정의되어 있을 경우

Data2 d=new Data2(); 이렇게 기본생성자를 찾아도 추가되지 않았기 때문에 에러가 난다.

 

Data2 d=new Data2(10);이런식으로 선언해야 한다.

 

 

클래스에 정의된 생성자가 1개도 없을 경우에만 기본생성자가 컴파일러에 의해 추가된다.

 

 

5.3 매개변수가 있는 생성자

인스턴스를 생성할 때 매개변수가 있는 생성자를 사용하면 인스턴스 생성과 동시에 초기화를 할 수 있어서

코드가 더 간결하고 직관적이다. 더 바람직함.

 

Car c1=new Car();

c1.color="white";

c1.gearType="auto";

c1.door=4;

보다

 

Car c2=new car("white","auto",4);

가 더 직관적이고 간결하다.

 

되도록 매개변수가 있는 생성자를 사용하자

 

 

 

5.4 생성자에서 다른 생성자 호출하기 - this(), this

서로 다른 생성자간에도 서로 호출이 가능하다.

하지만 2가지 조건을 만족해야 한다.

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

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

 

첫줄에서만 호출 가능하게 한 이유:

초기화 작업 도출 다른 생성자를 호출하면 호출된 생성자안에서도 초기화작업을 

진행하므로, 이전의 초기화작업이 무의미해질 수 있어서!

 

Car()에서 또다른 생성자 Car(String color, String gearType, int door)를 호출할 때 'Car'대신 'this'를 이용해서 호출했다.

그리고 첫째 줄에서 호출했다.

 

생성자들은 서로 호출하게 해서 유기적으로 연결해주면 유지보수도 쉬운 좋은 코드를 얻을 수 있다.

생성자의 매개변수로 선언된 이름 (ex:color)가 클래스의 인스턴스 변수(color)와 같을 때는 이름만으로는 구분이 불가능해서 this를 붙여 this.color(클래스 내의 인스턴스 변수), color(생성자의 매개변수) 로 구분짓는다.

 

 

this는 참조변수로 인스턴스 자신을 가리킨다. 참조변수로 인스턴스 멤버에 접근 가능한것처럼

this로 인스턴스변수에 접근할 수 있다.

 

하지만 this는 인스턴스멤버에서만 사용가능하다.

클래스메서드(static 메서드)에서는 인스턴스가 존재하지 않을 수도 있기 때문에( 왜냐하면 클래스메서드는 인스턴스 생성없이 호출이 가능하다.) 클래스 메서드에서는 this를 못쓴다. 클래스 메서드에서 인스턴스 멤버를 못쓰는것 처럼.

 

 

모든 인스턴스메서드에는 this가 지역변수로 숨겨져있다.

인스턴스메서드는 특정 인스턴스와 관련된 작업을 해서 자신과 관련된 인스턴스 정보가 필요하지만

클래스 메서드에서는 인스턴스와 관련없는 작업을 해서 인스턴스 정보가 필요없다. -> this가 필요없다.

 

 

5.5 생성자를 이용한 인스턴스의 복사

현재 사용하고 있는 인스턴스와 같은 상태(모든 인스턴스 변수가 같은값을 가지고 있는 것)를 갖는 인스턴스를 1개 더 만들고자 할 때는

어떤 클래스의 참조변수를 매개변수로 선언한 생성자를 이용하면 편하게 만들 수 있다.

 

Car(Car c){

this(c.color, c.gearType,c.door);

}

이렇게 쓰면

매개변수로 넘겨진 참조변수가 가리키는 Car 인스턴스의 변수들의 값을 인스턴스 자신으로 복사하게 된다.

 

c1을 먼저 인스턴스로 생성한 후,

Car(Car c) 생성자를 이용해서 c1의 인스턴스를 복사한 c2 인스턴스를 생성했다.

독립적으로 생성된 인스턴스들이므로 값의 영향을 받지 않는다.

c2의 color는 변경되지 않았다.

인스턴스 생성시 결정할 2가지

1)클래스-어떤 클래스의 인스턴스를 생성할 것인가

2)생성자- 선택한 클래스의 어떤 생성자로 인스턴스를 생성할 것인가 ( ex: 기본, 매개변수있는 다른 오버로딩 생성자, 복사용 생성자)

 

 

6. 변수의 초기화

6.1 변수의 초기화

변수를 선언하고 처음으로 값을 저장하는 것이다.

가능하면 선언과 동시에 초기화하는 것이 바람직하다.

 

멤버변수는 자동으로 자료형에 맞게 초기화가 이루어져서 그대로 사용해도 되는데,

지역변수는 반드시 초기화 해야한다.

 

x,y는 멤버변수이다. (인스턴스 변수. static이 없으므로)

하지만 i는 지역변수이다. 따라서 초기화 안된 i를 j의 초기값으로 사용할 수 없다.

 

멤버변수 초기화 방법:

1) 명시적 초기화

2) 생성자

3) 초기화 블럭

   -인스턴스 초기화 블럭  : 인스턴스 변수 초기화에 사용

   -클래스 초기화 블럭    : 클래스 변수 초기화에 사용

 

 

6.2 명시적 초기화

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

가장 기본적이고 간단한 초기화 방법이다.

int door=4; // 기본형 변수 초기화

Engine e=new Engine(); // 참조형 변수 초기화

이런식으로.

 

복잡한 초기화 작업 필요시 초기화 블럭을 사용해야 한다.

 

6.3 초기화 블럭

인스턴스 초기화 블럭, 클래스 초기화 블럭 2가지가 있다.

 

인스턴스 초기화 블럭은 클래스 내에 { }블럭을 만들고 사용

클래스 초기화 블럭은 인스턴스 초기화 블럭 앞에 static만 붙여주면 된다.

 

인스턴스 초기화 블럭은 인스턴스가 생성될 때 마다

클래스 초기화 블럭은 클래스가 메모리에 처음로딩 될 때만

생성됨.( 클래스가 처음 로딩될 때 클래스 변수가 메서드 영역에 만들어지고, 클래스 초기화 블럭이 클래스 변수들을 초기화한다.)

 

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

 

인스턴스 변수를 초기화 할때는 주로 생성자를 사용하고,

모든 생성자에서 공통으로 수행되야 하는 코드를 넣을 때 인스턴스 초기화 블럭을 사용한다.

 

현재 count++; 이랑 No=count;라는 코드가 두 생성자에서 중복되고 있다.

이렇게 인스턴스 초기화 블럭으로 공통된 부분을 빼서 따로 넣어주면

더 간결한 코드가 나온다.

 

재사용성을 높이고, 중복을 제거하는것은 객체지향프로그래밍의 궁극적인 목표중 하나이다.

코드의 중복제거는 코드의 신뢰성 향상 및 오류의 발생가능성을 줄여준다.

 

배열이나 예외처리가 필요한 초기화에서는 추가적으로 클래스 초기화 블럭을 사용해준다.

 

 

6.4 멤버변수의 초기화 시기와 순서

클래스 변수의 초기화 시점 : 클래스가 처음 메모리(메서드영역)에 로딩될 때 단 한번 초기화 된다.

인스턴스변수의 초기화 시점 : 인스턴스가 생성될 때마다 각 인스턴스별로 힙영역에 초기화가 이루어진다

 

클래스 변수의 초기화 순서: 기본값 - > 명시적 초기화 -> 클래스 초기화 블럭

인스턴스 변수의 초기화 순서: 기본값 -> 명시적 초기화 -> 인스턴스 초기화 블럭 - > 생성자 

 

 

 

 

'자바의 정석' 카테고리의 다른 글

Vol.7 객체지향 프로그래밍 2  (0) 2021.07.27
자바 특징  (0) 2021.07.19