본문 바로가기

학원/복기

0405 - 객체 중심 프로그래밍(OOP), 메소드 선언 및 호출, return 키워드

배열에 저장된 모든 요소값을 오름차순 정렬하여 출력하는 프로그램 작성

 
절차지향적 방법으로 작성하는 방법)

public class ArraySortApp {
	public static void main(String[] args) {
		int[] array = {30, 50, 10, 40, 20};
		
		System.out.print("정렬 전 >> ");
		for(int num : array) {
			System.out.print(num + " ");
		}
		System.out.println();
		
		//배열 요소값을 선택 정렬 알고리즘을 사용하여 오름차순 정렬되도록 저장
		for(int i = 0; i < array.length - 1 ; i++) { 
			for(int j = i+1; j < array.length ; j++) { //피비교자
				if(array[i] > array[j]) {
					int temp = array[i];
					array[i] = array[j];
					array[j] = temp;
				}
			}
		}
		
		System.out.print("정렬 후 >> ");
		for(int num : array) {
			System.out.print(num + " ");
		}
		System.out.println();
	}
}

 

 
** 자바는 정형적인 객체지향적 언어이다.
     클래스가 제공해주는 메소드 활용해 요소값을 쉽게 오름차순으로 정렬할 수 있다.

 
Arrays 클래스 배열의 요소를 제어하는 기능의 메소드를 제공하는 클래스 
 
Arrays.toString(Object[] array) : 매개변수를 통해 배열을 전달받아 배열의 모든 요소값들을 
                                                        문자열로 변환하여 반환하는 메소드 

System.out.print("정렬 전 >> " + Arrays.toString(array));
		//정렬 전 >> [30, 50, 10, 40, 20]


Arrays.sort(Object[] array) : 배열을 전달받아 배열의 모든 요소값들을 오름차순 정렬하는 메소드 
 

Arrays.sort(array);
		System.out.println("정렬 후 >> " + Arrays.toString(array));
		//정렬 후 >> [10, 20, 30, 40, 50]

 


*OOP(Object Oriented Programming) : 객체 중심 프로그래밍 

- 객체를 이용하여 프로그램을 작성하는 방식 
- 현실에 존재하는 대상들을 모델링하여 클래스로 선언하고 선언된 클래스로 객체를 생성하여 객체의 요소를 사용하여  프로그램을 작성하는 방법 
- 클래스를 통해 생성된 객체 하나하나를 해당 클래스의 '인스턴스'라고 한다.
- 클래스를 사용하여 힙 영역(Heap Area)에 새로운 인스턴스(객체)를 생성할 수 있다.
     >> 따라서 인스터스란 현실의 객체를 소프트웨어 내에서 구현한 실체라고 볼 수 있다.


즉, 객체지향 프로그래밍이란 
 >> 여러개의 객체들이 서로 관계를 맺고, 메시지를 주고받는 방식(메소드 호출)을 통한 프로그램 작성 방식

자바는 현존하는 프로그래밍 언어 중 가장 객체 지향적 언어에 가깝다

*객체지향프로그래밍의 장점 
 >> '클래스' 자료형을 배포해, 프로그램을 보다 빠르게 만들 수 있음
 >> 수정할 때, 잘못된 객체 하나만 수정하면 된다. (쉬운 유지보수)

 
*객체 지향 프로그래밍의 4대 특성
 >> 추상화, 캡슐화, 다형성, 상속성

- 객체 모델링(Object Modeling) : 현실에 존재하는 대상을 속성과 행위로 구분하여 설계
 => 설계된 대상을 클래스(필드와 메소드)로 선언 - 추상화 (Abstraction)          ** 필드(상태) / 메소드(동작)

클래스는 배포가 가능하다 : 프로그램의 생산성 증가 및 유지보수의 효율성 증가

 


*Method

-메소드(Method) 클래스 내부에 선언된 함수 - 멤버함수
 => 필드(멤버변수)를 이용하여 필요한 기능을 제공하기 위한 명령들의 모임
 => 명령(Statement)은 메소드 내부에서만 작성 가능  
 
-함수(Function) : 매개변수로 값을 제공받아 계산하여 결과를 반환하는 명령들의 모임 -> 기능 제공 

 

** 함수와 메소드의 차이

함수 : 여러 문장들이 하나의 기능을 구현하도록 구성한 것.
그 함수 중에서 클래스 내부에 정의한 함수 -> 메소드 

또한 메소드는 객체의 속성을 다루기 위한 행위를 정의한 것이라는 의미도 포함.

>>> 즉, 독립적으로 존재하는 함수이냐, 클래스 내부에 종속되어 있느냐의 구분으로 함수와 메소드를 구분할 수 있다.



*메소드 선언하는 방법

