[원격 강의] Java 실무 기초(3), 쉽게 배우는 알고리즘(5)

우정·2022년 11월 15일
0

[내일배움캠프] TIL

목록 보기
7/50

Java 실무 기초

객체지향언어

  1. 접근제어자
  • 멤버변수/함수, 클래스 앞에 붙어서 사용되고 외부에서의 접근을 제한하는 역할을 함
  • 클래스 내부에 선언된 데이터의 부적절한 사용으로부터 보호해줌 ⇒ 캡슐화(encapsulation)
  • 캡슐화가 가능할 수 있도록 돕는 도구
  • 종류
    • private : 같은 클래스 내에서만 접근이 가능함
    • default(nothing) : 같은 패키지 내에서만 접근이 가능함
    • protected : 같은 패키지 내, 다른 패키지의 자식클래스에서 접근이 가능함
    • public : 접근 제한이 전혀 없음
  • 코드
    • Main.java
      import pkg.ModifierTest;  // 다른 패키지에 있는 클래스를 참조할 때는 import 구문이 항상 따라옴
      							// java system은 패키지 이름까지 포함한 클래스 이름을 진짜 클래스 이름으로 인식을 함
        
      class Child extends ModifierTest{
          void callParentProtected() {
              System.out.println("call my parent's protected method");
              super.messageProtected();  // 내가 상속받은 부모 클래스를 가리키는 키워드
          }
      }
       
      public class Main {
          public static void main(String[] args) {
              ModifierTest modifierTest = new ModifierTest();
              modifierTest.messageOutside();
          }  // ModifierTest.java 보면 messageOutside 에서 messageInside(); 이렇게 호출해줬기 때문에 결과가 둘 다 출력됨
      }
      public class Main {
          public static void main(String[] args) {
              ModifierTest modifierTest = new ModifierTest();
              modifierTest.messageOutside();
      //        modifierTest.messageInside();
      //        modifierTest.messageProtected();
      //        에러. 둘은 pkg.ModifierTest에서 private, protected 엑서스를 가짐
      
              Child child = new Child();  // 위에 선언한 child 클래스의 인스턴스를 만들어 줌
              child.callParentProtected();
          }
      }
      Scanner scanner = new Scanner(System.in);
              // multiple choices라고 Alt+Enter를 누르면 Scanner라는 이름이 많이 나옴.
              // 괄호 옆을 보면 패키지 각각의 이름이 있음
              // 똑같은 이름의 클래스가 여러 개 있을 수 있는데, import할 때 정확하게 어떤 패키지에 있는 클래스인지 확인하고 선택해야 함.
    • ModifierTest .java
      package pkg;
       
      public class ModifierTest {
       
          private void messageInside() {
              System.out.println("This is private modifier");
          }
        
          public void messageOutside() {
              System.out.println("This is public modifier");
              messageInside();
          }
        
          protected void messageProtected() {
              System.out.println("This is protected modifier");
          }
      }
      • 패키지 private
        • 아무 것도 선언 안하면 패키지 private이라고 함.
        • Main.java에 있는 callParentProtected라는 메소드가 앞에 아무것도 안 붙었기 때문에 패키지 private임
        • Main class와 Child class는 같은 패키지 안에 , 최상위 아무것도 없는 자바 밑에 있는 것이기 때문에 호출이 됨
        • 만약, ModifierTest에 void messagePackagePrivate() { System.out.println(”This is package private modifier”)라고 해도 호출할 수 없음
  1. 추상클래스
  • 추상메소드를 선언할 수 있는 클래스
  • 클래스와는 다르게 상속받는 자식클래스 없이 그 자체로 인스턴스를 생성할 수 없음(Animal이 추상클래스라면 new Animal은 할 수 없고 new Dog만 할 수 있음)
  • 추상메소드
    • 설계만 되어있고 구현체가 없는 것(메소드의 시그니처는 선언하지만 중괄호 안에 있는 블럭 구현체는 없고 자식클래스에서 모두 구현해야 된다는 것을 의미)
  • 특징
    • 일반 클래스랑 똑같은데 객체를 그 자체로 생성할 순 없다
    • 클래스 상속과 마찬가지로 extend 키워드를 쓰고, 그래서 다중상속이 불가능함
    • 추상 method에 대해서만 자식클래스에서 무조건 구현해야함
  • 코드
    abstract class Bird {  // 1. 추상클래스
        private int x,y,z;  // 2. 생성자 없으면 처음에 000으로 세팅이 됨
        void fly(int x, int y, int z) {  // 3.
            printLocation();  // 5.
            System.out.println("이동합니다");
            this.x = x;
            this.y = y;
            if(flyable(z)){
                this.z = z;
            } else {
                System.out.println("그 높이로는 날 수 없습니다.");
            }
            this.z = z;  // 6. x,y,z 해 준대로 이동
            printLocation();  // 7. 다시 위치를 찍어봄
        }
      
        abstract boolean flyable(int z);  // {} 쓸 수 없음
        public void printLocation() {  // 4.
            System.out.println("현재 위치 {" + x + "," + y + "," + z + ")");
        }
    }
    // Bird를 상속받은 새 구현체 만들어주기
    class Pigeon extends Bird {  // alt+enter 눌러서 메서드 구현 클릭
     
        @Override
        boolean flyable(int z) {
            return z < 10000;
        }
    }
      
    class Peacock extends Bird {
     
        @Override
        boolean flyable(int z) {
            return false;
        }
    }
      
    public class Main {
        public static void main(String[] args) {
    //        Bird bird = new Bird();  // 인스턴스 생성할 수 없음
            Bird pigeon = new Pigeon();
            Bird peacock = new Peacock();
            System.out.println("--- 비둘기 ---");
            pigeon.fly(1, 1, 3);
            System.out.println("--- 공작새 ---");
            peacock.fly(1, 1, 3);
            System.out.println("--- 비둘기 ---");
            pigeon.fly(3, 3, 30000);
        }
    }
  1. 인터페이스
  • 객체의 특정 행동의 특징을 정의함
  • 함수의 특징인 method, 시그니처, 접근제어자, return type method 이름만 정의하고 함수의 내용은 없음
  • 인터페이스를 구현하는 클래스는 인터페이스에 존재하는 상세 내용을 반드시 구현해야함
  • 특징
    • 구현하는 객체의 동작에 명세
    • 다중상속이 가능함
    • implements 라는 키워드를 이용해서 구현함
    • method 시그니처만 선언이 가능함
  • 형식
    interface MyInterface {
        void myMethod();
  • 코드
    interface Flyable {  // 멤버를 가지지 못하고 동작만, method만 정의함
        void fly(int x, int y, int z);
    }
    class Pigeon implements Flyable {  // 실제 구현한 것(implements), 상속과는 다르게 여러 개의 인터페이스를 구현할 수 있음
        private int x,y,z;
        @Override  // 바디
        public void fly(int x, int y, int z) {
            printLocation();
            System.out.println("날아갑니다.");
            this.x = x;
            this.y = y;
            this.z = z;
            printLocation();
        }
        public void printLocation() {
            System.out.println("현재위치 (" + x + "," + y + "," + z + ")");
        }
    }
      
    public class Main {
        public static void main(String[] args) {
        Flyable pigeon = new Pigeon();
        pigeon.fly(1, 2, 3);
        }
    }
  • 퀴즈
    • 조건
      • 코드
        • Human.java
          public class Human { // 1.
              String name;
              int age;
              int speed;
              int x,y;
            
              // 2. 초기화할 수 있는 constructor 만들기(Alt+Insert)
              public Human(String name, int age, int speed, int x, int y) {
                  this.name = name;
                  this.age = age;
                  this.speed = speed;
                  this.x = x;
                  this.y = y;
              }
              // 3. 모든 사람의 처음 위치는 (0,0), int는 초기값이 (0,0)
            
              public Human(String name, int age, int speed) {
                  this(name, age, speed, 0, 0);
              }
              // 4. 위치 정보를 출력할 수 있는 getLocation 함수 만들기
              public String getLocation() {
                  return "(" + x + "," + y + ")";  // 위치 정보 return하게 해줌
              }
              // 5. 내가 누구인지 알아야 함
              protected void printWhoAmI() {
                  System.out.println("My name is " + name + ", " + age + " aged.");
              }
          }
          // 6. 자식과 부모님은 뛸 수 있다. 자식만 수영할 수 있다.  >> 부모클래스, 자식클래스에서 만들지 않고 인터페이스로 만들거임
          // 인터페이스 Walkable, Runable, Swimmable
          // 7. 이것들을 이용해서 조부모, 부모, 자식 클래스 만들기
        • Walkable.java(인터페이스)
          public interface Walkable {
              void walk(int x, int y);  // 7. 인터페이스라 구현체는 없음
          }
        • Runable.java(인터페이스)
          public interface Runable {
              void run(int x, int y);
          }
        • Swimmable.java(인터페이스)
          public interface Swimmable {
              void swim(int x, int y);
          }
        • GrandParent.java
          public class GrandParent extends Human implements Walkable { // 1. 인간이니까 휴먼을 상속받음 // 3. 걸을 수 있으니까 Walkable이란 인터페이스 구현
              public GrandParent(String name, int age) {  // 2. 기본 위치는 0이니까 x,y는 안가져옴, 기본속도는 1이라 파라미터 받을 필요 없음
                  super(name, age, 1);
              }
           
              @Override  // 4. 함수의 내용 구현해줌(Alt+Enter, 메서드 구현)
              public void walk(int x, int y) {
                  printWhoAmI();  // 5. 내가 누구인지 출력을 해줌
                  System.out.println("walk speed: " + speed);
                  this.x = x;
                  this.y = y;
                  System.out.println("walked to " + getLocation());
              }
          }
        • Parent.java
          public class Parent extends Human implements Walkable, Runable {
              public Parent(String name, int age) {
                  super(name, age, 3);
              }
            
              @Override
              public void run(int x, int y) {
                  printWhoAmI();
                  System.out.println("run speed: " + (speed + 2));
                  this.x = x;
                  this.y = y;
                  System.out.println("ran to " + getLocation());
              }
            
              @Override
              public void walk(int x, int y) {
                  printWhoAmI();
                  System.out.println("walk speed: " + speed);
                  this.x = x;
                  this.y = y;
                  System.out.println("walked to " + getLocation());
              }
          }
        • Child.java
          public class Child extends Human implements Walkable, Runable,  Swimmable {
              public Child(String name, int age) {
                  super(name, age, 5);
              }
            
              @Override
              public void swim(int x, int y) {
                  printWhoAmI();
                  System.out.println("swim speed: " + (speed + 1));
                  this.x = x;
                  this.y = y;
                  System.out.println("swum to " + getLocation());
              }
            
              @Override
              public void run(int x, int y) {
                  printWhoAmI();
                  System.out.println("run speed: " + (speed + 2));
                  this.x = x;
                  this.y = y;
                  System.out.println("ran to " + getLocation());
              }
            
              @Override
              public void walk(int x, int y) {
                  printWhoAmI();
                  System.out.println("walk speed: " + speed);
                  this.x = x;
                  this.y = y;
                  System.out.println("walked to " + getLocation());
              }
          }
        • Main.java
          // 1. Human, 인터페이스, 조부모,부모,자식 클래스 다 만든 후 Main에서 동작하는 것들을 표현함
          public class Main {
              public static void main(String[] args) {
                  Human grandParent = new GrandParent("할아버지", 70);
                  Human parent = new Parent("엄마", 54);
                  Human child = new Child("나", 20);
            
                  // 2. 배열에 3종류 담아보기
                  Human[] humans = {grandParent, parent, child};
                  for (Human human: humans){  // 3. 이 친구가 누구인지 출력해보기
                      System.out.println(human.name + ", 나이: " + human.age + ", 속도: " + human.speed + ", 현재위치: " + human.getLocation());
                  }
                  // 4. 활동하는 코드 만들어보기
                  System.out.println("<활동 시작>");
                  for (Human human: humans) {
                      if (human instanceof  Walkable) {
                          ((Walkable) human).walk(1, 1);  // human.walk 쳤는데 이렇게 바뀜, 여기서는 Human 타입인데 Walkable임이 확인 됐으니까 Walkable이라는 타입으로 캐스팅하겠다. 라는 뜻 // 중괄호로 감싸진 것은 Walkable 의 인스턴스 타입으로 인식되고 있다는 것
                          System.out.println("- - - - - -");
                      }
                      if (human instanceof Runable) {
                          ((Runable) human).run(2, 2);
                          System.out.println("- - - - - -");
                      }
                      if (human instanceof Swimmable) {
                          ((Swimmable) human).swim(3, -1);
                          System.out.println("- - - - - -");
                      }
                  }
              }
          }

Java 18강~20강

  1. 예외, 에러 처리
  • 예외처리(Exception, Error Handing)

    • 다양한 예외 상황이 발생할 시 대응하기 위해 예외 처리 코드가 필요함
  • 목적

    • 예외의 발생으로 실행 중인 프로그램의 비정상 종료를 막기 위해
    • 개발자에게 알려 기존의 코드를 보완할 수 있도록 하기 위해
  • Java에서는 상속을 이용해 모든 예외를 표현함.

  • 모든 예외 클래스는 Throwable의 자식 클래스임

  • Throwable

    • Error
      • 프로그램이 종료되어야 하는 심각한 문제
      • OutOfMemoryError(OOM)
    • Exception
      • 프로그램이 종료되진 않지만 예외나 문제상황을 표현하기 위해 사용
      • RuntimeException
        • 실행 도중 발생하는 Exception을 정의하는 방법
      • IOException
        • 파일을 읽고 쓰거나 네트워크의 데이터를 읽고 쓸 때 발생하는 Exception을 표현할 때 사용
  • try-catch(-finally) 형식

    • 코드
      public class Main {
          public static void main(String[] args) {
              int number = 10;
              int result;
        
              for (int i = 10; i>=0; i--) {  // i가 10부터 0까지 하나씩 줄이면서 반복하는 구문
                  try {
                      result = number / i;
                      System.out.println(result);  // 위의 결과 한 번 출력
                  } catch (Exception e) {  // 만약 Exception이 발생하면
                      System.out.println("Exception 발생: " + e.getMessage());  // 모든 Exception은 getMessage(예외의 이유를 설명하는 글자가 담겨있음)를 가짐
                  } finally {  // 항상 실행되는지 보기 위해 출력
                      System.out.println("항상 실행되는 finally 구문");
                  }
              }
          }
      }
  • try-catch-resource 형식

    • 코드
      import java.io.FileOutputStream;
      import java.io.IOException;
       
      public class Main {
          public static void main(String[] args) {
              try (FileOutputStream out = new FileOutputStream("test.txt")) {  // 괄호 안엔 Closeable 인터페이스를 구현한 클래스만 올 수 잇음, ctrl누르면 확인가능
                  out.write("hello sparta".getBytes());
                  out.flush();
              } catch (IOException e) {
                  System.out.println("IOException 발생: " + e.getMessage());
                  e.printStackTrace();
              }
          }
      }
  • method에서의 예외 선언

  • 퀴즈

    • 주어진 코드
      class ArrayCalculation {
        
          int[] arr = { 0, 1, 2, 3, 4 };
      
          public int divide(int denominatorIndex, int numeratorIndex) {
              return arr[denominatorIndex] / arr[numeratorIndex];
          }
      }
        
      public class Main {
          public static void main(String[] args) {
              ArrayCalculation arrayCalculation = new ArrayCalculation();
        
              System.out.println("2 / 1 = " + arrayCalculation.divide(2, 1));
              System.out.println("1 / 0 = " + arrayCalculation.divide(1, 0)); // java.lang.ArithmeticException: "/ by zero"
              System.out.println("Try to divide using out of index element = "
                                 + arrayCalculation.divide(5, 0)); // java.lang.ArrayIndexOutOfBoundsException: 5
          }
        
      }
    • 코드
      class ArrayCalculation {
        
          int[] arr = { 0, 1, 2, 3, 4 };
       
          public int divide(int denominatorIndex, int numeratorIndex) throws ArithmeticException, ArrayIndexOutOfBoundsException {
              return arr[denominatorIndex] / arr[numeratorIndex];
          }
      }
        
      public class Main {
          public static void main(String[] args) {
              ArrayCalculation arrayCalculation = new ArrayCalculation();
        
              System.out.println("2 / 1 = " + arrayCalculation.divide(2, 1));
              try {
                  System.out.println("1 / 0 = " + arrayCalculation.divide(1, 0)); // java.lang.ArithmeticException: "/ by zero"
              } catch (ArithmeticException arithmeticException) {
                  System.out.println("잘못된 계산입니다. " + arithmeticException.getMessage());
              }
              try {
                  System.out.println("Try to divide using out of index element = "
                          + arrayCalculation.divide(5, 0)); // java.lang.ArrayIndexOutOfBoundsException: 5
              } catch (ArrayIndexOutOfBoundsException arrayIndexOutOfBoundsException) {
                  System.out.println(
                          "잘못된 index 범위로 나누었습니다. 타당한 index 범위는 0부터 " + (arrayCalculation.arr.length - 1) + "까지 입니다.");
              }
          }
      }
  1. 날짜와 시간 다루기
  • 코드

    import java.time.LocalDate;
    import java.time.LocalDateTime;
    import java.time.LocalTime;
      
    public class Main {
        public static void main(String[] args) {
            System.out.println("now usages");  // 현재 시간
            LocalDate date = LocalDate.now();
            LocalTime time = LocalTime.now();
            LocalDateTime dateTime = LocalDateTime.now();
    
            System.out.println(date);
            System.out.println(time);
            System.out.println(dateTime);
    
            System.out.println("of() usage");  // 특정 시간 지정
            LocalDate dateOf = LocalDate.of(2022, 02, 21);
            LocalTime timeOf = LocalTime.of(22, 50, 0);
      
            System.out.println(dateOf);
            System.out.println(timeOf);
        }
    }
  • 날짜와 시간의 형식 바꾸기(format 수정)

    import java.time.LocalTime;
    import java.time.format.DateTimeFormatter;
    import java.time.format.FormatStyle;
      
    public class Main {
        public static void main(String[] args) {
            DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);  // FULL, LONG, MEDIUM, SHORT
            String shortFormat = formatter.format(LocalTime.now());
            System.out.println(shortFormat);
        }
    }
  • 내가 원하는 형식으로 바꾸기

    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
     
    public class Main {
        public static void main(String[] args) {
            DateTimeFormatter myFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
            String myDate = myFormatter.format(LocalDate.now());
            System.out.println(myDate);
        }
  • 날짜와 시간의 차이 계산하기

    import java.time.LocalDate;
    import java.time.Period;
     
    public class Main {
        public static void main(String[] args) {
            LocalDate today = LocalDate.now();
            LocalDate birthday = LocalDate.of(2022, 1, 1);
            Period period = Period.between(today, birthday);  // Period 는 두 날짜 사이의 간격을 나타냄  // Duration는 두 시간 사이의 간격
            System.out.println(period.getMonths());  // 몇 달이 지났는지 출력
            System.out.println(period.getDays());  // 며칠이 지났는지 출력
        }
    }
  • 퀴즈

    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    
    public class Main {
    	public static void main(String[] args) {
            DateTimeFormatter dateTimeFormatter = 	DateTimeFormatter.ofPattern("yyyy/MM/dd h/mm");
            String now = 	dateTimeFormatter.format(LocalDateTime.now());
    
        	System.out.println("현재시간: " + now);
    	}
    }

알고리즘

  1. DFS(Depth First Search)
  • 탐색의 순서를 깊이 우선으로 함
  • 그래프의 최대 깊이 만큼의 공간을 요구해 공간을 적게 씀
  • 최단 경로를 탐색하기 쉽지 않음
  • 구현해보기
    • 방법 - 재귀함수 1) 루트 노드부터 시작한다.
      2) 현재 방문한 노드를 visited 에 추가한다.
      3) 현재 방문한 노드와 인접한 노드 중 방문하지 않은 노드에 방문한다.
      4) 2부터 반복한다. ⇒ 무한정 깊어지면 에러가 생길 수 있음
    • 또 다른 방법 - 스택 1) 루트 노드를 스택에 넣습니다.
      2) 현재 스택의 노드를 빼서 visited 에 추가한다.
      3) 현재 방문한 노드와 인접한 노드 중 방문하지 않은 노드를 스택에 추가한다.
      4) 2부터 반복한다.
      5) 스택이 비면 탐색을 종료한다.
  1. BFS(Breadth First Search)
  • 탐색의 순서를 너비 우선으로 함
  • 최단 경로 쉽게 찾을 수 있음
  • 공간을 많이 써야하고, 시간도 더 오래 걸릴 수 있음
  • 구현해보기
    • 방법 - 큐 1) 루트 노드를 큐에 넣습니다.
      2) 현재 큐의 노드를 빼서 visited 에 추가한다.
      3) 현재 방문한 노드와 인접한 노드 중 방문하지 않은 노드를 큐에 추가한다.
      4) 2부터 반복한다.
      5) 큐가 비면 탐색을 종료한다.
  1. Dynamic Programming(DP, 동적 계획법)

0개의 댓글

관련 채용 정보