자바 클래스

이지용·2024년 4월 21일

클래스

클래스는 크게 속성(attributes)과 메서드(methods)로 이루어진다.
속성은 데이터의 값을 말하고, 메서드는 함수를 말한다.

클래스를 통해서 우리는 객체를 만들 수 있다. 이렇게 만들어진 객체는 이 객체를 만든 클래스의 인스턴스라고도 할 수 있다.

class Circle { 
  double radius;

  double area(){
    return radius * radius * 3.14159; 
  }
}

여기서 radius는 속성이 되고, area는 메서드가 된다.

객체 만들기

객체를 만들기 위해서는 먼저 선언을 해줘야 한다.
우리가 정수 x 를 선언할 때 int x;를 했던 것 처럼 객체를 만들 때에는 클래스명 객체명;으로 선언한다.
예시로 위의 Circle 클래스로 객체를 선언하기 위해선 Circle circle1; 과 같이 선언해줄 수 있다.
정수를 선언하면서 초기값을 넣는 것 처럼( int x=1;) 객체를 만들 때에도 선언과 동시에 객체를 생성할 수 있다.

Circle circle1=new Circle();

여기서 Circle은 클래스명, circle1은 객체명, new는 객체를 생성할 때 사용하는 키워드이다.

위의 코드를 해석해보자면 Circle이라는 타입의 circle1을 선언하고, 그와 동시에 Circle이라는 클래스에서 객체를 만들어서 넣는 것이라고 볼 수 있다.

원시 데이터 타입과 참조 타입의 차이

클래스는 참조 타입이다.
int 와 같은 원시 데이터 타입은 실제 값을 저장한다.
하지만 클래스는 참조 타입으로, 실제 값을 저장하는 것이 아닌, 값이 있는 곳의 주소를 저장한다.

int x=1;
int y=2;
x=y;

다음과 같은 식에서는 x의 값은 2가 된다.

그렇다면 클래스를 사용했을 때에는 어떻게 될까?

circle1.radius=10;
circle2.raidus=20;
circle1=circle2;

여기서 circle1.radius=20이 된다. 하지만 int와는 다른 점이 있는데, 아예 circle1과 circle2가 참조하는 객체가 동일해졌다는 것이다.

엥 ? int일 때랑 뭐가 다를까?

참조하는 객체가 동일해지면 circle1의 속성을 바꿀 때, circle2의 속성도 바뀌게 된다.

circle1.radius=10;
circle2.raidus=20;
circle1=circle2;
circle1.radius=50;
//circle2.radius도 50이 된다.

다음과 같이 circle1의 속성만 바꿨을 뿐인데, circle2의 속성도 바뀐 것이 된다. 이것은 circle1과 circle2가 참조하는 객체가 같기 때문이다.

그렇다면 원래 circle1의 객체는 어떻게 될까?
그냥 쓰레기가 되어 자동적으로 JVM에 의해 수집된다.
따라서 만약 객체가 필요없어지면 그냥 null을 배정하면 된다.

객체 접근

객체의 속성이나 메서드를 접근하고 사용하기 위해선 어떻게 해야할까?
앞에서 circle1의 radius 속성을 변경했었다.

circle1.radius=50;

다음과 같이 메서드도 사용가능하다.

circle1.area();

물론 이렇게 사용하는 것은 접근 제어자에 의해 불가능해 질 수도 있다.
접근 제어자는 뒤에 더 설명한다.

생성자(constructor)

생성자는 객체가 생성될 때 호출된다.

단순하게 생각하면 객체가 생성될 때 호출하는 메서드로, 클래스의 이름과 같고, 리턴값이 아예 존재하지 않는다.(void도 쓰지 않음)

``` java
class Circle { 
  double radius;

  double area(){
    return radius * radius * 3.14159; 
  }
}
  Circle(double r) { //생성자 1
    radius = r;
  }

  Circle() { //생성자 2
    radius = 1.0; 
  }

여기서 Circle(double r), Circle()이 생성자가 된다. 보이듯이 리턴값도 쓰지 않고, 메서드명은 클래스명과 동일하다.
생성자가 2개여도 괜찮을까?
아까 오버로딩에 대해서 배웠다.
동일한 생성자가 두개라도 생성할 때 매개변수를 준다면 생성자 1을 사용하고, 매개변수를 주지 않는다면 생성자 2를 사용하게 된다.

Circle circle1=new Circle(4.0); // 생성자 1 사용, radius=4.0

Circle circle2=new Circle(); // 생성자 2 사용, radius=1.0

접근 제어자(accessor modifier)

접근 제어자(access modifier)를 사용하여 변수나 메서드의 사용 권한을 설정할 수 있다. 다음과 같은 접근 제어자를 사용하여 사용 권한을 설정할 수 있다.

  1. default
    클래스, 변수, 데이터는 같은 패키지 내에 있으면 모두 접근할 수 있다.

  2. public
    어떤 패키지, 어떤 클래스 내에 있든간에 모두 접근할 수 있다.

  3. private
    해당 클래스 내에서만 접근할 수 있다.

보통 클래스에서 속성은 private 으로 하여 외부에서 직접 건드리지 못하게한다.
대신 public 메서드를 통해 간접적으로 클래스의 속성을 건드릴 수 있게 한다.

매개변수 전달

메서드에 매개변수를 전달할 때는 passing by value를 사용한다.

인자의 값을 복사하여 메서드 안에서 사용하는 것이다.

원시 자료형 타입에서는 명확하지만 참조 타입을 매개변수로 전달할 때는 어떻게 될까?
참조 타입에서 변수는 객체의 주소값을 가지고 있다. 매개변수로 전달할 때 이 주소값을 복사하여 전달한다.
따라서 메서드 내에서 객체의 속성을 변경하면 전달한 인자가 참조하는 객체의 속성 또한 변하게 된다.

인스턴스 변수, 메서드

인스턴스 변수는 특정한 인스턴스에 포함되어 있다. 따라서 인스턴스(객체)가 있어야 변수를 사용할 수 있고, 인스턴스 메서드도 마찬가지로 인스턴스가 있어야 한다.
인스턴스 변수는 특정한 인스턴스에 종속되므로 인스턴스마다 값이 다를 수 있다.

클래스 변수, 메서드, 상수(static)

클래스 변수는 클래스의 모든 인스턴스가 같은 값을 가지게 된다.
클래스 메서드는 인스턴스 메서드와 다르게 인스턴스를 생성하지 않고, 작동할 수 있다.
클래스 상수는 클래스의 모든 인스턴스가 같은 값을 가지고, 값을 변경할 수 없다.

클래스 변수, 메서드, 상수를 선언하기 위해선 static을 붙이면 된다.

클래스 변수와 상수는 모든 인스턴스 끼리 값을 공유하고 싶을 때 보통 사용한다

인스턴스 변수와 클래스 변수의 유효 범위는 클래스 전체이다. 이 둘은 클래스 내부에서 언제든지 선언될 수 있다.

this 키워드

this 키워드는 말 그대로 객체 자기 자신을 말한다. 이는 객체가 자기 자신을 참조할 때 사용된다.
인스턴스1과 인스턴스2가 this 키워드를 각자 사용할 때, 인스턴스1 에선 인스턴스1을, 인스턴스2에선 인스턴스2를 가르킨다.
this.radius 처럼 사용된다.

this()는 같은 클래스에 있는 자신의 생성자 중 다른 생성자를 선택할 때 사용된다.

0개의 댓글