자바 기본 배우기 -자바에서 함수와 클래스 기본-

1. 클래스란 무엇인가

 

사람의 정보를 관리하고 싶다

 

 

가장 쉬운방법은 변수들을 만들어서 일단 무작정 넣어놓는것

 

package com.ssafy.class01;

public class PersonTest {
	public static void main(String[] args) {
		String name1 = "Yang";
		String name2 = "Hong";
		
		int age1 = 45;
		int age2 = 25;
		
		String hobby1 = "Youtube";
		String hobby2 = "Golf";
	}
}

 

 

하지만 사람이 더 늘어난다면?

 

동일한 자료형들을 하나로 묶어서 관리할 수 있는 배열을 사용

 

그러면 반복문도 사용 가능해지고 코드도 간결해지고..

 

		//배열 사용
		
		int size = 2;
		String[] names = new String[size];
		
		names[0] = "Yang";
		names[1] = "Hong";
		
		int[] ages = new int[size];
		
		ages[0] = 45;
		ages[1] = 25;
		
		String[] hobbies = new String[size];
		
		hobbies[0] = "Youtube";
		hobbies[1] = "Golf";

 

 

그런데 자세히 살펴보니.. names나 ages나 hobbies 이 배열들이 서로 관련이 있는가?

 

사실 names[i], ages[i], hobbies[i]은 하나의 사람을 나타내는데..

 

이들을 오히려 하나로 묶어서 관리할수는 없는가?

 

배열은 서로 같은 자료형을 하나로 묶어서 관리하는데..

 

지금 String name, int age, String hobby들을 하나로 묶어서 사람으로 관리할 수는 없는가?

 

이처럼 하나의 변수에 다양한 서로 다른 정보를 묶어서 우리만의 공간을 만들어 관리할 수는 없을까?

 

틀을 하나 만들어놓고

 

필요할때마다 이 틀을 이용해서.. 정보를 넣어가지고 사람을 만들어내는거지

 

코드로 어떻게 정의하지..?

 

 

파이썬보다 더 쉬워보이냐..

 

public class Person {
    String name;
    int age;
    String hobby;
}

 

기초자료형 int 같은 경우 크기가 4byte로 고정되어있는데..

 

이런 자료형들의 모임인 Person은 크기를 얼마로 해야하나..??

 

크기를 모르겠으니까 Person에 대한 주소를 저장

 

stack에 Person 만들고 그 안에는 heap에 만들어진 공간으로 가는 주소를 저장

 

참조자료형 생성을 위해 new라는 명령어 사용한 것처럼 클래스도 new라는 명령어로 생성한다..?

 

 

2. 함수

 

(갑자기 함수 이야기를 하네..)

 

교육생의 하루 일과..

 

 

컴퓨터 입장에서 교육생을 컨트롤한다고 할때.. 위 일과 하나하나는 교육생에 대한 "명령어"

 

그리고 이렇게 명령어들을 작성해서 나열하는 행위를 "프로그래밍"한다

 

2월 8일의 일과가 다음과 같아서...

 

package com.ssafy.class01;

public class FunctionTest1 {
	public static void main(String[] args) {
		System.out.println("아침에 일어난다.");
		System.out.println("교육장으로 대중교통을 이용하여 이동한다.");
		System.out.println("오전 수업을 듣는다.");
		System.out.println("점심을 먹는다.");
		System.out.println("오후 수업을 듣는다.");
		System.out.println("집으로 대중교통을 이용하여 이동한다.");
		System.out.println("과제를 해결한다.");
		System.out.println("잔다.");
	}
}

 

그런데 다음날 2월 9일에는 어쩐지 아침밥을 먹고싶었음

 

package com.ssafy.class01;

