프로그래밍 언어/Java

[java]클래스를 알아보자 2

ssung.k 2019. 4. 10. 16:17

정적 멤버

경우에 따라서 한 클래스의 여러 객체들이 하나의 변수를 공유해야하는 경우가 생긴다. 이러한 맴버를 정적 멤버 또는 클래스 멤버라고 한다. 정적 맴버를 만드는 방식은 단순히 필드를 정의할 때 앞에 static을 붙여서 구현한다.

  • 정적 변수
class Student {
    static int count = 0;    
}

또한 정적 멤버는 객체없이도 접근이 가능하다. 클래스 이름 뒤에 . 과 정적 멤버를 연결시켜준다. 물론 객체를. 통한 접근도 가능하다.

Student.count += 1;

정적 변수와 상대되는 개념을 인스턴스 변수라고 한다. 인스턴스 멤버는 각 객체 마다 독립적인 기억공간을 가지고 당연히 값도 다 다를 수 있다.

 

자바에서는 전역 변수가 없기 때문에 정적 변수를 사용하여 전역 변수의 개념처럼 활용 할 수 있다.

 

  • 정적 메소드

정적 메소드도 마찬가지로 static 을 붙여서 구현이 가능하다. 대표적인 예시로 Math 클래스에 있는 여러 메소드들이다.

double num = Math.sqrt(4.0);

또한 여태까지 의심없이 봐왔던 main() 메소드에도 앞에 static이 붙어있다. 이 역시도 자바 가상 기계가 객체 생성 없이 main() 메소드를 실행시키기 위함이다.

정적 메소드에서는 객체가 없더라도 사용이 가능하기 때문에 인스턴스 변수를 사용할 수 없다. 또한 같은 이유로 this 연산도 사용 불가능하다.

객체 소멸

객체가 소멸되는 경우를 알아보자. 앞에서 알아봤듯이 객체를 생성하기 위해서는 new 연산을 사용한다. Student Class 의 객체를 두 개 생성해보자.

Student s1 = new Student();
Student s2 = new Student();

s1 이 가르키는 객체와 s2 가 가르키는 객체는 현재 다르다.

s1 = s2

다음과 같이 s2도 s1의 객체를 가르키게 하면 기존의 s2 가 가르키던 객체는 더 이상 의미가 없어져 자동으로 소멸하게 된다.

Student s2 = new Student();
s2 = null;

다음과 같이 s2가 아무것도 가르키지 않게 해서 객체를 강제적으로 소멸시킬 수 도 있다.

객체 배열

객체 배열은 일반적인 배열과는 조금 다르다. 일반적인 배열, 정수형 배열을 생각하면 각 배열의 원소로 정수값이 저장되지만 객체 배열에는 객체에 대한 참조값이 저장되어있다. 예시를 통해서 알아보자.

class Student{
	int number;
	
	public Student(int number) {
		this.number = number;
	}
	
	void print_number() {
		System.out.println("해당 학생의 번호는 "+number);
	}
}
public class StudentTest {

	public static void main(String[] args) {
		Student[] list;
		list = new Student[5];
		
		for (int i=0;i<list.length;i++) {
			list[i] = new Student(i);
		}
		
		for (int i=0;i<list.length;i++) {
			list[i].print_number();
            //해당 학생의 번호는 0
			//해당 학생의 번호는 1
			//해당 학생의 번호는 2
			//해당 학생의 번호는 3
			//해당 학생의 번호는 4
		}
	}
}
  1. 참조 변수 선언

    자바에서는 배열이 객체이기 때문에 배열을 참조할 수 있는 참조변수가 필요하다.

    Student[] list;
    
  2. 배열 객체 생성

    list = new Student[5];
    
  3. 배열의 크기만큼 객체를 생성하여 배열 요소에 저장

    for (int i=0;i<list.length;i++) {
    			list[i] = new Student(i);
    		}
    

동적 객체 배열

일반적인 배열은 크기가 정해져 있으므로 이를 변경하기 힘들다. 따라서 크기가 가변하는 동적 객체 배열을 사용한다.

import java.util.ArrayList;

public class ArrayListTest {
	
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();
		list.add("고양이");
		list.add("강아지");
		list.add("금붕어");
		
		for (int i =0;i<list.size();i++) {
			System.out.println(list.get(i));
            //고양이
			//강아지
			//금붕어
		}
	}
}
  1. ArrayList 생성

어떤 객체를 저장할지를 <> 안에 적어준다.

ArrayList<String> list = new ArrayList<String>();
  1. 메소드
  • add 를 통해 객체를 추가한다.
  • size 를 통해 크기를 반환한다.
  • get을 통해 해당 인덱스의 값을 반환한다.

내부 클래스

자바에서는 클래스 안에서 클래스를 정의할 수 있다. 이를 내장 클래스라고 하고 내장 클래스도 여러 종류가 있지만 그 중 가장 많이 사용하는 내부 클래스에 대해서 알아보겠다.

내부 클래스의 장점은 접근성에 있다. 외부 클래스의 필드와 메서드를 전부 사용할 수 있으며, private로 선언되어있어도 접근이 가능하다. 예제를 통해 살펴보자.

class Outer {
	private int num;
	
	class Inner{
		public void print() {
			System.out.println("여기는 내부 클래스 입니다.");
			System.out.println("num="+num);
		}
	}
	void display() {
		Inner obj = new Inner();
		obj.print();
	}
}
public class InnerTest {

	public static void main(String[] args) {
		Outer obj = new Outer();
		obj.display();
        //여기는 내부 클래스 입니다.
		//num=0
	}
}

내부 클래스는 말 그대로 클래스 내부에 또 하나의 클래스를 정의하면 됩니다. 내부 클래스 안에서 외부 클래스의 private 변수에 참조할 수 있다.

class Inner{
		public void print() {
			System.out.println("여기는 내부 클래스 입니다.");
			System.out.println("num="+num);
		}
	}

내부 클래스를 사용하려면 객체를 생성해야 한다.

void display() {
		Inner obj = new Inner();
		obj.print();
	}