1. 객체지향 프로그래밍

- 데이터와 함수를 하나의 덩어리로 묶어서 생각하는 방법: 캡슐화

public class Circle {
	double radius;           // data
	String color;            // data
	double getArea() {return 3.14*radius*radius; }   // func
}

 

2. 정보 은닉

- 객체의 외부에서는 내부 데이터와 알고리즘을 볼 수 없게 함

- 공개된 인터페이스를 통해서만 객체에 접근하도록

 

3. 상속

- 이미 작성된 클래스(부모 클래스)를 이어받아서 새로운 클래스(자식 클래스) 생성 가능

- 자식 클래스는 부모의 속성과 동작 물려받음

 

4. 클래스

- 객체에 대한 설계도 (틀)

- 클래스로부터 만들어지는 각각의 객체 -> '인스턴스'

- 하나의 클래스로 여러 인스턴스를 만들어내지만, 인스턴스마다 속성의 값은 다름

public class Circle {
    // 필드
    public int radius;
    public String color;
    
    // 메소드
    public double getArea() {
        return 3.14*radius*radius;
    }
}

 

5. 객체 생성

- 참조 변수 선언

//Type   변수명  
 Circle   obj;

- 객체 생성

//변수       객체의 참조값
  obj = new Circle();

 

public class CircleTest {
    public static void main(String[] args) {
        // 참조 변수 선언
        Circle obj;
        
        // 객체 생성 & 객체의 참조값 -> 참조 변수에 저장
        obj = new Circle();
        
        // 객체의 필드 사용
        obj.radius = 100;
        obj.color = "blue";
        
        // 객체의 메소드 사용
        double area = obj.getArea();
        System.out.println("원의 면적= " + area);
    }
}

 

6. 참조 변수

- 객체 를 참조할 때 사용되는 변수 - 객체의 참조값이 저장되어 있음

- 참조값은 일반적으로 객체의 주소

- 자바에서 모든 객체는 new 연산자를 이용해야 생성됨

public class DeskLamp {
    // 인스턴스 변수 정의
    private boolean isOn;
    
    // 메소드 정의
    public void turnOn()  { isOn = true; }
    public void turnOff() { isOn = false; }
    public String toString() {
        return "현재 상태는" + (isOn == true ? "켜짐" : "꺼짐");
    }
}

public class DeskLampTest {
    public static void main(String[] args) {
        // 객체 생성
        DeskLamp myLamp = new DeskLamp();
        
        // 객체의 메소드 호출
        myLamp.turnOn();
        System.out.println(myLamp);
        myLamp.turnOff();
        System.out.println(myLamp);
    }
}

 

7. 메소드 오버로딩

- 이름이 동일한 여러 개의 메소드 작성 가능

- 매개변수의 수, 타입, 순서 등이 달라야 함

public class MyMath {
    int add(int x, int y)          { return x+y; }
    int add(int x, int y, int z)   { return x+y+z; }
    int add(int x, int y, int z, int w)   { return x+y+z+w; }
    
    public static void main(String[] args) {
        MyMath obj;
        obj = new MyMath();
        System.out.println(obj.add(10, 20));
        System.out.println(obj.add(10, 20, 30));
        System.out.println(obj.add(10, 20, 30, 40));
    }
}

 

8. 생성자

- 객체가 생성될 때 객체를 초기화하는 특수한 메소드

- 중복 정의 가능

class Pizza {
    int size;
    String type;
    public Pizza 90 {
        size = 12;
        type = "슈퍼슈프림";
    }
    
    public Pizza(int s, String t) {
        size = s;
        type = t;
    }
}

