📕 객체의 행위 - 메서드
1) 메서드 선언
리턴타입 메서드명(매개변수, ...) {
실행할 코드 작성
}
double brakePedal() {...} // double 타입 반환
char changeGear(char type) {...} // char 타입 반환
boolean onOffLights() {...} // boolean 타입 반환
void horn() {...} // 반환할 값 없음
리턴타입 기억할 점 :
메서드는 실행할 때 return문을 만나면 그대로 종료하게 되는데 void 타입일 때 return; ← 이렇게 return문을 사용하여 원하는 지점에서 메서드를 종료할 수도 있다
매개변수 기억할 점 :
위의 예시 horn()과 같이 전달하려는 매개변수 값이 없다면 생략이 가능하다
2) 메서드 호출
외부 접근 : 객체를 생성(Car car = new Car();) 했다면 참조변수 car을 이용해 외부에서 객체 내부의 메서드에 접근 가능 예) car.brakePedal(); 내부 접근 : 도트 연산자를 사용하여 외부에서 객체 내부에 접근할 수도 있고 객체 내부 메서드에서도 내부 메서드에 접근하여 호출 가능 예) double gasPedal(double kmh, char type) {
changeGear(type);
speed = kmh;
return speed;
}
📗 기본형/참조형 매개변수
기본형 매개변수 : 메서드를 호출할 때 전달한 매개값으로 지정한 값을 메서드의 매개변수에 복사하여 전달한다
=> 매개변수의 타입이 기본형일땐 값 자체가 복사되어 넘어가기 때문에 원본값은 변경 X
참조형 매개변수 : 메서드를 호출할 때 전달한 매개값으로 지정한 값을 메서드의 매개변수에 복사하여 전달한다
=> 매개변수를 참조형으로 선언하면 원본 주소를 알 수 있어서 읽어오는 것 뿐만 아니라 원본값 변경 O
=> 매개변수 뿐만 아니라 반환타입도 참조형이 될 수 있다
(반환타입이 참조형이라는 것은 반환하는 값의 타입이 "실제 값의 주소"라는 의미)
// 기본형 or 참조형 변수 차이점 알아보기
public class Main {
public static void main(String[] args) {
Car car = new Car(); // 객체 생성
// 기본형 매개변수
char type = 'D';
car.brakePedal(type);
// 메서드 실행 완료 후 전달할 매개값으로 지정된 type 값 확인
System.out.println("type = " + type); // 기존에 선언한 값 'D' 출력, 원본 값 변경되지 않음
// 메서드 실행 완료 후 반환된 car 인스턴스의 gear 타입 확인
System.out.println("gear = " + car.gear); // 객체 내부(Car.java)에서 type을 변경하여 수정했기 때문에 'P' 출력
// 결론 : 원본 객체는 변하지 않음 - 읽기만 가능하니 여기서 변경했다고 하더라도 돌아가서 P로 변경해버리는 거
System.out.println();
// 참조형 매개변수
Tire tire = new Tire();
tire.company = "금호"; // 금호 타이어(회사 이름) 객체 생성
// 차 객체의 타이어를 등록하는 메서드 호출한 후 반환값으로 차 객체의 타이어 객체 반환
Tire carInstanceTire = car.setTire(tire);
// 메서드 실행 완료 후 전달할 매개값으로 지정된 참조형 변수 tire의 company 값 확인
System.out.println("tire.company = " + tire.company); // "KIA" 출력
// 전달할 매개값으로 지정된 tire 인스턴스의 주소값이 전달되었기 때문에 호출된 메서드에 의해 값이 변경됨.
// 메서드 실행 완료 후 반환된 car 인스턴스의 tire 객체 값이 반환되어 저장된 참조형 변수 carInstanceTire의 company 값 확인
System.out.println("carInstanceTire.company = " + carInstanceTire.company); // "KIA" 출력
}
// 결론 : 원본도 다 바뀐 것을 알 수 있음
}
// Car.java의 breakPedal 부분
double brakePedal(char type) {
speed = 0;
type = 'P'; // 정지 후 매개변수 type을 어떤 타입으로 전달 받았는지 상관없이 'P'로 고정시키기
changeGear(type);
return speed;
}
// Tire.java의 tire 부분
public class Tire {
String company; // 타이어 회사
public Tire() {}
}
📘 인스턴스 멤버와 클래스 멤버
- 필드
class 구조 - 생성자 --> 여기서 필드 + 메서드 = 멤버
- 메서드
인스턴스 멤버와 클래스 멤버는 선언하는 방법에 따라 구분한다 (static 유무)인스턴스 멤버 : 객체 생성 후에 사용 가능 객체의 인스턴스 필드는 각각의 인스턴스마다 고유한 값을 가질 수 있다 (매번 객체의 메서드들이 인스턴스에 포함되어 생성되는 것은 아님 - 중복저장으로 메모리 효율이 떨어지기 때문) => 메서드는 메서드 영역에 두고 모든 인스턴스들이 공유해서 사용클래스 멤버 : 메서드 영역의 클래스와 같은 위치에 고정적으로 위치하고 있는 멤버를 의미 객체 생성 없이 사용 가능 일반적으로 인스턴스마다 모두 가지고 있을 필요가 없는 공용적인 데이터를 저장하는 필드에 사용
Car.company = "Audi"; // 이런 식으로 '클래스 이름과 도트(.)'로 바로 접근 가능
String companyName = Car.setCompany("Benz"); // 메서드(setCompany)도 마찬가지로 클래스 메서드로 바로 접근 가능
// +)
Car car = new Car();
car.company = "Ferrari";
String companyName2 = car.setCompany("Lamborghini");
// 이렇게 참조형 변수(new~)를 사용하여 클래스 멤버에 접근은 가능하지만 추천 X - static인데 굳이 이렇게 할 필요가 없다
// '클래스 이름'으로 접근하는 것이 좋다
// 예시
// Main.java
public class Main {
public static void main(String[] args) {
// 클래스 필드 company 확인
System.out.println(Car.company + "\n"); // 출력 : GENESIS
// 클래스 필드 변경 및 확인
Car.company = "Audi";
System.out.println(Car.company + "\n"); // 출력 : Audi
// 클래스 메서드 호출
String companyName = Car.setCompany("Benz"); // 객체를 생성한게 아니라 바로 찍어준 것임
System.out.println("companyName = " + companyName); // 출력 : Benz
// Car.java
public class Car {
static String company = "GENESIS"; // 자동차 회사 : GENESIS
static String setCompany(String companyName) { // 13열로 인해 companyName에 Benz 삽입
// System.out.println("자동차 모델 확인: " + model); // 인스턴스 필드 사용 불가
company = companyName;
return company;
}
'JAVA' 카테고리의 다른 글
빌더 패턴(Builder pattern)을 써야할까?, @Builder (0) | 2024.02.23 |
---|---|
object 클래스의 메서드와 instance of (1) | 2024.01.23 |
지역변수, 다형성 형변환, instanceOf (0) | 2024.01.04 |
배열(초기화, 복사..)과 컬렉션 종류 (1) | 2024.01.02 |
[JAVA] JAVA 이모저모 (0) | 2023.12.29 |