TECHIT 앱 스쿨 2기: Android 5일차 (23.04.28)
자료 출처 : 안드로이드 앱스쿨 2기 윤재성 강사님 수업 내용
앱 스쿨 2기: Android 과정이 시작되고 첫 주말입니다.
역시 어제 걱정했던 대로 오늘 배운 내용은 어려웠지만 강사님께서 최대한 쉽게 설명해 주셔서 이해는 갔으나,
누군가가 저에게 물어봤을 때 제대로 된 대답이 나올지는 잘 모르겠습니다. 음....
하지만 최대한 오늘 배운 내용을 정리하고, 만약 헷갈린다면 검색을 통한 내용을 작성 할 수 있도록 하겠습니다.
시작은 어제 내주신 보너스 문제에 대해서 코드 작성 및 설명해주셨습니다.
* 하기에 기재한 코드는 강사님의 코드가 아닌 제가 작성한 코드입니다.
* 전날 혹은 당일 배운 내용으로만 코드를 작성하였습니다.
첫번째 문제는 숫자를 입력 받은 후 그 숫자 까지의 총합을 구하는 문제였습니다.
import java.util.*;
public class Ex4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//보너스 문제1)
//사용자에게 숫자를 입력 받아 그 숫자 까지의 총합을 구한다.
System.out.print("첫번째 값을 입력해주세요. : ");
Scanner scan = new Scanner(System.in);
int num1 = scan.nextInt();
int result1 = 0;
for(int i = 0; i <= num1; i++) {
result1 += i;
}
System.out.printf("보너스 문제1 : %d\n",result1);
scan.close();
}
두번째 문제는 숫자를 입력 받은 후 그 숫자의 배수 100개를 출력하는 문제였습니다.
import java.util.*;
public class Ex5 {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 보너스 문제2)
// 사용자에게 숫자를 입력 받아 그 숫자의 배수 100개를 출력한다.
Scanner scan = new Scanner(System.in);
System.out.print("값을 입력해주세요. : ");
int num2 = scan.nextInt();
for(int i = 1; i <= 100; i++) {
System.out.printf("%d ",i*num2);
if(i % 10 == 0) System.out.println();
}
scan.close();
}
}
세번째 문제는 2 부터 입력 받은 숫자 까지의 범위 안에서 소수를 구하는 문제였습니다.
import java.util.*;
public class Ex6 {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 보너스 문제3)
// 사용자에게 숫자를 입력 받아 2에서 부터 그 숫자까지의 범위 안에서 소수
// (1과 자기자신으로만 나눠지는 수)를 모두 출력한다.
Scanner scan = new Scanner(System.in);
System.out.print("값을 입력해주세요. : ");
int num3 = scan.nextInt();
for(int i = 2; i <= num3; i++) { // 소수인지 확인할 값
boolean check = true;
for(int j = 2; j < i; j++) {
if(i % j == 0)
check = false;
}
if(check)
System.out.printf("%d ",i);
}
System.out.println();
scan.close();
}
}
네번째 문제는 주민번호의 유효성 체크를 하는 문제였습니다.
네번째 문제의 경우 처음에 작성하였었을 때는 switch문을 이용하여 작성하였었지만, 작성하다보니 좀 더 간결하게 작성할 방법이 보여 작성하였었습니다.
해당 코드를 작성할 때 사용자 입장은 1도 생각하지 않았습니다.ㅋㅋㅋㅋ
강사님께서 작성하셨던 코드는 입력받은 숫자를 long 형태로 받아서 자릿수별로 다 분리하여 계산하신 형태였습니다.
그래서 사용자 입장에서 사용하기 편한 코드였었습니다.
import java.util.*;
public class Ex7 {
public static void main(String[] args) {
// TODO Auto-generated method stub
// // 보너스 문제4) 주민등록 번호를 입력받아 올바른 주민 등록 번호인지 확인한다.
// (2 x 1자리) + (3 x 2자리) + (4 x 3자리) + (5 x 4자리)
// + (6 x 5자리) + (7 x 6자리) + (8 x 7자리) + (9 x 8자리)
// + (2 x 9자리) + (3 x 10자리) + (4 x 11자리) + (5 x 12자리) 의 합을 구한다.
// 위의 합을 11로 나눈 나머지를 구한다.
// 11에서 나머지를 뺀다.
// 뺀 숫자를 10으로 나눈 나머지를 구한다. 이 값이 13번째 자리 숫자가 된다.
Scanner scan = new Scanner(System.in);
int num4 = 0;
for(int i = 1; i <= 12; i++) { // 주민번호 입력 및 합 구하기
System.out.printf("%d번째 자리의 주민번호를 입력해주세요",i);
int temp = scan.nextInt();
if( i < 9)
num4 += temp * (i+1);
else
num4 += (i-7)*temp;
}
num4 %= 11;
num4 = 11 - num4;
num4 %= 10;
System.out.print("13번째 자리의 주민번호를 입력해주세요");
int lastNumber = scan.nextInt();
if(num4 == lastNumber)
System.out.print("올바른 주민번호 입니다.\n");
else
System.out.print("올바르지 못한 주민번호 입니다.\n");
scan.close();
}
}
보너스 문제에 대한 설명이 끝난 후 객체에 대해서 설명해주셨습니다.
* 하기 내용에 대해서 잘못 기재한 내용이 있을 수 있습니다.
* 틀린 내용이 있을 경우 댓글을 남겨주시면 감사하겠습니다.
* 반박 환영합니다.
시작은 배열에 대하여 설명해 주셨습니다.
배열을 생성하고 실습하지는 않았지만, 객체를 쉽게 설명해주시기 위해 배열은 일단 간단하게 알려주셨습니다.
예를 들어 500명의 학생이 있을 때 과목 당 변수 500개를 만들어서 학생의 점수를 관리하는 것과 과목별로 학생들의 점수를 관리하는 것으로 비교하여 설명해주셨습니다.
그리고 과목별 점수로 아닌 학생별로 관리하고 싶어졌다라는 비유를 해주시면서 객체에 대한 설명을 시작하셨습니다.
주제로는 하기와 같습니다.
객체지향기법에 대한 설명
객체를 설계할 때 순서에 대한 설명.
어떠한 기능을 할지.
객체 설계를 하는 방법에 대하여 설명.
OOP기법에 대하여 설명.
클래스는 객체를 만들기 위한 설계도라고 볼 수 있다.
하나의 클래스를 가지고 만들 수 있는 객체의 수는 제한이 없다.
클래스를 가지고 만든 객체는 프로그램 실행 중에 수정할 수 없다.
스몰토크 방식에 대한 설명
클래스 설계 방법에 대한 설명.
종속성에 대하여 설명.
-> 영향을 미치는 것은 최대한 줄여야함.
클래스 설계시
첫번째로는 구현하고자 하는 기능을 정리
두번째로는 관련있는 것끼리 묶기
세번째로는 관련있는 것끼리 묶은 후 필요한 데이터를 정리
* 하기 내용은 강사님께 오늘 배운 내용을 바탕으로 제가 이해한 대로 적었기
때문에 내용이 올바르지 않거나, 내용이 없을 수 있습니다.
EX)
학생1 | 학생2 | 학생3 | 학생4 | |
국어 (데이터) | 50 | 100 | 70 | 30 |
영어 (데이터) | 50 | 100 | 80 | 90 |
평균 (기능) | 50 | 100 | 75 | 60 |
위 표에서 객체는 하기 4개라고 말할 수 있습니다.
학생1 | |
국어 (데이터) | 50 |
영어 (데이터) | 50 |
평균 (기능) | 50 |
학생2 | |
국어 (데이터) | 100 |
영어 (데이터) | 100 |
평균 (기능) | 100 |
학생3 | |
국어 (데이터) | 70 |
영어 (데이터) | 80 |
평균 (기능) | 75 |
학생4 | |
국어 (데이터) | 30 |
영어 (데이터) | 90 |
평균 (기능) | 60 |
위 의 표들을 보면 학생의 번호와 점수를 제외하고 하기와 동일한 규격을 가지고 있는 점을 볼 수 있습니다.
학생 | |
국어 (데이터) | |
영어 (데이터) | |
평균 (기능) |
이 동일한 규격이 클래스라고 할 수 있습니다.
그리고 중간에 return에 대해서 설명해주셨습니다.
return : 메서드를 종료하고 원래 실행하던 코드로 되돌아가라 라는 의미입니다.
return 옆에 값을 작성하면 값을 같이 전달함. 값을 전달하는 것은 부가적인 기능임.
값을 반환할 때 1가지의 값만을 반환할 수 있다.
클래스는 객체가 가지고 있어야 할 속성(데이터)과 객체가 수행 할 작업(기능)을 정의합니다.
하기 코드로 설명하겠습니다.
점수는 이미 정해져 있다고 하겠습니다.
public class MainClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
// s1이라는 객체를 생성하였습니다.
// s1이라는 객체는 StudentClass을 이용하여 새로운 StudentClass 형태를 갖는
// 객체 입니다.
// 해당 말이 헷갈릴 수 있는데 비유를 하자면 벤츠 자동차 생산라인을 거쳐
// 완성된 벤츠 자동차라는 것입니다.
// 클래스는 비유로 하자면 벤츠 자동차 생산라인, 객체는 완성된 벤츠 자동차 입니다.
StudentClass s1 = new StudentClass();
// 객체 참조 변수를 통한 멤버 변수 접근
// 메서드와 동일하게 . 을 이용하여 접근한다.
System.out.printf("국어점수 : %d\n", s1.koreaScore);
System.out.printf("영어점수 : %d\n", s1.englishScore);
System.out.printf("평균점수 : %d\n", s1.getAvg());
}
}
class StudentClass {
// koreaScore, englishScort 2개는 멤버 변수(데이터) 입니다.
// 멤버 변수의 경우 같은 클래스 내 작성한 멤버 메서드(기능)에서 사용이 가능합니다.
int koreaScore = 50;
int englishScore = 50;
// 평균을 구하는 메서드(기능) 입니다.
// 멤버 변수의 경우 같은 클래스 내 작성한 멤버 메서드(기능)에서 사용이 가능합니다.
// 따라서 koreaScore, englishScort의 값을 가져와 평균을 구한 후
// int 형으로 반환 합니다.
public int getAvg(){
int avg = (koreaScore + englishScore) / 2;
return avg;
}
}
클래스는 객체에 대한 설계도 라고 말할 수 있습니다.
그렇다고 객체를 생성할 때마다 클래스를 생성해야 되나? 라는 의문이 생길 수 있는데 고전적인 비유인 자동차를 비유하자면 자동차 1대를 생산할 때 그 1대에 대한 설계도를 매번 작성하여 자동차를 생산하는 것이 아닌 것처럼 자동차를 제작하기 위한 설계도는 1번 제작하여 설계도 대로 자동차를 생산하는 것 처럼 클래스도 1번만 생성하면 됩니다.
상기코드를 보면
StudentClass s1 = new StudentClass();
라는 코드가 있는데 s1이라는 이름을 가진 변수에는 무엇이 저장되어 있을까요?
-> JVM에서 지정한 객체의 ID가 저장되어 있습니다. 주소값 아닙니다.
System.out.printf("s1 : %s\n", s1);
출력 결과 s1 : StudentClass@1cd072a9
그리고 가비지 컬렉션에 대해서 알려주셨습니다.
자바에서의 객체 소멸 시점은 객체를 접근하기 위해 사용하는 객체의 ID값을 가지고 있는 변수가 하나도 없다면
소멸의 대상이 됩니다.
메모리 청소 작업이 수행되면 소멸의 대상이 되는 객체는 모두 메모리에서 사라집니다.
메모리 청소 시점은
1. JVM이 메모리가 부족하다고 판단하는 경우.
2. OS가 부족하다고 판단하는 경우
3 . 프로그램이 종료될 때(JVM이 종료되면) OS에 의해 청소됨
4. 개발자가 코드를 통해 명시적으로 메모리 청소 명령을 날린 경우.
가비지 컬렉션은 매우 부담이 되는 작업이기에 많이 발생하지 않는 것이 중요하다고 말씀해주셨습니다.
하더라도 보통 사용자가 적은 시간대(새벽)에 실행하도록 설정한다고 하셨습니다.
그리고 마지막으로 변수, 메서드 등의 사용 범위를 설명해주셨습니다.
즉, 변수나 메서드를 현재 사용 가능한지에 대한 이야기입니다.
객체의 멤버 변수나 멤버 메서드는 객체가 생성되어야지만 사용이 가능합니다.
객체가 소멸되면 멤버 변수도 소멸되기 때문에 사용이 불가능 하며, 객체를 통해 메서드 또한 호출하지 못하므로
사용이 불가능 합니다.
자바는 기본적으로 블럭 스코프를 가지는데 블럭 스코프는 변수 등이 선언된 블럭( { } ) 내부에서 사용이 가능합니다.
public class MainClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 객체을 생성하지 않음.
// StudentClass s1 = new StudentClass();
// 하기 코드 사용못함.
System.out.printf("국어점수 : %d\n", s1.koreaScore);
System.out.printf("영어점수 : %d\n", s1.englishScort);
System.out.printf("평균점수 : %d\n", s1.getAvg());
System.out.printf("s1 : %s\n", s1);
}
}
class StudentClass {
int koreaScore = 50;
int englishScort = 50;
public int getAvg(){
int avg = (koreaScore + englishScort) / 2;
return avg;
}
}
하기 코드는 강사님께서 보여주신 잘못된 예제와 설명해주신 내용입니다.
public class MainClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
TestClass1 t1 = new TestClass1();
System.out.printf("t1.memberA : %d\n", t1.memberA);
System.out.printf("t1.memberB : %d\n", t1.memberB);
// 클래스에 정의된 메서드들은 클래스를 통해 생성한 객체를 통해 호출 할 수 있다.
// 따라서, 객체가 생성되었다면 이를 통해 호출할 수 있다.
t1.testMethod1();
}
}
class TestClass1 {
// 멤버 변수 선언
// 멤버 변수는 객체를 생성해야 지만 메모리에 생성된다.
int memberA = 100;
int memberB = 200;
// 멤버 메서드
public void testMethod1() {
System.out.println("testMethod1 호출");
// 같은 객체에 있는 멤버 변수의 사용
// 멤버 메서드는 객체를 생성하고 그 객체를 통해서 호출할 수 있기 때문에
// 멤버 변수가 생성되어 있다는 것을 보장받을 수 있다. 이에 사용이 자유롭습니다.
System.out.printf("memberA : %d\n", memberA);
System.out.printf("memberB : %d\n", memberB);
}
// 지역변수 에제
// 메서드 내부에 정의한 변수들을 의미한다.
// 변수가 정의된 블럭이 끝나면 변수는 소멸된다.
// 매개변수. 매개변수는 메서드의 지역변수에 해당한다.
// 따라서 매개변수가 정의된 메서드 내부에서만 사용이 가능하다.
public void testMethod2(int a1, int a2) {
// 매개변수 사용
// 메서드가 끝나면 소멸된다.
System.out.printf("a1 : %d\n", a1);
System.out.printf("a2 : %d\n", a2);
// 메서드 내부에서 선언한 변수
// 같은 메서드 내부에서만 사용이 가능하다.
// 메서드가 끝나면 소멸된다.
int a3 = 100;
int a4 = 200;
System.out.printf("a3 : %d\n", a3);
System.out.printf("a4 : %d\n", a4);
// 제어문 내부
for(int i = 0 ; i < 3 ; i++) {
// 제어문 내부에서 선언된 변수는 제어문 내부에서만 사용이
// 가능하고 제어문 수행이 끝나면 소멸된다.
int a5 = 300;
System.out.printf("for - %d\n", a3);
System.out.printf("i : %d\n", i);
System.out.printf("a5 : %d\n", a5);
}
// 제어문 내부에서 선언된 변수 사용
System.out.printf("a5 : %d\n", a5);
System.out.printf("i : %d\n", i);
{
int a6 = 100;
System.out.printf("a6 : %d\n", a6);
}
// 사용 불가
System.out.printf("a6 : %d\n", a6);
}
public void testMethod3() {
// testMethod2에 정의된 매개변수 사용 시도
// 다른 메서드 이므로 사용 불가
System.out.printf("a1 : %d\n", a1);
System.out.printf("a2 : %d\n", a2);
// testMethod2의 정의된 지역변수 사용 시도
// 다른 메서드 이므로 사용 불가
System.out.printf("a3 : %d\n", a3);
System.out.printf("a4 : %d\n", a4);
}
}
마무리
오늘 배운 내용자체가 좀 헷갈리는 부분이 있었는데, 오늘 강의를 들으면서 오늘 배운 내용에 한해서 객체와 클래스에 대한 개념은 이해가 되었습니다. 해당 글을 적으면서 다시 보고 읽고 그래서 그런 것일 수도 있습니다. 혹은 지금도 잘못알고 있는 부분이 있을 수도 있습니다. 하지만 약간 클래스,객체,멤버 변수,멤버 메서드 등에 대한 이해도는 어제보다는 확실하게 올라갔다고 말할 수 있을 것 같습니다.
어제의 저에게 클래스,객체,멤버 변수,멤버 메서드를 설명하라고 하면, 설명하지 못하였을 것 입니다.
알고리즘 등을 공부하면서 코드 작성을 하였었지만, 진짜 내부적으로 자세히 어떻게 작동하는지도 모르면서 알고리즘 코드를 작성했던 저를 반성하게 되었습니다.
그리고 자바에 익숙해지기 위해 알고리즘 문제들을 풀어봐야 될 것 같습니다.
실전 만큼 해당 언어에 빠르게 익숙해지는 방법은 없다고 생각하고 있지만, 배운 내용 또한 확실히 이해하기 위해서는
이번주 동안 배운 내용을 토대로 풀 수 있는 문제들만 풀 예정 입니다. 즉, 배열을 사용해야 한다면 제외입니다......
아마 다음주에는 배열을 이용하여 풀 수 있는 문제들도 풀 예정 입니다.