Skill Tree🌲/coding_package

Java 웹개발자 과정 7일차 - 메소드

체다치즈 2022. 3. 16. 00:53
클래스와 클래스의 관계
has a  관계 is a 관계
포함관계 상속관계, 구현관계
Car has a tire Galaxy is a SmartPhone
Car has a engine Iphone is a SmartPhone

Java 웹개발자 6일차 과정 중에서

String과 Student는 has a 관계이다.

 


 

public class StudentScore {
	
	String name;
	int kor;
	int eng;
	int math;

}

 

// 이번 시험에 5명의 학생이 시험에 응시했다.
// 학생 각각의 점수를 저장하는 StudentScore객체를 생성하고, 객체의 필드에 학생이름, 성적을 저장한다.
// 5명 학생의 시험점수를 하나의 이름으로 관리하기 위해서 StudentScore을 여러개 저장하는 배열객체를 생성한다.
// 배열객체에 순서대로 학생객체의 참조값을 저장한다.
// 배열객체에 저장된 모든 학생의 이름, 국어점수, 영어점수, 총점, 평균점수를 출력하시오.

 

더보기
public class StudentScoreApp {

	public static void main(String[] args) {
		
		StudentScore score1 = new StudentScore();
		score1.name = "홍길동";
		score1.kor = 90;
		score1.eng = 80;
		score1.math = 100;
		
		StudentScore score2 = new StudentScore();
		score2.name = "김유신";
		score2.kor = 90;
		score2.eng = 80;
		score2.math = 100;
		
		StudentScore score3 = new StudentScore();
		score3.name = "류관순";
		score3.kor = 90;
		score3.eng = 80;
		score3.math = 100;
		
		StudentScore score4 = new StudentScore();
		score4.name = "안중근";
		score4.kor = 90;
		score4.eng = 80;
		score4.math = 100;
		
		StudentScore score5 = new StudentScore();
		score5.name = "체다치즈";
		score5.kor = 90;
		score5.eng = 80;
		score5.math = 100;
		
		// 한 번에 담고싶어
		// new StudentScore[5]는 StudentScore객체 5개를 생성한 것이 아님
		// new StudentScore[5]는 StudentScore객체의 참조값 5개를 저장할 수 있는 저장소를 가진 배열객체를 생성함
		// StudentScore[] scoreArray는 StudentScore객체의 참조값을 여러 개 저장하는 배열객체의 참조값을 저장하는 참조변수 생성
		StudentScore[] scoreArray = new StudentScore[5];
		
		scoreArray[0] = score1;
		scoreArray[1] = score2;
		scoreArray[2] = score3;
		scoreArray[3] = score4;
		scoreArray[4] = score5;
		
		// 향상된-for문을 사용해서 배열객체에 저장된 StudentScore객체들의 정보를 화면에 출력하기
		// 왼쪽에는 배열,오른쪽은 뽑아낼 것. 변수의 타입은 배열의 참조값을 따라간 객체 이름. 이름이 곧 타입. 알지?
		for(StudentScore s : scoreArray) {
			System.out.println("학생이름: " + s.name);
			System.out.println("국어점수: " + s.kor);
			System.out.println("영어점수: " + s.eng);
			System.out.println("수학점수: " + s.math);
			System.out.println("총   점: " + (s.kor + s.eng + s.math));
			System.out.println("평   균: " + (s.kor + s.eng + s.math)/3);
			System.out.println();
		}			
	}
}

배열을 하나에 모두 담아 주고 싶다.

배열을 쓰지 않으면, 값을 여러개 줘야 한다. 그렇게 되면 전해주는 양이 많을뿐더러, 배열이 없으면 반복문 사용도 할 수 없다.


메소드
그 객체의 고유한 기능을 담당한다.
선언부와 구현부로 구성된다.

선언부는 접근제한자 반환타입 메소드이름(타입 매개변수명, 타입매개변수명, ...) 으로 구성되어있다.
구현부는 해당메소드가 수행하는 작업에 대한 수행문이 포함되어 있다.

 

 

 

다른 기능과 구분하기 위해 블록이 필요하다.

 

기능을 사용하기 위해서는 이름(메소드명)이 필요하다.

입력한걸 저장해줄 것이 필요해서 매개변수,

수행결과를 제공해주는 것이 필요해서 변환타입을 사용한다.

 

 

 

 

 

 

 

뻥튀기 기계가 메소드이다.