public class FunctionTest1 {
	public static void main(String[] args) {
		System.out.println("아침에 일어난다.");
		System.out.println("교육장으로 대중교통을 이용하여 이동한다.");
		System.out.println("오전 수업을 듣는다.");
		System.out.println("점심을 먹는다.");
		System.out.println("오후 수업을 듣는다.");
		System.out.println("집으로 대중교통을 이용하여 이동한다.");
		System.out.println("과제를 해결한다.");
		System.out.println("잔다.");
		
		System.out.println("아침에 일어난다.");
		System.out.println("아침밥을 먹는다.");
		System.out.println("교육장으로 대중교통을 이용하여 이동한다.");
		System.out.println("오전 수업을 듣는다.");
		System.out.println("점심을 먹는다.");
		System.out.println("오후 수업을 듣는다.");
		System.out.println("집으로 대중교통을 이용하여 이동한다.");
		System.out.println("과제를 해결한다.");
		System.out.println("잔다.");
	}
}

 

그 다음날 2월 10일은 똑같고.. 2월 11일도 똑같고.. 2월 12일은 여기에 저녁밥을 먹고.. 2월 13일은 똑같고...

 

반복적인 행위들이 있는데.. 이걸 계속 하염없이 작성해야하나

 

예전에 쓴걸 가지고 와서 쓸 수는 없나?

 

반복되는 부분을 하나로 묶어서 하나의 이름을 부여한다

 

이를 함수(function)라고 부른다

 

 

코드에서도 반복되는 부분을 하나로 가지고 와서... 다음과 같이 작성할 수 있다

 

package com.ssafy.class01;

public class FunctionTest1 {
	public static void main(String[] args) {
		System.out.println("아침에 일어난다.");
		System.out.println("교육장으로 대중교통을 이용하여 이동한다.");
		교육();
		System.out.println("집으로 대중교통을 이용하여 이동한다.");
		System.out.println("과제를 해결한다.");
		System.out.println("잔다.");
		
		System.out.println("=========================");
		
		System.out.println("아침에 일어난다.");
		System.out.println("아침밥을 먹는다.");
		System.out.println("교육장으로 대중교통을 이용하여 이동한다.");
		교육();
		System.out.println("집으로 대중교통을 이용하여 이동한다.");
		System.out.println("과제를 해결한다.");
		System.out.println("잔다.");
	}
	
	public static void 교육() {
		System.out.println("오전수업을 듣는다.");
		System.out.println("점심을 먹는다.");
		System.out.println("오후 수업을 듣는다.");
	}
}

 

물론 함수명은 한글로 작성하는 것은 절대로 권장하지 않는다

 

아무튼 반복되는 부분을... 간단하게 만들어서 코드가 조금 간결해지는 효과가 있지

 

이렇게 할때 장점은...?

 

코드 수정이 용이하다

 

교육()에 해당하는 부분을 고치고 싶다면..?

 

함수를 쓰지 않는다면 6군데를 수정하지만

 

함수를 쓴다면.. 함수 부분에 3군데만 수정해도 6군데 수정하는 효과와 동일

 

 

함수로 고치고 나서 일과를 또 보니 밑줄친 두 부분이 뭔가 비슷해보여서... 

 

 

3. 함수의 인자

 

또 줄여서 써보고 싶은데

 

 

"어딘가"로 "무언가"를 이용하여 이동한다라는 틀로 고칠 수 있을 것 같다

 

그리고 이 틀에 필요할때마다 "어딘가"와 "무언가"만 고쳐써주면 그만이다

 

 

 

package com.ssafy.class01;

public class FunctionTest1 {
	public static void main(String[] args) {
		System.out.println("아침에 일어난다.");
		이동("교육장","대중교통");
		교육();
		이동("집","대중교통");
        System.out.println("과제를 해결한다.");
		System.out.println("잔다.");
		
		System.out.println("=========================");
		
		System.out.println("아침에 일어난다.");
		System.out.println("아침밥을 먹는다.");
		이동("제주도","비행기");
		교육();
		이동("집","배");
        System.out.println("과제를 해결한다.");
		System.out.println("잔다.");
	}
	
