[Java] 클래스, 객체, 필드와 메서드

김세림·2024년 4월 25일

Java

목록 보기
8/24
post-thumbnail

클래스, 객체, 필드와 메서드


클래스

클래스 설계

  1. 클래스 선언 - 설계도를 이렇게 만들거다~
  2. 필드 정의 - 이 설계도엔 이런 속성이 필요하다
  3. 생성자 정의 - 어떻게 생성할지 방식 정하기!
  4. 메서드 정의 - 어떤 행동을 할지 정하기
//ex)
public class Car {//클래스 선언

//필드 정의
    double speed;  // 자동차 속도 , km/h
    char gear; // 기어의 상태, P,R,N,D
    boolean lights; // 자동차 조명의 상태

//생성자 정의
    public Car() {} 
    // 기본 생성자 : ()괄호 안에 아무것도 없는 생성자
    // 생성자는 반환타입이 없고 클래스 이름과 동일하다.

//메서드 정의
    double brakePedal(char type) { 
    //반환타입이 double이며, 매개변수인 type을 통해 매개값을 전달받는다.
        speed = 0; //전역변수 speed를 0으로 만든다.
        type = 'P'; 
       	// 정지 후 매개변수 type을 어떤 타입으로 전달 받았는지 상관없이 'P'로 고정
        return speed; //return 은 speed(double)을 반환한다.
    }
    //반환타입이 무엇이냐에 따라 return 값이 달라진다.
}

객체

객체 생성

new 객체생성 연산자를 사용하여 생성가능하다.

Car car = new Car(); 
// Car();의 형태로 기본생성자의 형태와 같기때문에 
// 해당 객체가 생성될 때 기본 생성자가 호출된다.

위 예시처럼 해당 인스턴스의 주소가 반환되기 때문에 해당 클래스의 참조형 변수를 사용하여 받는다.

또한, 객체는 참조형 변수와 동일하게 취급되기 때문에 배열 또는 컬렉션에도 저장하여 관리가 가능하다.

public class Main {
    public static void main(String[] args) {
        Car[] carArray = new Car[3];
        Car car1 = new Car();
        car1.changeGear('P');
        carArray[0] = car1;
        
        Car car2 = new Car();
        car2.changeGear('N');
        carArray[1] = car2;
        
        Car car3 = new Car();
        car3.changeGear('D');
        carArray[2] = car3;

        for (Car car : carArray) {
            System.out.println("car.gear = " + car.gear);
        }
    }
}

// 출력
//car.gear = P
//car.gear = N
//car.gear = D

저번 포스팅인 객체지향이란?에서 말했듯 객체는 속성과 행위, 즉 필드메서드로 구성되어있다. 이에 대해 알아보자.

필드(속성)

필드란?

객체의 데이터를 저장하는 역할을 한다.

위 그림처럼 고유, 상태, 객체로 크게 분류할 수 있으며,
이 객체에서 변하지않을 값을 말하고, 상태데이터는 바뀔 수 있는 값, 객체 데이터는 한 객체에서 하위 객체를 포함하는 값이다.

사용방법

필드를 초기화 하는 방법은 변수 초기화 방법과 동일하다.
(그 변수가 객체의 필드(속성)이 될 것이기 때문)
하지만 초기화를 하지않았을 때는 초기값으로 세팅이 되어있는데
숫자같은 경우에는 0, 문자형은 공백, 이밖에 배열이나 클래스, 인터페이스 등은 null값으로 세팅되어있다.

이렇게 세팅이 된 필드를 인스턴스화 한 후 사용하는 방법은 두가지가 있다. (클래스에 필드를 선언했다고 바로 사용할 수 있는 것이 아니라 실제 데이터를 가지고 있는 객체를 생성 한 후 사용 가능하다는 뜻이다.)

외부 접근

  • 도트(.)연산자를 사용하여 접근한다.

내부 접근

  • 메서드 내부에서 객체의 필드를 바로 호출하여 사용한다.
//외부 접근
Car car = new Car(); // 객체 생성

car.speed = 100;

//내부접근
double speed;

double brakePedal() {
    speed = 0;
    return speed;
}

메서드(행위)

메서드란?

객체의 행위를 뜻하며 객체간의 협력을 위해 사용한다.
메서드의 선언은 아래와 같다.

리턴타입 메서드 명(매개변수, ...){
	(실행할 연산)
}

여기서 리턴타입과 매개변수를 알아보자!

리턴타입

메서드가 실행된 후 호출을 한 곳으로 값을 반환할 때의 데이터 타입을 의미한다.
아까 위에 예시로 든 브레이크 페달을 본다면

double speed;

double brakePedal() { //리턴타입이 double이다.
    speed = 0;
    return speed; //return 값은 speed(double)이다.
}

리턴타입은 double이며 return 을 하는 speed 또한 double로 필드를 작성한 것을 볼 수 있다.
만약 리턴할 필요가 없다면 리턴타입에 void를 작성해야하며, return문도 작성하지않아도 된다.
하지만, 메서드는 실행하다 return 문을 만나면 그대로 종료하게되는데 void에서도 이것을 사용하여 원하는 지점에서 종료할수도 있다.

