본문 바로가기
  • 비둘기다
  • 비둘기다
  • 비둘기다
코딩/JAVA Basics

[자바 JAVA] 클래스와 객체

by parzival56 2022. 12. 5.

차례

1. 객체 지향 프로그래밍

2. 클래스

3. 정적 멤버

 

객체 지향 프로그래밍

객체 지향이란 프로그래밍의 종류의 일환이지만 이를 이해하기 위해서는 객체의 정의를 살펴보아야 합니다. 

객체란 프로그래밍에선 독립적인 각각을 의미합니다. 독립적인 각각을 정의하여 이를 사용하는 것이 객체 지향 프로그래밍의 전반적인 개요인 것입니다. 

블로그의 첫 게시글에 있는 예와 똑같이 들어보겠습니다. 

예를 들어 본인이 자동차 공장의 공장장이라고 가정해봅시다. 자동차를 만드는데에는 여러 인력이 필요합니다. 그리고 그 인력들을 서로 다른 일을 하는데 배치를 하겠죠. 하나의 자동차를 만들기 위해서는 차체, 엔진, 바퀴, 내부, 도색 등 다양한 작업이 요구됩니다. 그러나 보통 1명에게 이 일들을 모두 시키지 않죠. 주로 차체 만들기 담당 몇 명, 엔진을 다루는 몇 명 등처럼 구성을 하죠. 여기서 객체란 이 담당을 의미합니다. 오직 본인이 맡은 역할만을 하는 것입니다.

코드로 비교해보겠습니다.

print(a);
print("a가 출력되었습니다.");

print(b);
print("b가 출력되었습니다.");

예를 들어 위와 같은 코드가 있습니다. (출력문은 귀찮아서 제대로 안 씀...) 여기서는 값을 출력하는 것과 해당 변수의 값이 출력되었다는 말을 반복합니다. 이와 같은 코딩은 하나의 수업을 하기 위해 계속 교생 선생님을 불러 초청하는 방식의 비효율적인 코딩입니다. 지금은 2번 밖에 본복하지 않았지만 만약 이를 몇 백 번씩 반복해야 한다면 계속 이를 쓸 수 없습니다.

class 이름 {
	void printer(i) {
    	print(i);
        print("i가 출력되었습니다");
        }
    }
    
    //메인함수
    
    이름.printer(a);
    이름.printer(b);

그러나 위와 같이 한 가지 작업을 하는 이름 속의 printer를 만들어 그 이름과 매개변수만 달리하여 메인 함수 내에 선언만 하면 되는 이러한 방식은 이전보다는 훨씬 효율적이라고 할 수 있습니다. 이 2줄을 출력하는 것은 별 일이 아니지만 만약 정말 많은 작업을 반복적으로 요구한다면 이를 필요시마다 계속 적을 수는 없기 때문에 이 복잡한 일을 하는 객체 하나를 생성하여 필요시마다 이를 불러내어 빠르게 작업을 마무리하는 것이 핵심이라고 할 수 있습니다. 그래서 노가다가 아니라 시간을 효율적으로 쓰며 빠르게 코딩을 하기 위해서 필수적인 개념이라고 할 수 있습니다.

 

객체의 특징으로는 상속과 다형성을 가지지만 이는 후에 설명하도록 하겠습니다.

 

클래스 (Class)

c언어를 접해보신 분들은 아시겠지만 클래스는 구조체와 굉장히 비슷한 개념입니다. 구조체는 여러 타입의 변수들을 하나의 구조체에 저장함으로써 이들을 한꺼번에 쉽게 다루기 위한 개념인데 클래스는 구조체에 함수가 결합한 개념이라고 보시면 될 것 같습니다. 

클래스는 흔히 파일을 생성하시면서 가장 많이 들어본 단어 중 하나일텐데 소스파일에서 생성하시는 클래스와 같은 말이 맞습니다. 클래스를 새롭게 생성해보시면 여러분이 정한 이름으로 public class 이름이라고 나오는데 이것이 바로 클래스를 생성한 것이죠. 그러나 public class는 해당 파일의 이름이기에 한 소스코드에 하나밖에 들어가지 못합니다. 그러나 public class 말고도 그냥 class라고 쓰면 무한정하게 사용할 수 있습니다.

class Ball {
   double radius = 2.0;
   double getVolume() {
    	return 4 / 3 * 3.14 * radius * radius * radius;
    }
}

class는 위와 같이 선언합니다. 그냥 class에 이름만 써서 선언합니다. public과 같은 선행 키워드는 접근제어지시자로 해당 이름을 접근시킬 범위를 정하는 단어입니다. 

 

클래스를 선언하였으면 이를 사용을 해야할텐데 이를 사용하기 위해서는 객체를 생성 후 클래스 변수를 설정해야 합니다. 

객체 생성은 문자열 배열 등과 마찬가지로 new 클래스();로 생성해줍니다. 

클래스 변수를 선언하기 위해서는 클래스이름 변수 = new 클래스 이름();으로 생성합니다. 클래스 변수라는 개념을 예로 들자면 클래스는 자동차의 엔진을 만드는 직책입니다. 그러면 변수를 이 엔진을 만드는 일자리에 고용된 사람을 뜻하는 것입니다. 

 

클래스는 크게 필드, 메서드, 생성자로 구성됩니다.