	public static void 교육() {
		System.out.println("오전수업을 듣는다.");
		System.out.println("점심을 먹는다.");
		System.out.println("오후 수업을 듣는다.");
	}
	
	public static void 이동(String 장소, String 탈것) {
		System.out.println(장소+"(으)로"+탈것+"(을)를 이용하여 이동한다.");
	}
}

 

함수에서 정의되는 부분에서...

 

	public static void 이동(String 장소, String 탈것) {
		System.out.println(장소+"(으)로"+탈것+"(을)를 이용하여 이동한다.");
	}

 

String 장소, String 탈것 을 parameter라고 부른다

 

그리고.. 함수를 쓰면서 실제로 넘겨주는 값들

 

		System.out.println("아침에 일어난다.");
		이동("교육장","대중교통");
		교육();
		이동("집","대중교통");
        System.out.println("과제를 해결한다.");
		System.out.println("잔다.");

 

"교육장", "대중교통", "집" ... 이들을 argument(인자)라고 부른다

 

4. 함수의 return

 

그런데 보통 교육생은 "과제를 해결한다" 이게... 과제라는게 있을때만 하는거지 없으면 과제는 하지 않아

 

과제가 있는지는 어떻게 아는가?

 

교육을 듣고나서 과제가 있는지, 없는지를 알수가 있다

 

교육의 결과로 과제의 유무를 과제라는 변수에 담아두고...

 

과제가 정말로 있다면 "과제를 해결한다"를 수행해야한다

 

그러면 교육()의 결과로 과제가 있는지 없는지 어떻게 줄거냐..?

 

함수의 return값으로 주면 된다

 

 

자바에서 함수의 return값은 어떻게 주는가??

 

	public static void 교육() {
		System.out.println("오전수업을 듣는다.");
		System.out.println("점심을 먹는다.");
		System.out.println("오후 수업을 듣는다.");
	}

 

public static "void" 부분.. 여기 "void"부분이 함수의 반환 유형을 나타낸다

 

그래서 이 void의 의미는 반환할게 없다는 의미다

 

만약 반환값이 있다면 어떤 유형인지 void 대신 적어줘야한다

 

과제가 있는지, 없는지를 반환하고 싶으니까.. boolean 유형을 반환해야겠다

 

 

 

boolean이라고 쓴 순간 빨간줄이 나오는데.. boolean 타입의 return이 반드시 있어야한다고 명시를 해준다

 

랜덤 객체를 쓰고 싶으면 import java.util.Random;을 해야하나봐

 

import java.util.Random;

public static boolean 교육() {
		System.out.println("오전수업을 듣는다.");
		System.out.println("점심을 먹는다.");
		System.out.println("오후 수업을 듣는다.");
		
		//과제를 랜덤으로 발생시킴
		//자바에서 정의해놓은 랜덤 객체
		
		//ctrl+shift+o를 누르면 자동으로 import 명시를 해주나봐
		Random random = new Random();
		
		return random.nextBoolean(); //true or false를 랜덤하게
	}

 

그러면 교육()의 결과는 true나 false를 내준다

 

그리고 이를 어떤 변수 homework에 저장해두자

 

homework를 쓰고 싶다면.. boolean homework;라고 타입을 미리 명시해주고 써야함

 