public class PizzaTest {
    public static void main(String[] args) {
        Pizza obj1 = new Pizza();
        System.out.println("(" + obj1.type + ", " + obj1.size + ",)");
        
        Pizza obj2 = new Pizza(24, "포테이토");
        System.out.println("(" + obj2.type + ", " + obj2.size + ",)");

 

9. 기본 생성자

- 매개변수 없는 생성자

- 생성자 하나도 정의하지 않으면 컴파일러가 자동으로 기본 생성자 만듦

 

10. this 참조 변수

- 현재 객체 자신을 가리키는 참조 변수

- 컴파일러에서 자동으로 생성

- 생성자에서 매개 변수 이름과 필드 이름이 동일한 경우에 사용

public Circle (int radius) {
    this.radius = radius;
}

 

11. this()

- 다른 생성자 의미

 

12. 접근 제어

- private: 클래스 안에서만 접근 가능

- public: 누구나 접근 가능

- protected: 자식 클래스만 접근 가능

- 접근지정자 x (default) : 동일 패키지 안에서만 접근 가능

 

13. 접근자와 설정자

- 접근자 (getters) 메소드: 필드값 반환

- 설정자 (setters) 메소드: 필드값 설정

 

- 접근자와 설정자 메소드만을 통해 필드에 접근해야 함!

- 설정자에서 매개변수를 통해 잘못된 값이 넘어오는 경우, 이를 사전에 차단할 수 있음

- 필요할 때마다 필드값을 동적으로 계산하여 반환할 수 있음

- 접근자만 제공 -> 읽기만 가능한 필드 만들 수 있음

- Source 메뉴에서 자동 입력 가능

 

class Account {
    private int regNumber;
    private String name;
    private int balance;
    
    // 접근자
    public String getName() {
    	return name;
    }
    
    // 설정자
    public String setName(String name) {
    	this.name = name;
    }
    
    public int getBalance() {
    	return balance;
    }
    
    public int setBalance(int balance) {
    	this.balance = balance;
    }
}

 

14. 객체의 소멸과 가비지 컬렉션

- 객체 삭제 연산자 없음

- 자동 메모리 시스템 사용: 가비지 컬렉션

 

- 가비지 컬렉터: 힙 메모리에서 더이상 필요없는 객체를 찾아 지움

- 가비지 컬렉션 요청 -> 모든 다른 애플리케이션 멈춤 -> JVM이 실행 여부 판단

System.gc;

 

15. 인수전달 방법

- 기본적으로 Call by value

- 객체를 메소드로 전달 -> 객체의 참조값만 복사되어 전달됨

- 참조 변수는 참조값(주소) 갖고 있음

- 배열도 객체 -> 배열 전달은 배열 참조 변수를 복사하는 것

 

public class ArrayArgumentTest {
	public static double minArray(double[] list) {
    	double min = list[0];
        for (int i = 1; i < list.length; i++) {
        	if(list[i] < min) 
            	min = list[i];
        }
        return (min);
    }
    
    public static void main(String[] args) {
    	double[] a = { 1.1, 2.2, 3.3, 4.4, 0.1, 0.2 };
        double[] b = { -2.0, 3.0, -9.0, 2.9, 1.5 };
        double min;
        
        min = minArray(a);
        System.out.println("첫번째 배열의 최솟값= " + min);
        min = minArray(b);
        System.out.println("두번째 배열의 최솟값= " + min);
    }
}

// 0.1
// -9.0

 

16. 정적 멤버

- 여러 개의 객체가 하나의 변수를 공유해야 하는 경우 

-> 이러한 멤버를 정적 멤버 (static member) / 클래스 멤버 (class member) 라고 함 

- 정적 변수: 클래스 당 하나만 생성되는 변수

- 여러 개가 존재할 수 있음, 한개의 static 변수는 한 번 선언됨

 

- 클래스를 통한 접근

Television.count = 100;

 

- 객체를 통한 접근

Television obj = new Televison();
obj.count = 100;

 

- 정적 메소드: 객체를 생성하지 않고 클래스 이름으로 접근해서 사용 가능

public class Math {
	public static double sqrt(double a) {
    	...
    }
}
...
double value = Math.sqrt(9.0);  // 클래스.함수명 으로 사용

 

17. 정적 변수의 활용

- 정적 메소드는 정적 멤버만 사용할 수 있음

class Test {
    int a;              // 인스턴스 변수
    static int b;       // 정적 변수
    
    void sub1() { a = 0; }         // OK
    static void sub2() { a = 0; }  // 오류! 정적 메소드에서는 인스턴스 멤버 사용할 수 없음

- 정적 메소드에서 정적 메소드를 호출하거나 정적 멤버를 사용하는건 가능

- 정적 메소드는 this를 사용할 수 없음

class Test {
    static int a;
    static void sub(int x) { this.a = x; }    // 오류!

 

- main()도 정적 메소드이기 때문에 인스턴스 메소드를 호출할 수 없음

- 정적 메소드는 main()에서 호출 가능!

public class Test {
    public static int cube(int x) {
        int result = x*x*x;
        return result;
    }
    
    public static void main(String args[]) {
        System.out.println("10*10*10은 " + cube(10));   // 정적 메소드 호출
    }
}

 

18. final 키워드

- 필드에 final을 붙이면 상수가 됨

- static과 동시에 사용하는 경우 많음

public class Car {
    static final int MAX_SPEED = 100;
}

- 상수는 클래스 변수로 만들어서 공유하는 것이 메모리 공간 절약

 

19. 싱글톤 패턴

- 객체 중 전체 시스템을 통틀어서 딱 하나만 존재해야 하는 것들이 있음

- ex) 환경설정 클래스, 네트워크 연결 풀 / 스레드 풀을 관리하는 클래스들

- 싱글톤 패턴은 하나의 프로그램 내에서 하나의 인스턴스만을 생성해야 하는 경우에 사용

 

class Single {
    private static Single instance = new Single();   
    private Single() { }      // 전용 생성자
    
    public static Single getInstance() {
        return instance;
    }
}

public class SingleTest {
    public static void main(String[] args) {
        Single obj1 = Single.getInstance();
        Single obj2 = Single.getInstance();
        System.out.println(obj1);
        System.out.println(obj2);
    }
}

 

20. 객체배열

- 객체를 저장하는 배열

- 객체에 대한 참조값 저장

 

class Rect {
    int width, height;
    
    public Rect(int w, int h) {
        this.width = w;
        this.height = h;
    }
    
    double getArea() {
        return (double) width * height;
    }
}

public class RectArrayTest {
    public static void main(String[] args) {
        Rect[] list = new Rect[5];             // 객체 배열 생성
        
        for (int i = 0; i < list.length; i++)
            list[i] = new Rect(i,i);           // 배열에 객체 값 저장 
            
        for (int i = 0; i < list.length; i++)
            System.out.println(i + "번째 사각형의 면적= " + list[i].getArea());
    }
}

/** 
0번째 사각형의 면적= 0.0
1번째 사각형의 면적= 1.0
2번째 사각형의 면적= 4.0
3번째 사각형의 면적= 9.0
4번째 사각형의 면적= 16.0
**/

 

for(int i = 0; i < list.length; i++)
     list[i] = new Rect(i, i);

 

21. 동적 객체 배열

- ArrayList<>

import java.util.ArrayList;

public class ArrayListTest {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        list.add("홍콩");
        list.add("싱가포르");
        list.add("괌");
        list.add("사이판");
        list.add("하와이");
        
        System.out.println("여행지 추천 시스템");
        int index = (int)(Math.random()*list.size());
        System.out.println("추천 여행지는 " + list.get(index));
    }
}

- list.add(); 로 추가

 

import java.util.ArrayList;

class Person {
    String name;
    String tel;
    
    public Person(String name, String tel) {
        this.name = name;
        this.tel = tel;
    }
}

public class ArrayListTest2 {
    public static void main(String[] args) {
        ArrayList<Person> list = new ArrayList<Person>();
        list.add(new Person("Anna", "01023459293"));
        list.add(new Person("Jane", "01082983491"));
        list.add(new Person("Jim", "01012349722"));
        list.add(new Person("Emily", "01092938475"));
        for (Person obj : list)
            System.out.println("(" + obj.name + "," + obj.tel + ")");
    }
}

'Software > JAVA' 카테고리의 다른 글

[JAVA] Day6. 추상클래스, 인터페이스, 중첩클래스  (0) 2022.12.29
[JAVA] Day5. 상속  (0) 2022.12.29
[JAVA] Day2. 조건문, 반복문, 배열  (0) 2022.12.27
[JAVA] Day1. 자바 기초  (0) 2022.12.27
[JAVA] 예외처리  (0) 2021.07.22

[수업출처] 숙명여자대학교 소프트웨어학부 유석종 교수님 수업 '자료구조'

 

1. Data Structures

- 문제 해결을 위한 대량의 데이터를 효율적으로 처리하고 조직하는 방법 또는 구조

 

- Linear DS: list, stack, queue, deque

- Non-Linear DS: tree, graph

- Advanced DS: BST, Weight networks

- Searching and Sorting algorithms

 

2. Algorithm

- 특정 작업을 수행하기 위한 명령어들의 유한한 집합

- 조건

    - Input: 명시적 입력이 필요하지 않다.

    - Output: 적어도 하나의 출력값이 있어야 한다.

    - Definiteness: 구체적이고 모호하지 않은 명령어들의 집합이어야 한다.

    - Finiteness: 유한한 단계를 거친 후 끝나야 한다.

    - Effectiveness: 쓸모 있어야하고, 효율적이어야 한다.

- 표현 방법

    - Pseudo code, Flow chart

    - 자연어, 프로그래밍 언어

 

3. System Life Cycle

- Requirement 요구사항 명세

    - 프로젝트의 목적을 정의하는 일련의 설계 명세서

    - 사용자, 플랫폼, 함수, 인터페이스 등

- Analysis 분석

    - 큰 프로젝트를 작은 모듈들로 나누는 과정

    - Divide and conquer 전략

    - Top-down approach

        - 주 목적에서 구성요소로 가는 계층적 접근

        - program -> subroutines -> instructions

    - Bottom-up approach

        - 구성요소가 모여 전체 시스템이 되는 방법

- Design 설계

    - 각 모듈에 대한 객체와 함수 정의

- Implementation 구현

    - 객체 및 알고리즘 코드 구현

- Verification 검증

    - 알고리즘의 정확성 증명

    - program test: black-box test, white-box test

 

4. Fibonacci Numbers

# fb는 리스트

def fibo(fb):
    a = 0
    b = 1
    fb.append(a)
    fb.append(b)
    while True:
    	a, b = b, a+b
        if b < n: break
        fb.append(b)

피보나치 수열을 구하는 함수이다.

리스트에 우선 0과 1을 넣고, b가 n이 되기 전까지 a = b, b = a+b로 대입하여 b, 즉 a+b를 리스트에 추가한다.

 

n = 100000
fb = []
fibo(fb)
print(fb)
print("# of fibos", len(fb))

 

5. Prime Numbers

- 소수: 1보다 큰 자연수 중 1과 자기자신 이외의 수로 나누어 떨어지지 않는 수

 

def find_prime(num):
    for i in range(2, num+1):
        prime = 1
        for j in range(2, i):
            if i % j == 0:
                prime = 0
                break
        if prime: prime_list.append(i)

2부터 num까지의 수를 각각 i로 둘 때, i를 2부터 i까지의 수로 나누어 본다. 

이 때, 나누어 떨어지면 소수가 아니기 때문에 prime = 0으로 둔다. 

i까지 전부 나눈 후  prime이 여전히 1이면 소수이기 때문에 prime_list에 추가한다. 

이 과정을 num까지 반복한다.

 

prime_list = []
max_num = 1000
find_prime(max_num)


for i in range(2, max_num):
    if i in prime_list: print('%3d' %i, end = '')
    else: print('_', end = '')
    if i % 50 == 0: print()
print()
print('# of prime numbers = ', len(prime_list))

 

6. Data Types

- 객체와 해당 객체에 작용하는 명령어들의 집합

 

- 내장 자료형

    - Basic type: char, int, float

    - Collection type: string, list, tuple, set, dictionary

 

- 추상 자료형

    - 객체의 자료형

 

7. Abstract Data Type (ADT) 추상 자료형

- 객체의 속성(attributes, properties, member variables)과 행동(methods, operations, member funtions)을 추상화하는 자료형

- 사용자가 필요에 의해 자료형을 직접 정의하는 것

- 객체지향 프로그래밍에서는 공통적인 행위를 하는 Class를 정의한다.

- ex) bank account, student, fraction

 

8. Fraction 분수

- 분자와 분모로 이루어져 있다.

- 기본적으로 분수는 내장되어있지 않기 때문에 객체로 정의해주어야 한다.

- 약분까지 해야 함 -> gcd(x, y)

 

class Fraction:
    def __init__(self, up, down):
        self.num = up
        self.den = down
    