수행문이 실행되기 위해 입력값이 필요하다. 👉변수를 만들어서 출력값을 저장해야한다. 👉값을 저장하고 싶은데 변수를 만들어야 한다. 👉타입을 알아야 변수를 만들 수 있다. 👉근데 타입을 모른다. 👉그럴때 쓰는 것이 반환타입이다.

 

출력값을 저장하고 싶을때 만드는 변수에 쓰는 것이 반환타입!

 

이런 메소드는 어떻게 실행하나?

 

 

참조변수.메소드명( ); 이렇게 실행한다. 그리고 호출하는 방법은 딱 이 네가지밖에 없다.

위의 그림 속 예시 설명
빨리 닫아! 화면에 찍어 줄래? (여기서 출력은 화면 출력이 아님)
입력 받아서 나 줘! 비교해서 같으면 true, 다르면 false 알려줘


출력이 있는건 반드시 변수가 있어야 한다. 그리고 값을 전해줘야 한다.
반환타입이 void는 반환해주지 않는다. void가 아닐때만 저렇게 대입할 수 있다.

 

 

Sample클래스에 정의된 메소드 실행하기
1. 객체 생성(- 무조건 객체부터 생성한다.)하고, 생성된 객체의 참조값을 참조변수에 대입시킨다.
2. 참조변수를 이용해서 생성된 객체의 메소드를 실행한다.


// 입력값 없음, 반환값 없음
public void test1() {
	System.out.println("test1 메소드가 실행됨");
}
	
// 입력값 있음, 반환값 없음 => 내 필요에 따라 만들기 때문에 내가 결정한다.
public void test2(int x, int y) {
	System.out.println("test2 메소드가 실행됨");
	System.out.println("x에 전달된 값: " + x);
	System.out.println("y에 전달된 값: " + y);
}
	
// 입력값 없음, 반환값 있음
public int test3() {	// 반환타입(int)이 있는 경우 반드시 return;이 있어야 한다.
	System.out.println("test3 메소드가 실행됨");
		
	return 100;			// 타입이 일치해야함 3.4 입력하면 오류
}

// 입력값과 반환값이 모두 있음
// 매개변수의 타입과 반환타입은 아무런 상관관계가 없음
public int test4(int x, int y) {
	System.out.println("test4 메소드가 실행됨");
	int result = x + y;
		
	return result;
}

어떨때 사용할까?

 

회원관리기능이 구현된 클래스

 

  • 매개변수 없음, 반환타입 없음
    • 모든 회원정보 삭제하기 기능
      public void deleteAll() {...}
  • 매개변수 있음, 반환타입 없음
    • 특정 번호에 해당하는 회원정보 삭제하기 기능
      public void deleteUserByNo(int no) {...}
    • 특정 상품을 지정된 회원의 장바구니에 저장하는 기능
      public void addCartItem(int userNo, int productNo, int quantity) {...}매개변수 없음, 반환타입 있음
      • 우리 사이트에 가입한 모든 회원의 수를 조회하는 기능
        public int getTotalUserCount() {...}
      • 우리 사이트에 가입한 모든 회원정보를 조회하는 기능
        public User[] getAllUsers() {...}

 

반환타입 있고 없고의 차이

반환타입이 void는 반환해주지 않는다. void가 아닐때만 저렇게 대입할 수 있다.

test를 호출한 곳에 반환해준다. 

 

  • 매개변수 없음, 반환타입 있음
    • 우리 사이트에 가입한 모든 회원의 수를 조회하는 기능
      public int getTotalUserCount() {...}
    • 우리 사이트에 가입한 모든 회원정보를 조회하는 기능
      public User[] getAllUsers() {...}
  • 매개변수 있음, 반환타입 있음
    • 최소가격, 최대가격을 전달받아서 그 가격범위에 속하는 상품정보를 조회하는 기능
      public Product[] getProductByPrice(int minPrice, int maxPrice) {...}
    • 검색조건을 전달받아서 그 조건에 맞는 책정보를 조회하는 기능
      public Book[] searchBooks(String searchOption, String keyword) {...}
    • 사용자 아이디를 전달받아서 사용자정보를 조회하는 기능
      public User getUserById(String userId) {...}
    • 카테고리를 전달받아서 해당 카테고리에 속하는 상품정보를 조회하는 기능
      public Product[] getProductsByCategory(String category) {...}

조회는 반환타입 있게, 추가(수정), 변경, 삭제는 반환타입 없게 만든다. => 기억할 것
메소드의 선언부를 설계할 수 있어야함


같은 객체 안에 있는다는 조건으로, 다른 멤버메소드를 멤버메소드 안에 쓸 수 있다.
public class Score {

	String name;
	int kor;
	int eng;
	int math;
	