public class FunctionTest1 {
	public static void main(String[] args) {
        
        //반드시 타입을 명시하고 변수에 저장해야함
        boolean homework;
        
		System.out.println("아침에 일어난다.");
		이동("교육장","대중교통");
		homework = 교육();
		이동("집","대중교통");
        System.out.println("과제를 해결한다.");
		System.out.println("잔다.");

 

그리고 homework가 true이면.. 과제를 해결하고 false이면 할 필요가 없겠지

 

if문을 이용하여 명시

 

package com.ssafy.class01;

import java.util.Random;

public class FunctionTest1 {
	public static void main(String[] args) {
		
		boolean homework;
		
		System.out.println("아침에 일어난다.");
		이동("교육장","대중교통");
		homework = 교육();
		이동("집","대중교통");
		if(homework) {
			System.out.println("과제를 해결한다.");
		}
		System.out.println("잔다.");
		
		System.out.println("=========================");
		
		System.out.println("아침에 일어난다.");
		System.out.println("아침밥을 먹는다.");
		이동("제주도","비행기");
		homework = 교육();
		이동("집","배");
		if(homework) {
			System.out.println("과제를 해결한다.");
		}
		System.out.println("잔다.");
	}
	
	public static boolean 교육() {
		System.out.println("오전수업을 듣는다.");
		System.out.println("점심을 먹는다.");
		System.out.println("오후 수업을 듣는다.");
		
		//과제를 랜덤으로 발생시킴
		//자바에서 정의해놓은 랜덤 객체
		
		//ctrl+shift+o를 누르면 자동으로 import 명시를 해주나봐
		Random random = new Random();
		
		return random.nextBoolean(); //true or false를 랜덤하게
	}
	
	public static void 이동(String 장소, String 탈것) {
		System.out.println(장소+"(으)로"+탈것+"(을)를 이용하여 이동한다.");
	}
}

아침에 일어난다.
교육장(으)로대중교통(을)를 이용하여 이동한다.
오전수업을 듣는다.
점심을 먹는다.
오후 수업을 듣는다.
집(으)로대중교통(을)를 이용하여 이동한다.
잔다.
=========================
아침에 일어난다.
아침밥을 먹는다.
제주도(으)로비행기(을)를 이용하여 이동한다.
오전수업을 듣는다.
점심을 먹는다.
오후 수업을 듣는다.
집(으)로배(을)를 이용하여 이동한다.
과제를 해결한다.
잔다.

 

그리고 뭐 기본이지만.. 

 

return new Random().nextBoolean(); 해도 문제는 없다

 

Random random = new Random();은 new Random() 객체를 Random random에 저장해둔거지..

 

앞으로 계속 쓰고 싶으니까

 

한번 쓸려면 굳이 변수에 저장 안하고 바로 return new Random().nextBoolean(); 해도 될것이다

 

이러면 다음번에는 못쓰겠지

 

 

5. 연습문제

 

사람의 정보를 출력해보자

 

단순히 일단 그냥 출력해봐

 

package com.ssafy.class01;

public class PersonTest {
	public static void main(String[] args) {
		
		//단순 변수 저장
		String name1 = "Yang";
		String name2 = "Hong";
		
		int age1 = 45;
		int age2 = 25;
		
		String hobby1 = "Youtube";
		String hobby2 = "Golf";
		
		//배열 사용
		
		int size = 2;
		String[] names = new String[size];
		
		names[0] = "Yang";
		names[1] = "Hong";
		
		int[] ages = new int[size];
		
		ages[0] = 45;
		ages[1] = 25;
		
		String[] hobbies = new String[size];
		
		hobbies[0] = "Youtube";
		hobbies[1] = "Golf";
		
		//사람의 정보 출력
		System.out.println("나의 이름은 "+names[0] + "입니다.");
		System.out.println("나이는 "+ages[0]+"세, 취미는 "+hobbies[0]+"입니다.");
		
		System.out.println("나의 이름은 "+names[1] + "입니다.");
		System.out.println("나이는 "+ages[1]+"세, 취미는 "+hobbies[1]+"입니다.");
	}
}

나의 이름은 Yang입니다.
나이는 45세, 취미는 Youtube입니다.
나의 이름은 Hong입니다.
나이는 25세, 취미는 Golf입니다.

 

하지만 배열을 이용한다면.. 반복문으로 인덱싱 접근해서 간단하게 할 수 있지

 

		//반복문
		
		for(int i= 0 ; i < size; i++) {
			System.out.println("나의 이름은 "+names[i] + "입니다.");
			System.out.println("나이는 "+ages[i]+"세, 취미는 "+hobbies[i]+"입니다.");
		}

 

 

함수를 배웠으니까.. 함수로 만들어본다면..?

 

		for(int i= 0 ; i < size; i++) {			
			info(names[i],ages[i],hobbies[i]);
		}
	}
	