    def __str__(self):
        return str(self.num) + '/' + str(self.den)
    
    def __add__(self, other):
        new num = self.num * other.den + self.den * other.num
        new_den = self.den * other.den
        common = self.gcd(new_num, new_den)
        return Fraction(new_num//common, new_den//common
        
    def multiply(self, other):
        new num = self.num * other.num
        new_den = self.den * other.den
        common = self.gcd(new_num, new_den)
        return Fraction(new_num//common, new_den//common)
        
    def gcd(self, a, b):
        while a % b != 0:
            a, b = b, a % b
        return b

def __init__(self, up, down)은 Fraction 클래스를 호출했을 때 두번째 매개변수 up을 self.num에, 세번째 매개변수 down을 self.den에 대입하는 메서드이다. 이때 self.num은 분자, self.den은 분모이다.

 

def __str__(self)는 print(Fraction(up, down)을 실행했을 때 호출되는 메서드이다. 분수형태로 출력해준다.

 

def __add__(self, other)는 덧셈 메서드이다. + 로 두 변수를 연결했을 때 자동으로 호출된다.

분자는 self의 분자 x other의 분모 + self의 분모 x other의 분자이고,

분모는 self의 분모 x other의 분모이다.

common은 덧셈 결과의 분자와 분모의 최대공약수로, 이후에 나올 gcd 메서드를 통해 구할 수 있다.

최종적으로 덧셈 결과의 분자와 분모를 최대공약수로 약분해서 결과를 도출한다.

 

def multiply(self, other)는 곱셈 메서드이다.

분자는 self의 분자와 other의 분자를 곱한 값이고,

분모는 self의 분모와 other의 분모를 곱한 값이다.

마찬가지로 gcd 메서드로 최대공약수를 구한 후 곱셈 결과를 약분해서 도출한다.

 

def gcd(self, a, b)는 분자와 분모의 최대공약수를 구하는 메서드이다.

gcd(a, b) = gcd(b, a%b) 공식을 이용하였다.

 

num1 = Fraction(1, 4)
num2 = Fraction(1, 2)
num3 = num1 + num2
print(num1, '+', num2, '=', num3)

num1 = Fraction(3, 4)
num2 = Fraction(2, 9)
num3 = num1.multiply(num2)
print(num1, '*' num2, '=', num3

 

9. Performance Analysis

- 이상적 기준 → 추상적

    - 고객의 요구사항을 만족하는지?

    - 잘 작동하는지?

    - 효율적으로 구현했는지?

- 현실적 기준 → 객관적 수치 도출

    - 공간복잡도: 실행할 때 메모리 공간을 얼마나 사용하는지

    - 시간복잡도: 연산 시간이 얼마나 소요되는지

 

10. 공간복잡도 Space Complexity

- Fixed space requirements(Sc) : 명령어, 단순 변수, 고정크기의 구조체 변수, 상수 등으로 컴파일 전에 알 수 있음

- Variable space requirements(Sv): 배열 함수 전달, 재귀호출 등으로 실행 중에 결정됨. Sv를 구해야 함

- S = Sc + Sv

 

def abc(a, b, c):
    return a + b * c  + (a + b - c) / (a + b) + 4.00

- input: 3개의 단순 변수

- output: 1개의 단순 변수

- 배열 전달, 재귀 X → 가변 요구공간 = 0

- 고정 요구공간은 있지만 관심있는 부분이 아님

 

def iSum(num):
    total = 0
    for item in num:
        total = total + num
    return total

- input: 배열(num)

- output: 단순 변수

- 공간복잡도는 배열 함수 전달 방법에 달려있음 (copy or 주소 전달)

 

- call by value 

    - 배열 요소들은 함수로 '복사'되어짐

    - 배열 크기에 비례하여 추가적인 메모리 공간이 요구됨

    - Sv = n

    - ex) Pascal

 

- call by reference 

    - 배열의 시작 주소만 함수로 전달됨

    - 추가적인 메모리 공간 요구되지 않음 

    - Sv = 0

    - ex) C, Python

 

- 재귀호출

def rsum(sum):
    if len(num):
        return rsum(num[:-1]) + num[-1]
    else:
        return 0
print(rsum([1, 2, 3, 4, 5])

- 함수가 호출될 때마다 현재 실행중인 문맥 모두 저장되어야 함

    - variables, return address, n times funcion calls (rsum(n-1), ..., rsum(0))

    - space complexity = n * (size(num) + return address)

 

11. 시간복잡도 Time complexity

- 알고리즘이 수행되는데 걸리는 시간

- T = compile time(Tc) + excution time(Te)

- 실행시간(Te)가 시간복잡도를 구할 때 사용되며, 실행 환경에 영향을 받음

→ 명령어 개수로 시간 측정, 명령어 별로 실행 시간 다른 것은 무시함

 

- Step count table

    - steps: 한 라인에 명령어가 몇 개인지 (함수 헤더, 변수 선언은 무시함)

    - frequency: 명령어가 몇 번 실행되는지 (for, while loops)

    - total steps = steps * frequency per line

 

12. Big-O Notation

- n이 매우 큰 경우 시간복잡도 함수를 점근적으로 근사한 것

- n이 증가할 경우 알고리즘을 실행하는데 소요되는 시간

- 알고리즘 성능 평가를 위한 표준

 

- T(n) = n² + 2n → O(n²)

 

- f(n) ≤ c * g(n) for all n ≥ n0 를 만족하는 정수 n0와 c가 존재하면 Big-O notation 사용 가능

- c * g(n)은 f(n)의 상한선 → c * g(n)보다는 시간이 적게 걸림

 

- ex) f(n) = 10n + 10,000 ∈ O(n)

    - f(n) ≤ 20n (=c) for all n ≥ 1000 (=n0)

 

13. Big-Omega Notation

- f(n) ≥ c * g(n) for all n ≥ n0 를 만족하는 정수 n0와 c가 존재하면 Big-Omega notation 사용 가능

- c * g(n)은 f(n)의 하한선

 

- ex) f(n) = 3n + 2 ∈ Ω(n)

    - f(n) ≥ 3n for n ≥ 1

 

14. Big-Theta Notation

- f(n) ∈ Ω(n) 이고 f(n) ∈ O(n)을 만족하는 c1, c2, n0가 존재하면 f(n) ∈ θ(g(n()) 존재

- c1 * g(n)  f(n)  c2 * g(n) for all n ≥ n0

 

- ex) f(n) = 3n + 2 ∈ θ(n)

    - 3n ≤ f(n) ≤ 4n for all n ≥ 2

 

15. Time complexity class

'Software > Data Structures' 카테고리의 다른 글

[Python] 2장 연습문제  (0) 2022.04.16
[Python] 2. Python Data Type  (0) 2022.04.16
[자료구조] 탐색  (0) 2021.04.20
[자료구조] 연결 리스트  (0) 2021.04.20
[자료구조] 선형 자료구조  (0) 2021.04.18

[출처] 모각코 'JAVA를 자바'

 

1. 스캐너 (Scanner)

 

자바에서 사용자에게 값을 입력받을 때에는 주로 '스캐너'를 사용한다.

 

스캐너를 이용하기 위해서 클래스 가장 상단에 

import java.util.Scanner;

코드를 추가해야 한다.

 

2. 스캐너 객체

 

스캐너를 이용하기 위해서는 스캐너 객체를 만들어야 한다.

스캐너 클래스의 기능을 쓸 수 있는 모듈을 복사한다는 뜻이다.

 

Scanner sc = new Scanner(System.in);

이 코드는 스캐너 클래스의 기능을 사용할 수 있는 sc 라는 이름의 객체(모듈)을 만든다는 의미이다.

 

한 번 스캐너 객체를 만들면 이 객체의 메소드를 이용해 사용자가 원하는 데이터를 읽을 수 있다.

 

String age = sc.next();
System.out.println("나이를 입력하세요: " + age);

이 코드는 스캐너 sc가 스캔한 문자열을 age라는 변수에 저장하고 이를 출력한 코드이다.

 

스캐너는 한 번 만들면 여러번 스캔할 수 있다.

 

3. 스캐너 닫기

 

스캐너를 만든 후 마지막에 닫지 않으면 경고가 뜬다.

 

sc.close();

따라서 항상 마지막에 이 코드를 적어 스캐너를 닫아야 한다.

 

4. 스캐너의 메소드 next

 

스캐너는 next 외에도 다양한 메소드를 제공한다.

 

next가 들어간 메소드를 검색해보면 next + 자료형으로 구성되어있는걸 알 수 있다.

 

nextInt()는 int 데이터를 입력받고, nextFloat()는 float 데이터를 입력받는다.

next는 공백이 생기기 전까지 입력받은 문자열을 읽고 (한 단어),

nextLine은 줄바꿈 전까지 쓴 문자열을 모두 읽는다.

'Software > JAVA' 카테고리의 다른 글

[JAVA] 객체지향  (0) 2021.07.22
[JAVA] 배열  (0) 2021.07.20
[JAVA] 객체, 생성자, 계산기 예제  (0) 2021.01.11
[JAVA] 3의 배수의 합 구하기  (0) 2021.01.11
[JAVA] 클래스와 객체  (0) 2021.01.10

+ Recent posts