필드에 들어갈 내용으로는 객체의 고유 데이터와 객체가 가져야할 부품 객체가 있습니다. 만약 우리가 일반적인 main함수에 int a = 10;이라는 문장을 치면 a는 보통 변수의 이름이라고 부릅니다. 그러나 클래스에서는 이를 필드명이라고 부릅니다. 위의 코드에서는 radius가 필드명이 됩니다. 이 필드도 마찬가지로 값을 선언해도 되고 안 해도 됩니다. 

클래스 내부에서는 선언한 필드명을 바로 사용하면 접근이 가능하지만 클래스 외부에서는 외부객체이름.필드이름으로 접근합니다. 

class Car {
   int maxspeed = 200;
   int speed;
}

//메인함수
Car car = new Car();

print(car.maxspeed); // 200
print(car.speed); // 0

다음은 메서드입니다. 메서드는 여태까지 쓰던 형식과 같지만 지금은 메서드의 성질 중 하나인 오버로딩에 대한 설명을 하겠습니다. 오버 로딩은 상속에 나올 오버 라이딩과 이름이 비슷해 헷갈리는 개념입니다.

오버 로딩을 사용하는 이유는 보통 같은 작업이지만 매개변수를 입력한 상태인지 아니면 하지 않은 상태가 존재할 때 사용합니다. 예를 들어 a, b, c라는 변수를 출력하는 메서드를 만들고 싶지만 a만 알아서 b, c는 메서드 내에서 입력을 받아 처리할 때나 a, b, c를 모두 알아서 그냥 출력해도 되는 경우가 있습니다. 

이럴 때 오버로딩을 사용하는 데 사용 방법은 return타입은 무관, 클래스 이름은 무조건 같게 그리고 타입, 변수, 개수, 순서 등이 달라야 합니다. 

int sum(int x, int y) {
    int result = x + y;
    return result;
}

double sum(double x, double y) {
    double result = x + y;
    return result;
}

위와 같은 경우도 오버로딩인데 이러한 경우는 메인 함수에서 숫자를 입력받을 때 이가 정수라면 위의 sum을 실수라면 밑의 sum을 사용할 것입니다. 그래서 모두 같이 더해주는 의미의 sum이지만 매개변수의 형식이 달라질 때 오버 라이딩을 사용합니다.

 

마지막으로 생성자입니다. 

생성자는 new 연산자가 사용되어 객체가 생성되었을 때 호출되어 객체의 초기화를 담당하는 역할입니다. 

생성자의 이름은 클래스 내에 존재하며 클래스의 이름과 똑같이 설정합니다. 생성자 또한 메서드와 같이 오버로딩이 가능하고 특별한 반환 타입은 존재하지 않습니다. 모든 클래스는 최소 하나 이상의 생성자를 필요로 하고 만약 생성자를 선언하지 않는다면 컴파일러가 자동으로 생성자를 추가합니다. 

class Korean {
   String nation = "대한민국";
   String name;
   String id;
   
   // Korean에 대한 생성자
   Korean (String nation, String name, String id) {
    this.nation = nation;
    this.name = name;
    this.id = id;
   }
}

생성자는 밑의 객체에서 얼마나 많은 정보를 입력받고 들어가느냐에 따라 오버로딩이 필요한 경우가 존재합니다.  만약 Korean의 객체 me가 Korean me = new Korean("미국", "김철수")로 선언된다면 위의 생성자는 사용할 수 없게 됩니다 왜냐하면 id를 객체에서 입력받지 못했기 때문입니다. 그러나  Korean me2 = new Korean("미국", "김영희", "hello");라고 하면 정상적으로 객체가 생성됩니다. 그래서 만약 me도 생성하고 싶다면 밑의 코드와 같이 하나를 더 생성해줍니다.

Korean(String nation, String name) {
    this.nation = nation;
    this.name = name;
}

여기서 나오는 this는 짧게 설명하자면 호출한 객체를 의미합니다. 그래서 생성자의 의미를 살펴보면 me를 예로 들었을 때 me에서 설정한 nation인 미국이 Korean이라는 클래스의 필드명 nation의 값이 되고, me의 name인 김철수가 Korean 클래스의 필드명 name의 값이 된다는 말입니다. 

 

정적(static) 멤버

정적 멤버의 특징이라고 한다면 객체를 생성하지 않고도 바로 접근하여 사용할 수 있다는 것입니다. static 멤버가 클래스 안에 있어 객체를 생성한다 한들 static 멤버는 객체 내부가 아닌 메서드의 영역에 존재하기 때문에 객체를 통한 접근이 필요가 없어집니다.

// 옳은 사용
class calc {
	static double pi = 3.141592;
}
// 메인 함수
double result1 = 10 * calc.pi;

// 옳지 않은 사용
calc mycalc = new calc();
double result2 = 10 * mycalc.pi;

이상 자바에서 중요한 클래스에 대해 알아봤습니다.

'코딩 > JAVA Basics' 카테고리의 다른 글

[자바 JAVA] 다형성  (0) 2022.12.05
[자바 JAVA] 상속  (0) 2022.12.05
[자바 JAVA] 참조 변수, 문자열, 배열  (0) 2022.12.04
[자바 JAVA] 변수, 자료형, 연산자  (0) 2022.11.07
[자바 JAVA] 자바의 기초 상식  (0) 2022.10.21

댓글