	static void info(String name, int age, String hobby) {
		System.out.println("나의 이름은 "+name + "입니다.");
		System.out.println("나이는 "+age+"세, 취미는 "+hobby+"입니다.");
	}

 

6. 클래스와 메소드

 

사람을 만든 클래스 안에 name, age, hobby를 넣었는데.. 바로 위에서 만든 info()라는 함수도 넣어줄 수 있을까?

 

 

package com.ssafy.class01;

//이러한 다양한 자료형을 가질 수 있는 자료형을 만들고 싶다.
public class Person {
	String name;
	int age;
	String hobby;
	
	public void info() {
	}
	
	static void info(String name, int age, String hobby) {
		System.out.println("나의 이름은 "+name + "입니다.");
		System.out.println("나이는 "+age+"세, 취미는 "+hobby+"입니다.");
	}
}

 

일단 쓰긴 했는데.. 쓸려고 보니까.. 이게 info()함수를 이용할때 String name, int age, String hobby의 경우

 

뭐가 들어올지 모르니까 이렇게 넘겨받았는데...

 

Person에다가 이걸 넣을려고 보니까.. 이미 String name, int age, String hobby는 알고 있는데??

 

굳이 인자로 받을 필요가 없겠다

 

package com.ssafy.class01;

//이러한 다양한 자료형을 가질 수 있는 자료형을 만들고 싶다.
public class Person {
	String name;
	int age;
	String hobby;
	
	public void info() {
		System.out.println("나의 이름은 "+name + "입니다.");
		System.out.println("나이는 "+age+"세, 취미는 "+hobby+"입니다.");
	}
	
	
}

 

7. 클래스 정리

 

1) 관련 있는 변수와 함수를 묶어서 만든 사용자가 정의한 <자료형>

 

2) 모든 객체들의 생산처이다

 

3) 클래스 == 객체를 생성하는 틀이다

 

--------------------------------------------------------------------------------------------------

4) 프로그래밍이 쓰이는 목적을 생각하여 어떤 객체를 만들어야 하는지 결정

 

5) 각 객체들이 어떤 특징(속성, 동작)을 가지고 있을지 결정

--------------------------------------------------------------------------------------------------

 

4),5)를 "객체 모델링"이라고 함

 

 

6) 클래스(class)를 통해 생성된 객체(object)를 인스턴스(instance)라고 부른다

 

class = instance를 만들기 위한 틀

 

instance = class로 인해 만들어진 object

 

 

7) 객체들 사이에서 메시지를 주고 받도록 만들어준다

 

"메시지를 주고 받도록 만든다" = 상호작용을 하도록 한다

 

=> 메소드를 이용한다

 

"메소드"?

 

클래스 안에 정의한 함수

 

위에서 정의한 info()는 아무런 인자를 받지 않았지만..

 

경우에 따라서는 다른 객체 인자를 받아서 그들끼리 상호작용시킬수도 있고..

 

 

8. 클래스의 구성

 

1) 속성(attribute) = 필드, 멤버 변수

 

이름, 나이, 

 

2) 동작(behavior) = 메소드, 함수

 

밥을 먹는다, 책을 읽는다,...

 

3) 생성자(constructor)

 

일종의 메소드

 

instance를 만들때 호출하는 메소드.. 파이썬의 __init__ 말하는듯

 

4)  inner class

 

클래스 안에 클래스를 정의할수도 있음

 

당연히 선택사항

 

 

9. 클래스의 선언

 

다음과 같은 방식으로 선언

 

접근 제한자 활용 제한자 class 클래스명 { 속성, 메소드, 생성자 }

 

 

접근제한자의 대표적으로 public, default

 

활용제한자의 대표적으로 final, abstract

 

당연히 더 있다고함

TAGS.

Comments