티스토리 뷰
자바를 공부한지 5일차?
사실 생성자, 클래스 개념이 애매했는데
이제야 가닥이 잡히는 것 같아서....심장이 떨린다
더 이해하고, 아는 게 많아질수록 더 깊이있게 배울 수 있을 것 같다.
혹여나, 코드를 잘못 해석했다면 지적해주세요...제발...ㅎㅎ
참조: https://wikidocs.net/225#_3
05-03 메서드 더 살펴보기
다른 프로그래밍 언어에는 함수가 별도로 존재한다. 하지만 자바는 클래스를 떠나 존재하는 것은 있을 수 없기 때문에 자바의 함수는 따로 존재하지 않고 클래스 내에 존재한다. 자바는…
wikidocs.net
메소드
- 핵심 키워드
- 선언부, void, 매개 변수, 리턴문, 호출, 오버 로딩
- 핵심 포인트
- 메소드를 선언하고 호출하는 방법에 대해 알기
- 메소드 쉽게 이해하기
- 믹서를 떠올려 보자. 주스를 만들기 위해 믹서에 과일을 넣는다. 그리고 믹서를 이용해서 과일을 갈아 주스를 만들어 낸다.
- 믹서에 넣는 과일 = 입력
- 만들어진 주스 = 출력(리턴값)
- 그렇다면 믹서는?
- 메서드이다. 입력값을 가지고 어떤 일을 수행한 후, 결과값을 내어놓는 것이 메서드가 하는 일이다.
메소드 (method)
- 클래스는 멤버로, 속성을 표현하는 필드(field)와 기능을 표현하는 메소드(method)를 가진다.
- 그 중, 메소드란 어떠한 특정 작업을 수행하기 위한 명령문의 집합이다.
메소드의 사용 목적
- 중복되는 코드의 반복적인 프로그래밍을 피할 수 있다.
- 모듈화로 인해 가독성도 좋아진다.
- 프로그램에 문제가 발생하거나, 기능 변경이 필요할 때 손쉽게 유지 보수를 할 수 있다.
int sum(int a, int b){
return a+b;
}
이 메서드는 다음과 같이 정의된다.
sum 메서드는 입력값으로 두개의 값 (int 자료형 a, int 자료형 b)을 받으며 리턴값은 두 개의 입력값을 더한 값(int 자료형) 이다.
여기서 return은 메서드의 결과값을 돌려주는 명령어이다.
public class Sample {
int sum(int a, int b) { // a, b는 매개변수이다.
return a + b;
}
public static void main(String[] args) {
int a = 3;
int b = 4;
Sample sample = new Sample();
int c = sample.sum(a,b); // 3,4는 인수이다.
System.out.printl(c);
}
}
7
매개변수와 인수
- 매개변수 (parameter)
- 메서드에 전달된 입력값을 저장하는 변수
- 인수(arguments)
- 메서드를 호출할 때 전달하는 입력값
메소드의 입력값과 리턴값
입력값 ---> 메서드 ----> 리턴값
메소드의 구조
리턴자료형 메서드명(입력자료형1 매개변수1, 입력자료형2 매개변수2, ...) {
...
return 리턴값; // 리턴자료형이 void 인 경우에는 return 문이 필요없다.
}
- 리턴 자료형은 메소드 수행 후 리턴되는 값의 자료형을 의미한다. 메소드는 결괏값을 반환하기 위해 return이라는 키워드를 사용한다.
메소드 정의 방법
접근제어자 반환타입 메소드이름 (매개변수목록) {//선언부
//구현부
}
- 접근제어자: 해당 메소드에 접근할 수 있는 범위
- 반환 타입(return type): 메소드가 모든 작업을 마치고 반환하는 데이터의 타입
- 메소드 이름: 메소드를 호출하기 위한 이름 명시
- 매개변수 목록(parameters): 메소드 호출 시에 전달되는 인수의 값을 저장할 변수들을 명시
- 구현부: 메소드의 고유 기능을 수행하는 명령문의 집합
- 예제
class Car {
private int currentSpeed;
private int accelerationTime;
public void accelerate(int speed, int second) { //선언부
//구현부
System.out.println(second + "초간 속도를 시속" + speed + "(으)로 가속함!!");
}
- accelerate() 메소드를 정의하고 있다.
- public 접근 제어자를 사용하여 선언되어, 해당 객체를 사용하는 프로그램 어디에서나 직접 접근할 수 있다.
- 반환 타입에는 어떠한 값도 반환하지 않는다는 의미를 가진 void를 명시한다.
- 메소드 이름을 명시하고, 매개변수로 int형 변수인 speed, second를 전달받는다.
리턴 타입
- 메소드를 실행한 후의 결과값의 타입
- 리턴값 없을 수도 있음
- 리턴값이 있는 경우, 리턴 타입이 선언부에 명시
void powerOn() { ...}
double divide( int x, int y) {...} //divide라는 메소드는 결과값을 리턴해야하니 double이라는 리턴타입 명시
- 리턴값 존재 여부에 따라 메소드 호출 방법도 다름.
powenOn();
double result = divide( 10, 20);
int result = divide( 10, 20); // 컴파일에러 발생한다. 값은 double이기 때문에.
매개변수 선언
- 메소드 실행에 필요한 데이터를 외부에서 받아 저장할 목적
double divide( int x, int y) {...}
- divide가 실행되기 위해선 2개의 데이터가 있어야하고, 외부에서 int인 x, y값을 저장해서 divide하고 → double 타입으로 반환한다.
double result = divide( 10, 20 );
byte b1 = 10;
byte b2 = 20;
double result = divide( b1, b2);
- int 타입에 byte가 올 수 있다. 자동 타입 변환되어 정상 작동한다.
메소드의 입/출력 유무에 따른 분류
이 파트는 직접 코드 쳐보면서 공부해야 할 것 같다.
입력과 출력이 모두 있는 메소드
일반적인 메소드는 입력값, 리턴값이 모두 있다.
int sum(int a, int b) {
return a+b;
}
- sum 메소드의 입출력 자료형은 아래와 같다.
- 입력값: int 자료형 a, int 자료형 b
- 리턴값: int 자료형
- sum 메소드의 사용 예는 아래와 같다.
Sample sample = new Sample();
int result = sample.sum(3,4);
- sample.sum.(3,4) 호출 후 리턴값을 저장하는 result의 자료형은 int로 해야만 한다.
- sum 메소드의 리턴 자료형이 int로 되어 있기 때문이다.
입력값이 없는 메소드
String say() {
return "Hi";
}
- say 메소드의 입출력 자료형은 아래와 같다.
- 입력값: 없음
- 리턴값: String 자료형
say라는 이름의 메소드를 만들었다. 입력 인수를 나타내는 괄호 안이 비어있다. 이렇듯, 입력 인수가 없을 경우에는 괄호 안을 비워 놓으면 된다.
public class Sample {
String say() {
return "Hi";
}
public static void main(String[] args) {
Sample sample = new Sample();
String a = sample.say();
System.out.println(a); // "Hi" 출력
}
}
Hi
리턴값이 없는 메서드
void sum(int a, int b) {
System.out.println(a+"과"+b+"의 합은 "+(a+b)+"입니다.");
}
- sum 메소드의 입출력 자료형은 다음과 같다.
- 입력값: int 자료형 a, int 자료형 b
- 리턴값: void (리턴값 없음)
- 리턴값이 없는 메소드는 명시적으로 리턴 자료형 부분에 void라고 표기한다. 리턴값이 없는 메소드는 다음과 같이 사용한다.
public class Sample {
void sum(int a, int b) {
System.out.printLn(a+"과 "+b+"의 합은 "+(a+b)+"입니다.");
}
public static void main(String[] args) {
Sample sample = new Sample();
sample.sum(3,4);
}
}
3과 4의 합은 7입니다.
- System.out.println문은 메소드 내에서 사용되는 문장일 뿐 리턴값은 없다.
정리하자면, 리턴값이 없는 메소드는 다음과 같이 호출할 수 있다.
객체.메소드명(입력인수1, 입력인수2, ...)
입력값과 리턴값이 모두 없는 메소드
void say() {
System.out.println("Hi");
}
say 메소드의 입출력 자료형은 다음과 같다.
- 입력값: 없음
- 리턴값: void
이 메소드를 사용하는 방법은 단 한 가지이다.
public class Sample {
void say() {
System.out.println("Hi");
}
public static void main(String[] args) {
Sample sample = new Sample();
sample.say();
}
}
Hi
정리하자면, 입력값도 리턴값도 모두 없는 메소드는 아래와 같이 호출할 수 있다.
객체.메소드명()
메소드 내에서 선언된 변수의 효력 범위
메소드 안에서 사용하는 변수의 이름을 메소드 밖에서 사용한 이름과 동일하게 사용한다면?
//메소드 내에서 선언된 변수의 효력 범위
package Test1;
public class methodTest {
void varTest(int a) {
a++;
}
public static void main(String[] args) {
int a = 1;
methodTest sample = new methodTest(); //객체를 생성했다.
sample.varTest(a);
System.out.println(a);
}
}
1
- main 메소드 분석
- main 메소드에서 → a 라는 int 자료형 변수 생성 → a에 1 대입
- varTest 메소드를 입력값으로 a를 주어 호출
- a의 값을 출력하게 했다.
- a의 값을 1만큼 증가시켰으니, 2가 되어야 할 것 같지만 결괏값은 1이다. 왜?
- 메소드에서 사용한 매개변수는 메소드 안에서만 쓰이는 변수이기 때문이다.
- varTest 메소드를 이용해서 main 메소드 외부의 a의 값을 1만큼 증가시킬 수 있는 방법은?
//메소드 내에서 선언된 변수의 효력 범위
package Test1;
public class methodTest2 {
int varTest(int a) {
a++;
return a;
}
public static void main(String[] args) {
int a = 1;
methodTest2 sample = new methodTest2(); //객체를 생성했다.
a = sample.varTest(a);
// sample.varTest(a);
System.out.println(a);
}
}
- varTest 메소드에 return 문을 이용하는 방법.
- varTest 메소드는 입력으로 들어온 값을 1만큼 증가시켜 리턴한다.
- varTest 입력값이 int 자료형이 아닌 객체인 경우는?
//메소드 내에서 선언된 변수의 효력 범위
//varTest 입력값이 int 자료형이 아닌 객체인 경우
package Test1;
public class methodTest2 {
int a; //객체변수 a
void varTest(methodTest2 sample) {
sample.a++;
}
public static void main(String[] args) {
methodTest2 sample = new methodTest2();
sample.a=1;
sample.varTest(sample);
System.out.println(sample.a);
}
}
🟡코드 뜯기
- int 자료형인 변수 a를 methodTest2 클래스의 객체 변수로 선언했다.
- 그리고**, varTest 메소**드는 methodTest2 클래스의 객체를 입력받아, 해당 객체의 a 값을 1만큼 증가시키도록 했다.
- 그리고 main 메소드에서는 varTest 메소드 호출 시 methodTest2 클래스의 객체인 sample을 전달하도록 수정했다.
- 즉, varTest 메소드의 입력 파라미터가 아닌 methodTest2 클래스의 객체라는 데에 집중해보자.
- 이렇게 메소드가 객체를 전달받으면 메소드의 객체는 전달받은 그 객체 자체로 수행되므로, 입력으로 전달받은 sample 객체의 객체 변수 a값이 증가하게 되는 것이다.
- this 활용하기
//메소드 내에서 선언된 변수의 효력 범위
//this 활용하기
package Test1;
public class methodTest4 {
int a;
void varTest() {
this.a++;
}
public static void main(String[] args) {
methodTest4 sample = new methodTest4();
sample.a = 1;
sample.varTest();
System.out.println(sample.a);
}
}
키워드 핵심
- 선언부: 리턴 타입, 메소드 이름, 매개변수 선언
- void: 리턴값이 없는 메소드는 리턴타입으로 void를 선언해야 한다.
- 매개 변수: 메소드 호출 시 제공되는 매개값이 대입되어 메소드 블록 실행 시 이용됨
- 리턴문: 메소드의 리턴값을 지정하거나 메소드 실행 종료를 위해 사용할 수 있다.
- 호출: 메소드를 실행하려면 '메소드 이름(매개값, ...) 형태로 호출
- 오버로딩: 클래스 내에 같은 이름의 메소드 여러 개 선언하는 것을 말함
메소드 실습
package sec04.exam01;
public class Calculator {
//Field
//Constructor
//Method
void powerOn() {
System.out.println("전원을 켭니다.");
}
}
package sec04.exam01;
public class CalculatorExample {
public static void main(String[] args) {
//new Calculator 객체가 가지고있는 메소드
Calculator myCalc = new Calculator();
//참조변수 myCalc로 접근을 해서 메소드 호출
myCalc.powerOn();
}
}
🟡 코드 뜯기
메소드, 생성자, 메소드 호출 흐름 완벽하게 이해하고 넘어가기.
1. Calculator 라는 클래스를 생성했습니다.
2. pownrOn() 이라는 메소드를 생성합니다. 결과값을 리턴할 필요가 없으니 앞에 리턴 타입 안 적어줘도 된다.
3. 인스턴스 객체를 생성합니다. Calculator myCalc = new Calculator();
4. new Calculator(); 라는 객체의 참조변수 myCalc로 Calculator 클래스에 접근을 한다.
5. myCalc.powerOn(); 으로 메소드를 호출해준다.
- 메소드 추가
public class Calculator {
//Field
//Constructor
//Method
void powerOn() {
System.out.println("전원을 켭니다.");
}
int plus(int x, int y) {
int result = x + y;
return result;
}
double divide(int x, int y){
double result = (double) x / (double) y;
return result;
}
void powerOff() {
System.out.println("전원을 끕니다.");
}
}
package sec04.exam01;
public class CalculatorExample {
public static void main(String[] args) {
//new Calculator 객체가 가지고있는 메소드
Calculator myCalc = new Calculator();
//참조변수 myCalc로 접근을 해서 메소드 호출
myCalc.powerOn();
// int result1이라는 변수를 선언하고, plus 메소드가 리턴해주는 결과값을 int result1에 저장한다.
int result1 = myCalc.plus(5,6);
System.out.println("result1: " + result1);
// byte 타입으로 줬지만, class에서 int 타입으로 저장하기 때문에 byte는 int로 자동변환된다.
byte x = 10;
byte y = 4;
double result2 = myCalc.divide(x,y);
System.out.println(result2);
myCalc.powerOff();
}
}
매개 변수의 개수를 모를 경우
- 매개 변수를 배열 타입으로 선언할 수 있다.
package sec04.exam02;
public class Computer {
//Field
//Constructor
//Method
int sum1 (int[] values) { //매개변수 개수가 정해지지 않았기 때문에, 배열로 매개변수 선언, int타입으로 리턴되기에 리턴타입 int로 설정. sum1은 배열의 요소를 모두 더해서 결과값으로 리턴해줌
int sum = 0; //매개변수를 전체 더하는 코드를 작성, int 타입의 작성변수 0으로 초기화
for(int i = 0; i<values.length; i++) { //length는 배열 안에있는 요소의 수.
sum += values[i];
}
return sum;
}
int sum2 (int ... values) {
int sum = 0;
for(int i = 0; i<values.length; i++) {
sum += values[i];
}
return sum;
}
}
package sec04.exam02;
public class ComputerExample {
public static void main(String[] args) {
Computer myCom = new Computer(); //myCom 변수 선언하고, new 연산자로 Computer 생성자 호출
int[] values1 = {1,2,3}; //배열을 생성한다. 요소는 1,2,3이다.
myCom.sum1(values1); //sum1이라는 메소드를 호출한다. Computer 생성자가 있어야 사용할 수 있는 메소드이기 때문에 myCom 참조 변수로 접근해야한다.
int result1 = myCom.sum1(values1);
System.out.println("result: " + result1);
int result2 = myCom.sum2(new int [] {1,2,3,4,5});
System.out.println("result2: " + result2);
int result3 = myCom.sum2(1, 2, 3); //매개값으로 1,2,3 이라는 3개의 매개값을 받는다.
System.out.println("result3 " + result3);
}
}
🟡 코드 뜯기
Computer.java
1. int sum1 (int[] values) { OR int sum2 (int ... values) {
- 매개변수 개수가 정해지지 않았기 때문에, 배열로 매개변수를 선언했다. int 타입으로 리턴되기에, 리턴타입 int로 설정했다.
- 배열 타입으로 선언하거나 값의 목록만 넘겨주는 방식으로 매개변수를 선언할 수 있다.
2. int sum = 0;
- 매개변수 전체를 더하는 코드를 작성했다. int 타입의 작성변수를 0으로 초기화했다.
3. for(int i = 0; i<values.length; i++) {
- length는 배열 안에 있는 요소의 개수이다.
ComputerExample.java
1. Computer myCom = new Computer();
- myCom 참조 변수를 선언하고, new 연산자로 Computer 생성자를 호출했다.
2. int[] values1 = {1,2,3};
- 배열을 생성한다. 요소는 1, 2, 3 이다.
3. myCom.sum1(values1);
- sum1이라는 메소드를 호출한다. Computer 생성자가 있어야 사용할 수 있는 메소드이기 때문에 myCom 참조변수로 접근했다.
4. int result3 = myCom.sum2(1, 2, 3);
- 매개값으로 1, 2, 3 이라는 3개의 매개값을 받는다.
리턴값이 없는 메소드
package sec04.exam03;
public class Car {
//Field
int gas;
//Constructor
//Method
void setGas(int gas) {
this.gas = gas; // this.gas의 gas는 필드의 gas를 말 한다. = gas; 의 gas는 int gas를 말하며 매개변수이다. 즉, 외부로부터 받은 gas를 다시 필드에 저장하는 메소드이다.
}
boolean isLeftGas() {
if(gas == 0) {
System.out.println("gas가 없습니다.");
return false; //만약 gas가 0이라면 false
}
System.out.println("gas가 있습니다.");
return true; //만약 gas가 0이 아니라면 true
}
void run() {
while(true) { //반복문
if(gas >0) {
System.out.println("달립니다.(gas잔량: " + gas + ")");
gas -= 1; //gas>0이라면 gas -1씩 감소
} else {
System.out.println("멈춥니다.(gas잔량: " + gas + ")");
return; //gas<=0이라면 멈춥니다 출력. 종료
}
}
}
}
package sec04.exam03;
public class CarExample {
public static void main(String[] args) {
Car myCar = new Car();
myCar.setGas(5); //int의 매개값을 받는다. setgas의 매개값으로 5를 주었다.
boolean gasState = myCar.isLeftGas();
if(gasState) {
System.out.println("출발합니다.");
myCar.run(); //myCar 메소드 실행 - 반복실행하다가 Car 클래스의 while문 false되면 종료
}
if(myCar.isLeftGas()) { // isLeftGas의 호출 결과값을 확인
System.out.println("gas를 주입할 필요가 없습니다."); //true 리턴되면
} else {
System.out.println("gas를 주입하세요."); //false 리턴되면
}
}
}
🟡코드 뜯기
1.void setGas(int gas) {
this.gas = gas;
- this.gas > 필드의 gas를 말한다.
- = gas; > int의 gas를 말하며 매개변수이다. 즉, 외부로 부터 받은 gas를 다시 필드에 저장하는 메서드.
객체 외부에서 호출
package sec04.exam05;
public class Car {
//Field
int speed;
//Constructor
//Method
int getSpeed() {
return speed; //외부로부터 값을 받지 않고, 필드의 speed 값을 받는다.
}
void keyTurnOn() {
System.out.println("키를 돌립니다.");
}
void run() {
for(int i=0; i<=50; i+=10) {
speed = i;
System.out.println("달립니다.(시속:" + speed + "km/h)");
}
}
}
package sec04.exam05;
public class CarExample {
public static void main(String[] args) {
Car myCar = new Car();
myCar.keyTurnOn();
myCar.run();
int speed = myCar.getSpeed();
System.out.println("(현재속도:" + speed + "km/h)");
}
}
메소드 오버로딩
//오버로딩 (메소드명이 똑같고, 매개변수의 수가 다른 메소드를 선언하는 것)
package sec04.exam06;
public class Calculator {
//Field
//Constructor
//Method
double areaRectangle(double width) { //정사각형 넓이 구하는 메소드
return width * width;
}
double areRectangle(double width, double height) { //직사각형 넓이 구하는 메소드
return width * height;
}
}
package sec04.exam06;
public class CalculatorExample {
public static void main(String[] args) {
Calculator myCalc = new Calculator();
double result1 = myCalc.areaRectangle(10); //하나는 width만 받고, 하나는 width와 height를 받는다. > 적사각형
double result2 = myCalc.areRectangle(10, 20); // > 직사각형
System.out.println("정사각형의 넓이 " + result1);
System.out.println("직사각형의 넓이 " + result2);
}
}
'Programming Language > JAVA (2) - 혼공자' 카테고리의 다른 글
[Java 혼자 공부하는 자바] 생성자 (0) | 2023.09.25 |
---|---|
[Java 혼자 공부하는 자바] 필드 (0) | 2023.09.24 |
[Java 혼자 공부하는 자바] 객체 지향 프로그래밍 (0) | 2023.09.23 |
[Java 혼자 공부하는 자바] 변수의 타입 - 기본(Primitive type), 참조(Reference type) (0) | 2023.09.23 |
[Java 혼자 공부하는 자바] for문, while문, do-while문, break문, continue문 (0) | 2023.09.23 |