매개변수(매개값, 파라미터)

매개변수는 메서드를 호출할때 메서드로 전달하려는 값을 받기 위해 사용하는 변수이다.

double gasPedal(double kmh, char type) { 
//리턴타입은 double / 매개변수는 kmh(double), type(char) 두개가 들어온다.
    speed = kmh; //받은 kmh를 전역변수 speed에 저장하여
    return speed; //return한다.
}

위 예제처럼 매개변수에 값을 전달하기 위해서는 순서와 타입을 맞춰 값을 넣어서 메서드를 호출하면된다.
gasPedal(100, 'D')
매개변수를 지정하지않고 위의 브레이크페달처럼 생략하여도 되고,
가변길이의 매개변수도 ...을 사용하여 선언이 가능하다.

void carSpeeds(double ... speeds) {
    for (double v : speeds) {
        System.out.println("v = " + v);
    }
}

기본형 & 참조형 매개변수

  • 기본형 매개변수
    • only read
    • 매개변수 타입이 기본형으로, 매개값 자체를 복사해서 넘기기 때문에 원본 값이 변경되지않는다.
// 기본형 매개변수
Car car = new Car();
char type = 'D'; //기본형 변수 type 초기화
car.brakePedal(type); //car클래스의 브레이크 메서드 호출

// 메서드 실행 완료 후 매개변수로 전달한 type 값 확인
System.out.println("type = " + type); 
// 기존에 선언한 값 'D' 출력, 원본 값 변경되지 않음

// 메서드 실행 완료 후 반환된 car 인스턴스의 gear 타입 확인
System.out.println("gear = " + car.gear); 
// 객체 내부에서 type을 변경하여 수정했기 때문에 'P' 출력
  • 참조형 매개변수
    • read & write
    • 매개값으로 지정한 값의 주소를 매개변수에 복사해 전달하므로 해당 주소값의 실제값을 변경 할 수 있다.
// Car 클래스
Tire setTire(Tire tireCompany) {
        tireCompany.company = "KIA"; // 금호 타이어를 전달 받았지만 강제로 KIA 타이어로 교체
        tire = tireCompany;
        return tire;
    }
// Tire클래스
public class Tire {
    String company; // 타이어 회사
    public Tire() {}
}
// Main 클래스
Tire tire = new Tire(); //타이어 객체 생성
tire.company = "금호";  //타이어 객체의 company를 금호로 초기화

Tire carInstanceTire = car.setTire(tire);//위에 생성한 tire객체를 매개변수로함.
//참조형 변수 carInstanceTire에 car.setTire 메서드를 호출하여 저장

System.out.println("tire.company = " + tire.company); 
// 전달할 매개값으로 지정된 tire 인스턴스의 주소값이 전달되었기 때문에 호출된 메서드에 의해 값이 변경됨.

// 메서드 실행 완료 후 반환된 car 인스턴스의 tire 객체 값이 반환되어 저장된 참조형 변수 carInstanceTire의 company 값 확인
System.out.println("carInstanceTire.company = " + carInstanceTire.company); // "KIA" 출력

메서드 호출방법

이것도 필드의 접근 방법과 똑같이 외부 접근, 내부 접근이 있다.

외부 접근

도트(.)연산자를 사용하여 호출한다.

내부 접근

같은 객체라면 바로 호출하여 사용이 가능하다.

//외부접근
public class Main {
    public static void main(String[] args) {
        Car car = new Car(); // 객체 생성

        // 메서드 호출 및 반환값 저장
        //여기서 gasPedal의 반환값이 double이므로 speed 변수를 만들어 저장할 수 있다.
        double speed = car.gasPedal(100, 'D');
        System.out.println("speed = " + speed);

        // gasPedal 메서드 내부에 호출된 changeGear(type); 메서드의 결과 확인
        // gear의 초기값은 'P'
        System.out.println("car.gear = " + car.gear); // 'D' 출력

        car.carSpeeds(100, 80); //100, 80 출력
        
        car.carSpeeds(110, 120, 150); // 110, 120, 150 출력
    }
}

//내부 접근
double gasPedal(double kmh, char type) {
        changeGear(type); //객체 내부의 다른 메서드를 바로 호출
        speed = kmh;
        return speed;
    }
char changeGear(char type) {
        gear = type;
        return gear;
    }

메서드 오버로딩

나중에 배울 오버라이딩이랑 이름이 비슷해서 헷갈릴 수 있지만 다른 개념이니 따로따로 정의를 새겨넣어야겠다!

오버로딩이란?

하나의 메서드 이름으로 여러기능을 구현하도록 하는 것
응답값, 접근 제어자만 다른 것은 오버로딩 할 수 없으며, 매개변수의 차이로만 구현할 수 있다.
-> 매개변수의 갯수, 타입, 순서가 다르면 동일한 이름을 사용해 메서드를 정의할 수 있어 메서드 이름을 절약할 수 있게 된다.
ex) println()을 예로 들었을 때 double일때, String일때 다 다르면 printlnDouble(), printlnString()과 같이 메서드명이 길어지고 낭비된다.

0개의 댓글