학습목표
객체지향 프로그래밍을 이해하고 클래스를 설계할 수 있다.
클래스에 정의되는 각종 메소드를 이해하고 프로그래밍에 적용할 수 있다.
객체지향 프로그래밍의 개요
객체(object)란?
특성과 기능을 가지는 하나의 독립적인 개체(entity)
객체(object) 모델링
객체의 특성과 기능을 분석하고 정리하는 작업
클래스(class) 정의
1. 객체 모델링을 한 후에 특성과 기능을 정의하는 도구
2. 특성은 변수로 정의
기능은 메소드로 정의하고, 구현
class Lion {
// 특성(키, 몸무게, 나이, 성별)
int hegiht;
int weight;
int age;
int sex;
// 기능(달리기, 싸우기, 사냥하기, 잠자기)
int running() {...}
boolean fight(Lion) {...}
boolean hunting() {...}
void sleeping() {...}
}
4. 객체 생성하고 사용하기
- 정의된 클래스를 new 연산자를 이용하여 메모리에 할당
- 메모리에 할당된 클래스 : 객체, 인스턴스(instance), 클래스의 변수
- 객체 사용 : 점(.)을 이용하여 클래스에 정의된 변수를 사용하거나 메소드를 호출
Lion a = new Lion();
Lion b = new Lion();
a.age = 10;
b.age = 5;
객체지향 프로그램 구현
1) 클래스 이름 정의
- 변수명 규칙과 동일
- 관행적으로 첫 문자는 대문자
class Lion {
}
2) 멤버 변수와 메소드
- 멤버 변수(필드) : 클래스 내부에 정의된 변수
- 멤버 메소드(메소드) : 클래스 내부에 정의된 메소드
- 멤버 변수와 메소드는 관행적으로 소문자로 시작함
class Lion {
// 멤버 변수
int hegiht;
int weight;
// 멤버 메소드
int running() {...}
boolean fight(Lion) {...}
}
3) 메소드 구현하기
- 메소드 : 반복되어 실행될 명령문들을 모아놓은 모듈
// 메소드 반환값 자료형(여기서는 int) + 메소드 이름(입력 매개 변수)
int running(int a, int b) {
...
return result;
}
- 반환값 규칙
- 반환값이 있는 경우 : return문에서 반환하는 값의 자료형과 일치해야 함
- 반환값이 없는 경우 : void로 정의하고, return문 생략 가능
// 반환값이 있는 경우
int running(int a, int b) {
int c = a*b;
...
return c;
}
// 반환값이 없는 경우
void running(int a, int b) {
int c = a*b;
...
return; // 생략 가능
}
4) 입력 매개 변수
- 입력 매개 변수를 지정하지 않아도 됨
- 입력 매개 변수의 개수는 원하는 만큼 정의하여 사용
// 입력 매개 변수가 있는 경우
int running(int a, int b){
int c = a*b;
...
return c;
}
// 입력 매개 변수가 없는 경우
int running( ){
int c = a*b;
...
return c;
}
5) main() 메소드
- 프로그램의 시작 메소드
- 클래스 내부에 정의되지만 멤버 메소드는 아님
class Lion {
public static void main(String[] args) {
....
}
}
6) 객체 생성하기
- main() 메소드에서 생성함
class Lion {
public static void main(String[] args) {
Lion a = new Lion();
Lion b = new Lion();
}
}
7) 멤버 변수와 메소드 사용하기
- 멤버 변수는 객체 생성 시 자동 초기화 됨
- 수치 관련 변수는 0
- 문자 관련 변수는 null
- 멤버 변수와 메소드는 객체 생성 후 사용
class Lion {
public static void main(String[] args) {
// Lion 클래스 객체 생성
Lion a = new Lion();
Lion b = new Lion();
// Lion 클래스의 멤버 변수 사용
a.age = 10;
b.age = 5;
// Lion 클래스의 멤버 메소드 호출
int ar = a.running();
int br = b.running();
}
}
8) 멤버 메소드 호출 과정
- 인수 : 메소드를 호출할 때 전달하는 값
- 매개변수 : 메소드를 호출할 때 전달되는 인수의 값을 저장하는 변수
- 인수와 매개변수는 나열한 순서대로 1:1 매칭되고, 자료형이 일치해야 함
class Lion {
int age;
int running(int x, int y) {
int result = (age*x) - y;
return result;
}
public static void main(String[] args) {
Lion a = new Lion();
a.age = 10;
// 객체 a의 멤버 메소드 running 호출
// 첫 번째 인수 5는 첫 번째 매개변수 x에 저장
// 두 번째 인수 20은 두 번째 매개변수 y에 저장
int ar = a.running(5, 20);
}
}
가비지 콜렉팅(garbage collecting)의 이해
- 필요 없어진 메모리를 해제하여 시스템에 반환하는 것
- 자바언어는 JVM이 자동으로 메모리를 해제함
- 객체 생성 후 메모리를 해제하려면 null 값을 지정해 주어야 자동으로 가비지 콜렉팅이 수행됨
Lion a = new Lion();
a = null;
// 명시적으로 가비지 콜렉팅을 수행하는 방법
System.gc();
클래스 선언 사용 실습
public class Lion {
int height;
int weight;
int age;
boolean sex; //true:남, false:여
int running(int x, int y) { // 달리기
int result = (age*x)-y;
return result;
}
boolean fight(Lion x) {// 싸우기
boolean result;
if (height > x.height && weight > x.weight)
result = true;
else result = false;
return result;
}
boolean hunting() { // 사냥하기
if(age>20) return false;
else return true;
}
String sleeping() {
return "Going to Sleep!!!";
}
// 객체의 멤버 변수(필드)를 화면에 출력하는 메소드
void printOut() {
System.out.println("height="+height);
System.out.println("weight="+weight);
System.out.println("age="+age);
System.out.println("sex="+(sex?"MAIL":"FEMALE"));
}
public static void main(String[] args) {
Lion a = new Lion();
Lion b = new Lion();
a.height = 160;
a.weight = 100;
a.age = 10;
a.sex = true;
b.height = 130;
b.weight = 90;
b.age = 9;
b.sex = false;
System.out.println("[A Lion]");
a.printOut();
System.out.println("running = "+a.running(5, 20));
System.out.println("hunting = "+a.hunting());
System.out.println("[B Lion]");
b.printOut();
System.out.println("running = "+b.running(6, 30));
System.out.println("hunting = "+b.hunting());
boolean result = b.fight(a); // a와 b가 싸우기
String win = result?"B Lion WIN!":"A Lion WIN!";
System.out.println("A FIGHT B : "+win);
System.out.println("A Lion : "+a.sleeping());
System.out.println("B Lion : "+b.sleeping());
a = b = null;
System.gc();
}
}
[A Lion]
height=160
weight=100
age=10
sex=MAIL
running = 30
hunting = true
[B Lion]
height=130
weight=90
age=9
sex=FEMALE
running = 24
hunting = true
A FIGHT B : A Lion WIN!
A Lion : Going to Sleep!!!
B Lion : Going to Sleep!!!
메소드 이해하기
1) 생성자(constructor) 메소드란?
- 객체 생성시 호출되는 메소드
- 멤버 변수의 초기화 작업할 때 사용
2) 생성자 메소드 규칙
- 클래스 이름과 동일해야 함
- public 키워드 지정 (필수는 아님)
- 반환값 자료형은 지정하지 않음
- 반환값이 없다는 의미의 void도 지정하지 않음
3) 디폴트(default) 생성자 메소드 이해하기
- 매개변수가 없는 생성자 메소드
- 생략할 경우 JVM이 있는 것처럼 컴파일 및 실행함
class Lion{
public Lion() {
}
public static void main(String[] args){
Lion a = new Lion();
}
}
4) 사용자 정의 생성자 메소드 이해하기
- 매개변수가 있는 생성자 메소드
- 디폴트 생성자 메소드와 동시에 정의하여 사용 가능
class Lion{
int age;
public Lion() {
}
public Lion(int x){
age = x;
}
public static void main(String[] args){
Lion a = new Lion(); // 디폴트 생성자 메소드 호출
Lion b = new Lion(10); // 사용자 정의 생성자 메소드 호출
}
}
5) 생성자 메소드 정의 시 유의할 점
- 사용자 정의 생성자 메소드가 정의되어 있지 않은 경우
- 디폴트 생성자 메소드를 생략해도 JVM이 디폴트 생성자 메소드가 있는 것처럼 컴파일 및 실행함
- 사용자 정의 생성자 메소드가 정의되어 있는 경우
- 디폴트 생성자 메소드를 생략하면 JVM이 디폴트 생성자 메소드가 있는 것처럼 컴파일 및 실행을 하지 못함
- 따라서 클래스 정의 시 디폴트 생성자 메소드를 항상 정의하면 문제는 없음
생성자 메소드 실습
import java.lang.reflect.Constructor;
public class ConstructorLion {
int height;
int weight;
int age;
boolean sex;
// 디폴트 생성자 메소드
public ConstructorLion() {
}
// 사용자 정의 생성자 메소드
public ConstructorLion(int g, boolean s) {
// 멤버변수 초기화
height = weight = 0;
age = g;
sex = s;
}
public ConstructorLion(int h, int w, int g, boolean s) {
height = h;
weight = w;
age = g;
sex = s;
}
int running(int x, int y) { // 달리기
int result = (age*x)-y;
return result;
}
boolean fight(Lion x) {// 싸우기
boolean result;
if (height > x.height && weight > x.weight)
result = true;
else result = false;
return result;
}
boolean hunting() { // 사냥하기
if(age>20) return false;
else return true;
}
String sleeping() {
return "Going to Sleep!!!";
}
// 객체의 멤버 변수(필드)를 화면에 출력하는 메소드
void printOut() {
System.out.println("height="+height);
System.out.println("weight="+weight);
System.out.println("age="+age);
System.out.println("sex="+(sex?"MAIL":"FEMALE"));
}
public static void main(String[] args) {
ConstructorLion a = new ConstructorLion();
ConstructorLion b = new ConstructorLion(10, true);
ConstructorLion c = new ConstructorLion(190, 200, 7, false);
/*
a.height = 160;
a.weight = 100;
a.age = 10;
a.sex = true;
b.height = 130;
b.weight = 90;
b.age = 9;
b.sex = false;
*/
System.out.println("[A Lion]");
a.printOut();
System.out.println("[B Lion]");
b.printOut();
System.out.println("[C Lion]");
c.printOut();
a = b = c = null;
System.gc();
}
}
[A Lion]
height=0
weight=0
age=0
sex=FEMALE
[B Lion]
height=0
weight=0
age=10
sex=MAIL
[C Lion]
height=190
weight=200
age=7
sex=FEMALE
객체 생성 시 인수를 다르게 하여 멤버 변수를 초기화한다.
메소드 오버로딩(overloading)
- 하나의 클래스 내부에 동일한 이름의 메소드를 여러 개 정의하는 것
- 생성자 메소드도 메소드 오버로딩 가능
메소드 오버로딩 규칙
- 메소드 이름은 동일해야 함
- 매개 변수의 개수가 달라야 함
- 매개 변수의 개수가 같다면 매개 변수의 자료형이 달라야 함
- 메소드의 반환값 자료형은 메소드 오버로딩 규칙에 포함되지 않음
- 매개 변수의 개수와 자료형이 동일한 상태에서 반환값 자료형을 다르게 한다고 하여도 메소드 오버로딩이 되지 않아 오류 발생
class Lion {
int running(int x, int y);
int running(int x);
int running(double x);
String running(int x); // 메소드 오버로딩 규칙 위반
}
메소드 가변 인수
- 메소드의 인수를 가변으로 지정하는 것
- 인수의 개수는 1부터 n개 까지 지정 가능
메소드 가변 인수 규칙
- 가변 인수는 "… "로 표현
- 다른 자료형의 인수가 같이 정의될 경우 가변 인수는 마지막에 정의
- 가변 인수는 1차원 배열로 처리
class Lion {
boolean hunting(int ... x);
boolean hunting(String t, int ...x);
public static void main(String[] args) {
Lion a = new Lion();
boolean b = a.hunting(10, 20 ,30);
boolean c = a.hunting("rabbit", 20, 30, 40, 50, 60);
}
}
메소드 오버로딩과 가변 인수 실습
import java.lang.reflect.Constructor;
public class OverloadingLion {
int height;
int weight;
int age;
boolean sex;
int speed;
public OverloadingLion() {
}
public OverloadingLion(int g, boolean s) {
// 멤버변수 초기화
height = weight = 0;
age = g;
sex = s;
}
public OverloadingLion(int h, int w, int g, boolean s) {
height = h;
weight = w;
age = g;
sex = s;
}
int running(int x, int y) { // 달리기
int result = (age*x)-y;
return result;
}
int running(int x) {
int result = (age*x);
return result;
}
int running(double x) {
double result = (age*x);
return (int)result;
}
boolean fight(OverloadingLion x) {// 싸우기
boolean result;
if (height > x.height && weight > x.weight)
result = true;
else result = false;
return result;
}
boolean hunting() { // 사냥하기
if(age>20) return false;
else return true;
}
boolean hunting(int ... x) { // 가변 인수
int sum=0;
for(int i=0; i<x.length; i++) sum += x[i];
if(sum<50) return false;
else return true;
}
boolean hunting(String name, int ... x) {
System.out.print("[Hunting.."+name+"]");
int sum = 0;
for(int i=0; i<x.length; i++) sum += x[i];
if(sum<50) return false;
else return true;
}
String sleeping() {
return "Going to Sleep!!!";
}
void printOut() {
System.out.println("height="+height);
System.out.println("weight="+weight);
System.out.println("age="+age);
System.out.println("sex="+(sex?"MAIL":"FEMALE"));
}
public static void main(String[] args) {
OverloadingLion a = new OverloadingLion(190, 100, 10, true);
System.out.println("[A Lion]");
System.out.println("int running(int, int) : "+a.running(5, 10));
System.out.println("int running(int) : "+a.running(5));
System.out.println("int running(double) : "+a.running(5.5));
OverloadingLion b = new OverloadingLion(180, 70, 5, false);
System.out.println("[B Lion]");
System.out.println("int hunting(int ... x) : "+b.hunting(10, 8, 6));
System.out.println("int hunting(String name, int ... x) : "+b.hunting("rabbit", 10, 20, 30, 40, 50));
a = b = null;
System.gc();
}
}
[A Lion]
int running(int, int) : 40
int running(int) : 50
int running(double) : 55
[B Lion]
int hunting(int ... x) : false
[Hunting..rabbit]int hunting(String name, int ... x) : true
this 키워드
- 클래스 내부에서 현재 자신의 객체를 참조하는 참조 변수
- 멤버 변수나 멤버 메소드를 참조하는 참조 변수
class Lion {
int height;
int age;
// 멤버 변수와 매개 변수의 이름이 달라 가독성이 떨어짐
public Lion(int a, int b){
height = a;
age = b;
}
// this 키워드를 이용하여 매개 변수의 이름 == 매개 변수의 이름 (가독성이 좋음)
public Lion(int hegiht, int age) {
this.height = height;
this.age = age;
}
}
this() 메소드
- 생성자 메소드 내부에서 다른 생성자 메소드를 호출
- 생성자 메소드 내부에서 첫 줄에 한번만 사용 가능
- 생성자 메소드 내부에서 중복된 코드를 줄일 수 있음
class Lion {
public Lion(int a){
height = a;
}
public Lion(int a, int b){
height = a;
age = b;
}
}
// 다음과 같이 바꿀 수 있다.
class Lion {
public Lion(int a){
height = a;
}
public Lion(int a, int b){
this(a); // 생성자 메소드 호출
age = b;
}
}
정적(static) 멤버 변수
- 해당 클래스로 생성된 모든 객체에서 변수의 값을 공유함
- 클래스의 객체 생성 없이 사용 가능(클래스 이름으로 정적 멤버 변수 접근)
- 멤버 변수 선언 시 static 키워드 지정
class Lion {
static int age;
public static void main(String[] args) {
Lion a = new Lion();
Lion b = new Lion();
Lion.age = 10; // Lion 클래스를 이용하여 정적 멤버 변수에 값 지정 (age = a = b = 10)
System.out.println(Lion.age + a.age + b.age); // 30
a.age = 20; // a 객체를 이용하여 정적 멤버 변수에 값 지정 (age = a = b = 20)
System.out.println(Lion.age + a.age + b.age); // 60
}
}
정적 멤버 메소드
- 클래스의 객체 생성 없이 메소드 사용 가능(클래스 이름으로 접근)
- 멤버 메소드 선언 시 static 키워드 지정
class Lion {
static String whoami(); {
return "Lion";
}
public static void main(String[] args) {
Lion a = new Lion();
System.out.println(Lion.whoami()); // Lion
System.out.println(a.whoami()); // Lion
}
}
this, this(), 정적 변수 및 메소드 실습
public class ThisLion {
int height;
int weight;
int age;
boolean sex;
static String name; // 정적 멤버 변수 선언
static int version;
public ThisLion() { // 디폴트 생성자 메소드
}
public ThisLion(int age, boolean sex) {
this.age = age;
this.sex = sex;
}
public ThisLion(int height, int weight, int age, boolean sex) {
this(age, sex); // 생성자 메소드 호출
this.height = height;
this.weight = weight;
}
int running(int x, int y) { // 달리기
int result = (age*x)-y;
return result;
}
int running(int x) {
int result = (age*x);
return result;
}
int running(double x) {
double result = (age*x);
return (int)result;
}
boolean fight(ThisLion x) {// 싸우기
boolean result;
if (height > x.height && weight > x.weight)
result = true;
else result = false;
return result;
}
boolean hunting() { // 사냥하기
if(age>20) return false;
else return true;
}
boolean hunting(int ... x) { // 가변 인수
int sum=0;
for(int i=0; i<x.length; i++) sum += x[i];
if(sum<50) return false;
else return true;
}
boolean hunting(String name, int ... x) {
System.out.print("[Hunting.."+name+"]");
int sum = 0;
for(int i=0; i<x.length; i++) sum += x[i];
if(sum<50) return false;
else return true;
}
String sleeping() {
return "Going to Sleep!!!";
}
void printOut() {
System.out.println("height="+height);
System.out.println("weight="+weight);
System.out.println("age="+age);
System.out.println("sex="+(sex?"MAIL":"FEMALE"));
}
static String whoami() { // 정적 멤버 메소드 정
return "[This is "+name+" Class]";
}
public static void main(String[] args) {
ThisLion a = new ThisLion(190, 100, 10, true);
System.out.println("[A Lion]");
a.printOut();
ThisLion b = new ThisLion(180, 70, 5, false);
System.out.println("[B Lion]");
b.printOut();
// 정적 멤버 메소드
ThisLion.name = "Lion";
System.out.println("ThisLion.whoami() : "+ThisLion.whoami());
System.out.println("a.whoami() : " + a.whoami());
System.out.println("b.whoami() : " + b.whoami());
a.name = "Lion's King";
System.out.println("ThisLion.whoami() : "+ThisLion.whoami());
System.out.println("a.whoami() : " + a.whoami());
System.out.println("b.whoami() : " + b.whoami());
// 정적 멤버 변수
ThisLion.version = 10;
System.out.println("version = " + (ThisLion.version+a.version+b.version));
a.version = 20;
System.out.println("version = " + (ThisLion.version+a.version+b.version));
b.version = 30;
System.out.println("version = " + (ThisLion.version+a.version+b.version));
a = b = null;
System.gc();
}
}
[A Lion]
height=190
weight=100
age=10
sex=MAIL
[B Lion]
height=180
weight=70
age=5
sex=FEMALE
ThisLion.whoami() : [This is Lion Class]
a.whoami() : [This is Lion Class]
b.whoami() : [This is Lion Class]
ThisLion.whoami() : [This is Lion's King Class]
a.whoami() : [This is Lion's King Class]
b.whoami() : [This is Lion's King Class]
version = 30
version = 60
version = 90
적용하기
1) Robot 클래스 설계 및 구현
2) 특성 : 현재 위치, 각도, 작업량
3) 기능 : 이동하기, 작업하기
4) 필요에 따라 특성 및 기능 추가
5) 생성자 메소드, 멤버 메소드, 정적 변수, 정적 메소드, 가변 인자 사용
(내 예제)
public class Robot {
// 현재 위치, 각도, 작업
int location;
int angle;
int workload;
//생성자 메소드
public Robot(int loc, int ang, int work) {
this.location = loc;
this.angle = ang;
this.workload = work;
}
// 이동하기 (x와 y만큼 이동하기)
public int moving(int x, int y) {
int result1 = x * y;
return result1;
}
// 작업하기 (40시간만 작동하는 로봇)
public String doWork(int workHour) {
if(workHour >= 40) {
return "40시간을 경과하여 작동을 종료합니다.";
} else {
return "누적 40시간까지 작동이 가능합니다.";
}
}
public static void main(String[] args) {
// 가까운 거리에서 20시간 일 한 로봇
Robot robot1 = new Robot(5, 10, 20);
// 먼 거리에서 45시간 일 한 로봇
Robot robot2 = new Robot(40, 80, 45);
System.out.println("==================");
System.out.println("robot1의 현재 위치는 " + robot1.moving(5, 10)+" 입니다.");
System.out.println("robot1의 작업량은 " + robot1.doWork(20));
System.out.println("robot2의 현재 위치는 " + robot2.moving(40, 80)+" 입니다.");
System.out.println("robot2의 작업량은 " + robot2.doWork(45));
System.out.println("==================");
}
}
==================
robot1의 현재 위치는 50 입니다.
robot1의 작업량은 누적 40시간까지 작동이 가능합니다.
robot2의 현재 위치는 3200 입니다.
robot2의 작업량은 40시간을 경과하여 작동을 종료합니다.
==================
(해설)
public class Robot {
static String name = "Robot Arm"; // 로봇 이름
static int limitX = 100; // 로봇 x 좌표 한계
static int limitY = 200; // 로봇 y 좌표 한계
int x; // 로봇의 현재 x 좌표
int y; // 로봇의 현재 y 좌표
int angle; // 로봇팔의 각도
static int job; // 로봇팔로 물건 옮긴 횟수
public Robot() {
}
public Robot(int x, int y, int angle) {
this.x = x;
this.y = y;
this.angle = angle;
}
public Robot(int x, int y, int angle, int job) {
this(x, y, angle);
this.job = job;
}
boolean gotoxy(int x, int y) { // 로봇 좌표 이동
int tx = this.x + x;
int ty = this.y + y;
if(tx> limitX || ty > limitY) { // 좌표 이동 한계를 넘으면 에러 발생
System.out.println("ERROR XY!!");
return false;
} else {// 좌표 이동 한계 내이면 로봇 이동
System.out.println("MOVE XY ["+tx+","+ty+"]");
this.x = tx;
this.y = ty;
return true;
}
}
void gotoxy(int ... xy) { // 로봇 좌표 이동(가변 인자) x1, y1, x2, y2, ...
for(int i=0; i<xy.length; i+=2) {
boolean result = gotoxy(xy[i], xy[i+1]);
if(result == false) break; // 좌표이동시 에러 발생하면 이동 종료
}
}
void armAngle(int angle) { // 로봇팔 각도 조정
int ta = this.angle + angle;
if(ta > 360) this.angle = ta - 360;
else if (ta < 0) this.angle = 360 + ta;
else {
this.angle = ta;
System.out.println("Robot Angle : "+this.angle);
}
}
void pickup() {
System.out.println("xy["+x+","+y+"], angle ["+angle+"] Pick up !!");
}
void putdown() {
System.out.println("xy["+x+","+y+"], angle ["+angle+"] Put down !!");
Robot.job++; // 물건을 내려놓으면 한번 작업(로봇이 여러대 있으면 모든 로봇의 작업량 카운터)
}
static String whoami() {
String result = "Robot name : "+Robot.name + "Limit XY["+limitX+","+limitY+"]";
return result;
}
public static void main(String[] args) {
System.out.println(Robot.whoami());
Robot a = new Robot(10, 10, 10);
Robot b = new Robot(20, 20, 10, 100);
boolean ok = a.gotoxy(15, 15); // 좌표 이동
if (ok) {
a.armAngle(150); // 각도 조정
a.pickup(); // 물건 잡기
a.putdown(); // 물건 내려놓기
}
ok = b.gotoxy(95, 80); // 좌표 이동
if(ok) {
b.armAngle(355);
b.pickup();
b.putdown();
}
System.out.println("Job Count = "+Robot.job);
}
}
Robot name : Robot ArmLimit XY[100,200]
MOVE XY [25,25]
Robot Angle : 160
xy[25,25], angle [160] Pick up !!
xy[25,25], angle [160] Put down !!
ERROR XY!!
Job Count = 101
어렵다 ^-ㅠ..................
'온라인 강좌 > 안드로이드 프로그래밍을 위한 자바기초' 카테고리의 다른 글
8차시 자바 기본 라이브러리 활용하기 (0) | 2023.07.12 |
---|---|
7차시 상속을 활용한 객체지향 프로그래밍 기본 문법 이해하기 (0) | 2023.07.11 |
5차시 배열의 기본 문법 이해하기 (0) | 2023.07.09 |
4차시 조건문과 반복문의 기본 문법 이해하기 (0) | 2023.07.08 |
3차시 연산자의 기본 문법 이해하기 (0) | 2023.07.08 |