	void initScore(String studentName, int korScore, int engScore, int mathScore) {
		name = studentName;
		kor = korScore;
		eng = engScore;
		math = mathScore;
	}
	
	int getTotalScore() {
		int totalScore = kor + eng + math;
		return totalScore;
	}
    
    int getAverage() {
		return getTotalScore()/3;				// getTotalScore()가 반환하는 값을 3으로 나눈 평균값을 변수에 저장하지 않고 바로 반환할 수 있다.
	}
	
	void printScore() {
		System.out.println("---------------------");
		System.out.println("학생이름: " + name);
		System.out.println("국어점수: " + kor);
		System.out.println("영어점수: " + eng);
		System.out.println("수학점수: " + math);
		System.out.println("총   점: " + getTotalScore());	// 반환값이 있는 메소드는 메소드실행으로 획득된 값을 바로 사용할 수 있다.
		System.out.println("평   균: " + getAverage());		// 반환값이 있는 메소드는 메소드실행으로 획득된 값을 바로 사용할 수 있다.

	}
}

반환타입이 객체인 경우

왼쪽의 아래쪽 노란박스는 메인 메소드이다. 

객체 영역은 Heap 영역이라고도 하고, 메소드 영역을 Stack 영역이라고도 한다.
Stack은 쌓여있다라는 뜻이다. 뭐가 쌓여있냐하면 메소드가 실행될 때 메소드에서 사용되는 변수들이 생성되는 공간이 만들어진다. 당연히 main메소드 전용 영역, 저장공간이 만들어진다. 메소드 실행될때마다 해당 메소드 영역이 생성되고, 최근 메소드 영역은 항상 위에 생긴다.

 

new Sample();을 적어서 Sample 객체를 만들었다. 주소값 생성됨.

main메소드 영역에 있는 sample이 Sample객체를 바라본다.

sample.test(score1);를 실행하면 test영역이 생긴다. 메인 메소드 위에. 메소드 실행될때마다 해당 메소드 영역이 생성되고, 가장 최근에 실행된 메소드는 항상 맨 위에 있다.

 

왼쪽의 아래쪽 노란박스는 메인 메소드이다. 

sample.test(score1)을 실행함으로써 Sample객체의 score에 참조값을 전달받고, test메소드 영역에 score1의 참조값이 전달된다.
test메소드 안에 이제 score변수가 생겼다. score변수 안에 0x222을 가지고 있다.
test메소드 안의 score는 score1을 바라보고 있다.
score1의 객체의 정보가 출력된다. Score객체 안의 printScore() 실행됨

그리고 그 순간 score1을 담고있던 test는 사라지게 된다.

 

score.printScore();

sample 객체 안에 있는 멤버 메소드인데, 다른 객체에 있는 메소드를 쓰려면 참조변수를 써서 표현한다.

 

void test(Score score)

매개변수가 참조자료형일 때, 이 참조변수 score에는 자신이 전달받은 참조값이 들어가있다. 매개변수의 타입이 Score인 score라고 적혀있는 것. Score타입 객체의 참조값을 주세요. 라는 의미이다.

 

score2는 사진으로 설명. 

그렇게 test가 두 개 다 없어진다.

 


(맨 왼쪽의 네모칸 두 개) score1 , score2 는 연결이 안 없어졌당.
참조값을 전해준다는 것은. 해당 매소드 내에서 같은 객체를 수정하게 한다. 내가 바라보고있는 그 객체 수정해, 갖고 장난쳐.
참조값자체가 복사해서 전달되긴 하지만, 서로 바라봤던게 같은 거였다. 그걸 수정했다는 것임

메소드 실행이 종료 후에 찍어보면, 수정된 값이 출력되게 된다. 


반환타입이 객체인경우, 객체의 주소값을 반환받게 된다.

메인메소드가 종료될때까지 값이 살아있게된다.

자바에서는 항상 주고받을때 객체를 주고받게된다. 꼭은 아니지만, 대ㅐㅐ부분
정보는 한개 이상의 값으로 구성되어 있다. 그래서 객체단위로 주고받음

메소드를 실행한다?

이 객체에 속성이라는게 있다. 없을 수도 있다. 속성 안에 고유한 기능이 있는데, main에서 메소드를 실행(호출)한 것. => 대화한다.

객체지향은 객체끼리 대화를 나누는 것이다. 메소드의 호출이 대화라는 뜻이다.
그걸로 객체를 주기도 받기도 하는데, 실제로는 객체가 아니라 참조값이다.

 


와.. 지금부터 어려워지나부다...