형식 )  반환형 메소드명(자료형 변수명, 자료형 변수명, ...){
명령;    //메소드를 호출하면 실행되는 명령 
                         ... 
         }

-반환형(ReturnType) : 메소드를 호출하여 얻을 수 있는 결과값에 대한 자료형 
-> void 자료형(무반환형) : 메소드를 호출하여 얻을 수 있는 결과값이 없는 경우 사용하는 자료형 
                                         >> 메소드가 아무런 값도 반환 하지 않음 
 

** 반환형(ReturnType) 은 자료형 or void 가 올 수 있다.
      만약, 자료형이 리턴타입으로 오면 >> 반환(return)해 주는 값(메소드 자료형과 동일한 값)이 반드시 존재해야 한다.
                                                  void >> 반환값이 없다.
       즉, 반환하고자 하는 데이터가 있으면 그 데이터의 자료형을 메소드의 자료형으로 줘야한다.

 
 

-메소드명 : 식별자 (알기 쉽도록 작성하는 것이 좋다)  

-메소드의 () 기호 안에 변수를 나열하여 선언할 수 있다 - 매개변수 (Parameter - Argument)
 => 메소드에 작성된 명령을 실행하기 위해 필요한 값을 메소드 호출시 전달받아 저장하기 위한 변수  
 => 메소드에 작성된 명령을 실행하기 위한 값이 필요 없는 경우 매개변수 생략 가능 



*메소드 호출(Method Invoke) 

: 메소드에 작성된 명령들을 실행하여 필요한 기능 제공 
(클래스로 객체를 만들어 준 다음, 객체로 메소드 호출하여 사용)

형식) 객체.메소드명 (값, 값, ...);

 
 => 객체가 저장된 참조변수를 사용하여 객체의 메소드 호출 
 => 메소드 호출시 매개변수에 차례대로 값을 전달하여 메소드 호출 
 => 매개변수에 값이 정상적으로 전달되지 않으면 메소드 호출 불가능 - 에러 발생 


*return 키워드 

: 메소드를 강제로 종료하기 위한 키워드 
 
형식-1) if(조건식) return 
 => 메소드의 반환형을 [void]로 작성
반환하는 것이 없고, 메소드를 강제로 종료하는 것이기 때문

형식-2) return 반환값;
 => 메소드를 종료하면서 반환값(변수 또는 연산식)을 메소드를 호출하는 명령에게 제공 
 => 메소드의 반환형을 대상의 자료형과 동일하게 반드시 같도록 작성

 
 ** return문은 메소드 내에서 동작하고 얻은 결과(필요한 데이터)를 반환해주는 역할을 한다.
      return문을 사용하면 값을 반환해 주고 해당 메소드는 실행이 종료. 
 
 


객체 생성 예시

 
객체 생성(참조)이 목적인 클래스 >>  main 메소드 미작성 
실행이 목적인 클래스 >> main 메소드를 반드시 작성
 
 
객체 생성(참조)
객체 생성이 목적인 클래스 >> main 메소드 미작성

public class Method {
	void displayOne() { //매개변수가 없는 메소드 
		System.out.println("Method 클래스의 displayOne() 메소드 호출");	
	} 
	void displayTwo() { //메소드명은 '식별자' - 마음대로 지을 수 있지만 알기 쉽게 만들기
		System.out.println("Method 클래스의 displayTwo() 메소드 호출");
	}

 
객체를 실행하기 위해서는 메소드를 호출 해줘야 한다
그러기 위해선, 클래스를 통해 객체를 만들어 줘야 한다. -> 실행을 목적으로 하는 클래스 필요
 

 
실행
실행이 목적인 클래스 >> main 메소드를 반드시 작성 

 

public class MethodApp {
	//프로그램 실행시 JVM(Java Virtual Machine)에 의해 자동 호출하는 특별한 메소드
	public static void main(String[] args) {
		//클래스로 객체를 생성하여 객체의 메모리 주소를 참조변수에 저장 		
		// => 같은 패키지에 작성된 클래스는 패키지 표현없이 클래스 사용이 가능 
		//    (다른 패키지의 경우 import 사용)
		// => 참조변수를 사용하여 객체의 필드 또는 메소드 접근 가능 
		Method method = new Method();  //힙영역에 객체 생성된다.
		
		//참조변수를 출력할 경우 "자료형@메모리주소" 형식의 문자열을 제공받아 출력 
		System.out.println("method = " + method); //method = oop.Method@3b6eb2ec
		
        
		//메소드 호출 : 객체를 이용하여 메소드를 호출하면 프로그램의 흐름(스레드)은 객체의
		//              메소드로 이동하여 메소드의 명령을 실행하고
		// 				메소드가 종료되면, 메소드를 호출한 그 다음 차례의 명령 실행 
		method.displayOne(); // displayOne은 매개변수가 없는 메소드이므로, 값 입력 X
		method.displayOne();
		method.displayOne(); // 필요하면 메소드는 반복 호출도 가능 
		
		
		method.displayTwo(); //Method 클래스의 displayTwo() 메소드 호출
   }  
 }

 
 


메소드 예시

 
매개 변수 없는 메소드

 

//생성
void printOne() {
	int tot = 0;
	for (int i = 1; i <= 100 ; i++) {
	tot += i; 
	}
	System.out.println("1~100범위의 정수들의 합계 = " + tot);
}

//실행
public static void main(String[] args) {
    method.printOne(); //1~100범위의 정수들의 합계 = 5050
	method.printOne(); //1~100범위의 정수들의 합계 = 5050
}

 
 

매개변수 존재하는 메소드 
매개변수 쓰는 이유 - 값 전달받아 메소드 안에서 사용하려고
해당 메소드 호출할 때, 매개변수를 정수값으로 잘 줘야한다

 

