2023-05-08 월
알고리즘 실습
- 별 출력하기 (Codeup 1256)
//별 출력하기
import java.util.Scanner;
public class codeup1256 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int star = sc.nextInt();
for (int j = 0; j < star; j++) {
System.out.print("*");
}
System.out.println();
}
}
출력 결과
5
*****
구구단을 *로 출력하기 (Codeup 1287)
import java.util.Scanner;
public class codeup1287 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int star = sc.nextInt();
for (int i = 1; i <= 9; i++) {
for (int j = 0; j< i*star; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
직각 삼각형 별찍기 (progrmmers 120823)
import java.util.Scanner;
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
출력결과
3
*
**
***
메소드
: 메소드는 기능입니다. 클래스는 상태와 동작(기능)을 가지고 있는데, ‘**상태’**에 해당하는 것이 ‘멤버변수’이고,
‘동작’에 해당하는 것이 메소드입니다.
ex) PrintHello의 .print(), Scanner의 .next(), .nextInt() 등은 메소드입니다.
예제)
public class SpaceInvaders {
int location; // 멤버 변수 선언
public void moveLeft() { //메소드
// 왼쪽으로 이동하는 메소드
location = location - 1; // 기존 값에 -1
}
public void moveRight() { //메소
// 오른쪽으로 이동하는 메소드
location = location + 1; // 기존 값에 +1
}
}
public class SpaceInvadersTest {
public static void main(String[] args) {
SpaceInvaders si = new SpaceInvaders();
//메소드 호출 할 때 new를 해야지만 호출된다.
si.moveLeft(); //-1
System.out.println(si.location);
si.moveLeft(); //-2
System.out.println(si.location);
si.moveRight(); //-1
System.out.println(si.location);
}
}
📍 SpaceInvaders si = new SpaceInvaders();와 같이 클래스를 new 키워드를 이용해 인스턴스화 시킨 후 사용할 수 있는 이유는 static main()이 생성되는 영역과 SpaceInvaders를 new했을 때, 인스턴스화 되는 영역이 각각 Static영역과 Heap영역으로 다르기 때문입니다.
조금 더 정확하게 말하면 main()이 호출 되는 시점에서는 SpaceInvaders가 생성되지 않았기 때문에 그렇습니다.
main()메소드는 java 프로그램이 실행 될 때 가장 먼저 호출이 되는 메소드이고 java프로그램이 실행 될 때 Static영역에 이미 생성이 되어 있습니다.
하지만 SpaceInvaders의 경우는 new 연산자로 인스턴스를 생성하기 전까지는 존재하지 않습니다.
그래서 new를 하기 전에는 호출이 되지 않는 것입니다.
메소드 선언 방법
: 메소드는 클래스 안에 접근제어자, 리턴타입, 메소드이름 세가지 요소를 지정해 메소드를 선언 할 수 있습니다.
** 메소드만 별개로 만들 수 없습니다.
**public class 클래스이름() {
접근제어자 리턴타입 메소드이름() {
// 메소드의 기능
}
}**
public 접근제어자
void 리턴타입
메소드 실행(호출)방법
메소드를 호출하기 위해서는 내가 호출하려는 **메소드가 들어있는 클래스가 인스턴스화 된 후에 실행(호출)**할 수 있습니다.
//Greet 클래스
public class Greet {
public void printHello() {
System.out.println("Hello");
}
}
//GreetTest 클래스 만든 뒤 main 만들고, Greet클래스->인스턴스화 시킴
public class GreetTest {
public static void main(String[] args) {
Greet greet = new Greet();
greet.printHello();
}
}
결과
Hello
메소드를 만드는 이유
- 반복 호출 가능 → 하나의 기능을 만들어 놓고 반복해서 사용 가능
- 멤버변수와 연계 → 자바의 클래스는 ‘상태’와 ‘ 동작’을 표현하기 위해 멤버변수와 메소드를 사용합니다.
- 멤버변수만 만들기도 하고 메소드만 만들기도 하지만 대체로는 두가지를 같이 쓰도록 고려해서 클래스를 만들게 됩니다.
- 중복된 코드 제거
💡 [ Java 네이밍 컨벤션 ]
- 변수명
- 카멜 케이스(CamelCase)→ 모든 문자의 첫글자 소문자 + 새로운(구분) 단어 대문자
- → 단봉낙타 표기법 (ex. ‘location’, ‘phoneNumber’)
- 클래스명
- 파스칼 케이스(PascalCase)→ 모든 문자의 첫글자 대문자 + 새로운(구분) 단어 대문자
- → 쌍봉낙타 표기법 (ex. ‘SpaceInvaders’, ‘SpaceInvadersTest’)
- 메소드명
- 카멜 케이스(CamelCase)→ 모든 문자의 첫글자 소문자 + 새로운(구분) 단어 대문자
- → 단봉낙타 표기법 (ex. ‘moveLeft’, ‘moveRight’)
메소드의 구성요소
TDD(Test-Driven Development)
애플리케이션 코드 작성 전, 테스트 코드를 먼저 작성하고 실행하면서 기대 결과를 충족하는 코드를 만들어내는 개발 방법론
💡 Test Class 생성 단축키
⌥⏎(MacOS)
Alt+Enter(Windows/Linux)
- test root가 없을 경우
- src - Directory - test/java
접근제어자
접근제어자는 메소드와 클래스, 변수에도 적용가능
public 모든 클래스에서 접근 가능 다른 패키지에서도 접근 가능
protected 같은 패키지 내의 클래스와 해당 클래스를 상속한 외부 패키지의 클래스에서 접근 가능
default 접근 제어자를 쓰지 않은 경우 기본값 같은 패키지 내의 클래스에서만 접근 가능
private 해당 클래스에서만 접근 가능
1. 접근제어자(public)
- 변경 불가능한 값
- public으로 선언되어 있어야 하며, private로 선언 시 JVM에서 접근이 불가하여 프로그램 실행이 불가하다.
2. static인지 여부(static)
- 변경 불가능한 값
- 자바 프로그램 실행 시 해당 클래스의 인스턴스를 생성하지 않고도 main메소드에 접근 가능해야 하기 때문에 static이여야 한다.
📌 static 메소드와 new를 통해 생성된 메소드(인스턴스 메소드)
- static 메소드 : 프로그램이 시작할 때 static 영역에 생성되며, 프로그램이 끝날 때 없어집니다.
- 인스턴스 메소드 : new를 통해 생성 시 heap영역에 생성되며, 해당 메소드의 실행이 끝나면 GC에 의해 없어집니다.
3. 리턴타입(void)
- 변경 불가능한 값
- main메소드는 new를 이용해 다른 클래스의 인스턴스를 생성하여 다른 기능들을 실행하는 코드들이 대부분이다. 따라서 리턴값이 필요 없으므로 리턴타입 또한 void로 고정이다.
4. 메소드명(main)
- 변경 불가능한 값
- 자바 프로그램 실행 시 JVM이 ‘main’이라는 이름으로 메소드를 찾기 때문에 변경 시 프로그램 실행이 불가하다.
2. 리턴타입
: 메소드를 만들 때는 꼭 리턴타입을 써야합니다. 접근제어자는 생략하면 default로 간주하지만, 리턴타입은 반드시 써야합니다.
하지만, 리턴타입이 없는 메소드의 경우도 있습니다. .printHello() 와 같이 단순히 출력하고 메소드가 끝나는 경우에는 리턴타입이 필요없습니다.
리턴타입이 없는 경우 리턴타입 자리에 void 라고 표시를 해주어야합니다.
public class Greet {
public void printHello() {
System.out.println("Hello");
}
}
-> 리턴타입이 없다
3. 여러가지 리턴타입
→ 리턴타입은 원시타입 (Primitiva Type)과 참조타입(Refrence Type)모두 가능합니다.
public class VariousReturnType {
public boolean isAdult(){
return true;
}
public int plus(){
return 1 + 1;
}
public User getUser(){
return new User();
}
public void printHello() {
System.out.println("Hello");
}
public static void main(String[] args) {
VariousReturnType vrt = new VariousReturnType();
boolean isAdult = vrt.isAdult();
int plusResult = vrt.plus();
User user = vrt.getUser();
vrt.printHello();
}
}
- 메소드명
: 한 개의 클래스에 메소드를 여러개 만들 수 있기 때문에 메소드는 다른 메소드와 구분할 수 있게 이름을 붙여줘야합니다.
이름을 지을 때도 그 메소드의 기능을 유추할 수 있도록 짓는 것이 좋습니다.
메소드의 이름은 .printHello(), .nextInt()와 같이 카멜케이스(Camel Case)를 씁니다.
클래스 이름을 지을때도 카멜케이스를 썼지만 클래스 이름을 지을때와는 조금 다르게 소문자로 시작 합니다.
특히, 메소드는 동작이기 때문에 이름은 동사로 짓는 경우가 많습니다.
메소드의 상태와 동작
: 클래스는 상태와 동작을 표현 할 수 있습니다. 멤버 변수는 ‘상태’를 표현 할 수 있고, 메소드는 ‘동작’을 표현 할 수 있습니다.
public class Number {
private int num = 10;
public boolean isOdd() {
return num % 2 != 0;
}
public boolean isEven() {
return num % 2 == 0;
}
public static void main(String[] args) {
Number num = new Number();
System.out.printf("짝수인지? %b\\n", num.isEven());
System.out.printf("홀수인지? %b\\n", num.isOdd());
}
실행결과
짝수인지? true
홀수인지? false
리턴(Return) = ‘돌려준다’
: 리턴은 메소드를 호출한 곳으로 연산 결과를 보내고 싶을 때 사용합니다. ‘돌려준다’ 라고 표현합니다.
매개변수(Parameter)
매개변수 ( Parameter )는 메소드 (함수)를 정의할 때 사용하는 변수이다.
- 매개변수는 일반 변수처럼 반드시 타입을 선언해야 한다.
- 매개변수는 원시 타입 , 참조 타입 등 모든 타입의 변수를 사용할 수 있다.
- 매개변수 선언 시 개수의 제약을 받지 않는다.
- 매개변수 선언 시 메소드를 호출할 때 전달 받을 값 순서대로 선언한다.
Parmeter 와 Argument
Parameter : 메소드(함수) 에서 전달된 값을 받는 변수이며 ‘인수’ 라고도 한다.
ex ) public int plus(int num1, int num2)
Argument : 메소드(함수) 를 호출할 때 매개변수로 전달할 값으로 ‘인자’ 라고도 한다.
반드시 매개변수 타입에 맞는 값을 전달해야 한다.
ex ) plus(10,20);