	//생성
	void printTwo(int num) { 
		//매개변수에 저장된 값에 대한 검증 
		if(num <= 0) { //비정상적인 값이 전달되어 저장된 경우
			System.out.println("[에러]매개변수에는 0보다 큰 값을 저장되어야 됩니다.");
			return; //메소드 종료 -> 이후의 명령은 실행되지 않는다. 
		}  
		
		int tot = 0;
		for (int i = 1; i <= num ; i++) {
			tot += i;
		}
		System.out.println("1~" + num + " 범위의 정수들의 합계 = " + tot);
	}
    
    //실행
    public static void main(String[] args) {
    	method.printTwo(50); //1~50 범위의 정수들의 합계 = 1275
		method.printTwo(80); //1~80 범위의 정수들의 합계 = 3240
		
		//사용자가 메소드에 잘못된 값 전달시 
		method.printTwo(-30); //[에러]매개변수에는 0보다 큰 값을 저장되어야 됩니다.
							  //return -> 메소드 종료 
    }

 

매개변수가 여러개 존재하는 메소드
 

//생성
void printThree(int num1, int num2) { 
   
   /*
   if(num1 > num2) { //비정상적인 값이 전달되어 저장된 경우
      System.out.println("[에러]첫번째 전달값이 두번째 전달값보다 작아야 됩니다.");
      return; //메소드 종료 
   }  
   */
           //잘못된 값 입력시 치환시키는 방법 

           if(num1 > num2) {
           int temp = num1;
           num1 = num2;
           num2 = temp;
           }

           int tot = 0;
           for (int i = num1; i <= num2 ; i++) {
           tot += i;
           }
           System.out.println(num1 + "~" + num2 + " 범위의 정수들의 합계 = " + tot);
           }

//실행 
public static void main(String[] args) {
	    method.printThree(35, 79); //35~79 범위의 정수들의 합계 = 2565
		method.printThree(19, 88); //19~88 범위의 정수들의 합계 = 3745
		
		//사용자가 메소드에 잘못된 값 전달시 
		method.printThree(67, 12); //치환되어 출력 >> 12~67 범위의 정수들의 합계 = 2212
}

 

원래 클래스가 가진 메소드는 입출력을 하지 않고, 데이터를 처리할 때만 쓴다
(특정 프로그램 제외한 다른 프로그램에 가져다쓸 수 없기 때문에)
데이터 처리할 때 사용하면, 모든 형태의 프로그램에서 클래스가 독립적으로 동작 가능.
따라서 출력 대신 return 이용해 값을 반환받으면 된다.
 

 
return 이용해 값 반환 
 
변수에 저장된 값을 메소드를 종료하며 메소드를 호출하는 명령에게 반환 
=> 주의: 반환되는 값의 자료형과 메소드의 반환형이 반드시 동일해야 함 

//생성
int returnTot(int num1, int num2) {
		int tot = 0;
		for (int i = num1 ; i <= num2; i++) {
			tot+=i;
		}
		return tot;
	}
    
    
//반환값이 존재하는 메소드 호출 
// => '메소드의 반환값을 지속적으로 사용하고자 할 경우' 반환값을 변수에 저장.
//    (메소드 실행한 값을 다른 곳에서 사용하고 싶을 때, 반환해주는 것임)
		
// >> 반환값을 저장하는 행위는 꼭 필요한 행위는 아님.
//    반환값이 존재해도 필요 없으면 받지 않아도 된다.

public static void main(String[] args) {
	int result = method.returnTot(30, 70); 
		System.out.println("합계(메소드 호출의 반환값) = " + result);
		//합계(메소드 호출의 반환값) = 2050
		
		//메소드의 반환값을 일시적으로 사용할 경우 반환값을 변수에 미저장 
		//(반환값을 지속적으로 사용하지 않고 한번만 사용할 경우 직접 출력해도 된다) 
		System.out.println("합계(메소드 호출의 반환값) = " + method.returnTot(30, 70));
		//합계(메소드 호출의 반환값) = 2050
}

 
매개변수로 정수값을 전달받아 홀수와 짝수를 구분하여 반환하는 메소드 
=> false 반환 : 홀수, true 반환 : 짝수 
 

//생성

boolean isOddEven(int num) {
		if(num % 2 != 0) {
			return false;
		} else {
			return true;
		}
	}

//실행

public static void main(String[] args) {
	boolean result1 =  method.isOddEven(10);
		
		if(result1) {
			System.out.println("매개변수로 전달된 값은 [짝수]입니다.");
		} else {
			System.out.println("매개변수로 전달된 값은 [홀수]입니다.");
		} //매개변수로 전달된 값은 [짝수]입니다.
		
		
		
		//조건식 대신 메소드의 반환값 이용하여 명령을 선택 실행 
		
		//(변수가 많을수록 유지보수가 어려워지기때문에 변수에 반환값 저장하지 않아도 되면 
		//저장하지 않는 것을 권장) 
		
		if(method.isOddEven(9)) {
			System.out.println("매개변수로 전달된 값은 [짝수]입니다.");
		} else {
			System.out.println("매개변수로 전달된 값은 [홀수]입니다.");
		} //매개변수로 전달된 값은 [홀수]입니다.
}

 
배열을 반환하는 메소드 -> 호출할 때도, 배열을 받을 수 있는 참조변수로 받아야한다. 
 

//생성

int[] returnArray() {
		
		/*
		int[] array = {10,20,30,40,50};
		return array; //배열의 메모리 주소를 반환 - 배열 반환 
		*/
		
		//return {10,20,30,40,50} //에러 발생 (배열이 아님)
		
		return new int[]{10,20,30,40,50}; //변수값 저장하지 않고, 직접 배열 반환하는 방법 
		
	}

//실행
public static void main(String[] args) {
	int[] array = method.returnArray();
		for (int num : array) {
			System.out.print(num + " "); 
		} //10 20 30 40 50 									
}

 
 
매개변수 3개에 전달된 정수값들의 합계를 계산하여 반환하는 메소드 
 

//생성

int sumOne(int num1, int num2, int num3) {
		return num1 + num2 + num3;
	}
    
//실행

public static void main(String[] args) {
	System.out.println("합계 = " + method.sumOne(10, 20, 30)); //합계 = 60
		
		//매개변수의 값이 정상적으로 전달되지 않을 경우 메소드 호출에 대한 에러 발생 
		//System.out.println("합계 = " + method.sumOne());
		//System.out.println("합계 = " + method.sumOne(10,20));
		//System.out.println("합계 = " + method.sumOne(10,20,30,40));
}

 
매개변수로 배열을 전달받아 배열의 모든 요소값들의 합계를 계산하여 반환하는 메소드 
 

//생성

int sumTwo(int[] array) { //배열을 전달받는 매개변수 
		int tot = 0;
		for(int num : array) { //배열의 요소값들을 num에 저장 
			tot += num;
		}
		return tot; //합계반환
	}
    
//실행
public static void main(String[] args) {
	//System.out.println("합계 = " + method.sumTwo(10,20,30)); //배열이 아님(에러 발생)
																 
		
		//매개변수의 배열의 메모리 주소를 전달하여 메소드 호출 
		System.out.println("합계 = " + method.sumTwo(new int[] {10,20,30})); //합계 = 60
		

		//요소의 갯수는 상관 없지만 배열은 무조건 전달해 줘야 올바른 결과값 출력 
		System.out.println("합계 = " + method.sumTwo(new int[] {})); //요소가 없는 배열 
		// -> 합계 = 0
		System.out.println("합계 = " + method.sumTwo(new int[] {10,20})); //합계 = 30
		System.out.println("합계 = " + method.sumTwo(new int[] {10,20,30,40})); //합계 = 100
}

 
... : 매개변수 생략기호 (...)를 이용하여 매개변수를 작성하면 값을 0개 이상 전달받아 
      메소드에서 배열처럼 사용 가능
 

//생성
int sumThree(int...array) {
		int tot = 0;
		for(int num : array) { //배열의 요소값들을 num에 저장 
			tot += num;
		}
		return tot; //합계반환
	}
    
//실행 
public static void main(String[] args) {
	System.out.println("합계 = " + method.sumThree(10,20,30)); //합계 = 60
	System.out.println("합계 = " + method.sumThree()); //합계 = 0
	System.out.println("합계 = " + method.sumThree(10,20)); //합계 = 30
	System.out.println("합계 = " + method.sumThree(10,20,30,40)); //합계 = 100
}