[원격 강의] Java 실무 기초(5), 객체지향 프로그래밍 특강

우정·2022년 11월 17일
0

[내일배움캠프] TIL

목록 보기
9/50

1) Java 실무 기초

  1. 제네릭스
  • 타입 체크를 해줌 → 안정성이 높아짐
  • 형식
    • public class 클래스명<T> {...}
    • public interface 인터페이스명<T> {...}
  • 자주 사용되는 타입인자 약어
    • <T> == Type
    • <E> == Element
    • <K> == Key
    • <V> == Value
    • <N> == Number
    • <R> == Result
  • 코드
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
      
    public class Main {
        public static void main(String[] args) {
      
            List<String> list = new ArrayList();  // ArrayList의 구현체를 만들어 인터페이스에는 List 타입 변수 list를 만듦, list를 List보다 상위의 인터페이스인 Collection의 변수에 할당해줌
            list.add("string");
            Collection<String> collection = list;
      
            List<Exception> exceptionList = new ArrayList<>();
            Collection<Exception> exceptionCollection = exceptionList;
      
            List<IllegalArgumentException> exceptions = new ArrayList<>();
            exceptionCollection.addAll(exceptions);
    //        exceptionCollection.addAll(list);  // 위에서 선언한 String의 list를 넣어봄 > exception을 상속받은 타입의 콜렉션인데 String 타입을 받는 list를 써서 빨간 줄이 생김
        }
    }
  1. 람다
  • 함수를 쉽고 정확하게 표현하는 것
  • 함수의 명색없이도 함수를 정의하고 실행할 수 있는 함수
  • 장점 : 문법이 간결하고 편리함
  • 단점 : 중복된 코드가 많아질 수 있어 코드가 지저분해짐
  • 코드
    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Stream;
      
    public class Main {
        public static void main(String[] args) {
            List<String> list = new ArrayList<>();
            list.add("korea");
            list.add("japan");
            list.add("france");
            Stream<String> stream = list.stream();
    //        stream.map(str -> str.toUpperCase())  // toUpperCase: 대문자로 바꿔주는 함수를 수행
    //                .forEach(it -> System.out.println(it));  // function이라는 파라미터를 받는다는 것은 람다식을 쓸 수 있다는 말
      
            // 여러 줄 쓰는 경우
            stream.map(str -> {
                System.out.println(str);
                return str.toUpperCase();  // 여러 개를 쓸 경우 {}을 하고 return문을 적어줘야 함
            }).forEach(it -> System.out.println(it));
      
            // 람다식을 표현하는 또 다른 방법
    //         forEach(System.out::println);
        }
    }
  1. 스트림
  • 하나의 데이터의 흐름
  • 특징
    • 데이터 소스(원래 있는 리스트(list.stream();의 list)를 변경하지 않음
  • 어떤 Collection에 대해 .stream 을 하면 만들 수 있음 Stream<String> stream = list.stream();
  • stream. 하고 어떤 메서드를 쓰던지, 원래 있던 데이터에서 하나씩 꺼내 뒤에 있는 연산을 수행해줌(위에 람다 코드에서 소문자 → 대문자 → 소문자 → 대문자로 출력됨을 확인할 수 있음) stream.map(str -> str.toUpperCase()) .forEach(it -> System.out.println(it));
    Stream<String> stream = list.stream();
    stream.map(str -> {
                System.out.println(str);
                return str.toUpperCase();
            }).forEach(System.out::println);  // stream 닫힘. 뒤에 어떤 것도 수행할 수가 없음
      
            System.out.println(list);  // stream 에서 대문자로 바꿔서 출력된 것은 stream 안에서만 존재함
    //        stream.forEach(System.out::println);  // error: stream은 이미 닫혔기 때문
            Stream<String> stream2 = list.stream();  // 새로운 stream 만들고 싶을 때, list는 변하지 않았으니까 새로운 스트림을 만들어 주면 됨
    • 예제 1 (기본구조)
      import java.util.ArrayList;
      import java.util.List;
      import java.util.Set;
      import java.util.stream.Collectors;
      
      public class Main {
          public static void main(String[] args) {
              List<String> list = new ArrayList<>();
              list.add("서울");
              list.add("부산");
              list.add("대구");
              list.add("서울");
      
              System.out.println(list);
      
              List<String> result = list.stream()  // 스트림 생성
                      .limit(2)  // 두 개만 출력  // 중간 연산
                      .collect(Collectors.toList());  // 스트림 처리된 것을 하나로 모을 때 다른 리스트로 만들어서 모을 거야  // 최종 연산
              System.out.println(result);  // 스트림은 stream을 만들면(list.stream()) transformation을 하고(limit()) 결과물을 만드는(collect(Collectors.toList());) 구조를 갖게 됨
      
              System.out.println("list -> transformation -> set");  // list를 set으로 변형하기
              Set<String> set = list.stream()
                      .filter("서울"::equals)
                      .collect(Collectors.toSet());  // list에 있는 데이터를 하나씩 꺼내서 서울이랑 글자가 같은지 확인하고 같은 거 남길 거야. 그리고 이것을 set의 자료구조로 바꿔서 모아줄 거야
              System.out.println(set);  // 중복 허용 안함
          }
      }
    • 예제 2 ( Array → Stream )
      import java.util.Arrays;
      import java.util.stream.Stream;
      
      public class Main {
          public static void main(String[] args) {
              String[] arr = {"SQL", "Java", "python"};  // String 배열 선언
              Stream<String> stringStream = Arrays.stream(arr);  // String 형태의 Stream 만들기, arr는 스트림이 됨.
              stringStream.forEach(System.out::println);  // 하나씩 개행해서 출력됨
          }
      }
    • 예제 3 (map연산 활용)
      import org.apache.commons.lang3.tuple.Pair;
      
      import java.util.Arrays;
      import java.util.List;
      
      class Sale {
          String fruitName;
          int price;
          float discount;  // 소숫점 표현
      
          public Sale(String fruitName, int price, float discount) {
              this.fruitName = fruitName;
              this.price = price;
              this.discount = discount;
          }
      }
      
      public class Main {
          public static void main(String[] args) {
              List<Sale> sales = Arrays.asList(  // List 만들기
                      new Sale("Apple", 5000, 0.05f),
                      new Sale("Orange", 4000, 0.2f),
                      new Sale("Grape", 2000, 0)
              );
              // 스트림으로 어떤 과일이 실제로 얼마인지 실구매가를 구해서 출력해보자
              sales.stream()
                      .map(sale -> Pair.of(sale.fruitName, sale.price * (1-sale.discount)))
                      .forEach(pair -> System.out.println(pair.getLeft() + " 실구매가: " + pair.getRight() + "원 입니다."));
          }
      }
    • 예제 4 (reduce를 이용한 계산)
      import java.util.Arrays;
      import java.util.List;
      
      public class Main {
          public static void main(String[] args) {
              List<Integer> list = Arrays.asList( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
              System.out.println(list.stream().reduce(0, Integer::sum));  // 0으로 시작해서 stream에서 하나씩 꺼내서 Integer::sum 함수를 실행할 거야
          }
      }
  • 스트림 퀴즈
    • 코드
      //이 씨 성을 가진 사람들의 수 구하기
      import java.util.Arrays;
      import java.util.List;
      
      public class Main {
          public static void main(String[] args) {
              List<String> names = Arrays.asList("김정우", "김호정", "이하늘", "이정희", "박정우", "박지현", "정우석", "이지수");
              System.out.println("이씨성을 가진 친구들: " + names.stream()
                          .filter(name -> name.startsWith("이"))
                          .count());
          }
      }
  1. 네트워킹 - OpenAPI
  • 네트워킹 : 두 대 이상의 컴퓨터를 케이블 또는 인터넷으로 연결하여 네트워크를 구성하는 것
  • 기본 개념
    • 클라이언트(Client) : 서비스를 사용하게 되는 컴퓨터, 요청하는 컴퓨터
    • 서버(Server) : 서비스를 제공하는 컴퓨터, 요청에 응답하는 컴퓨터
    • IP 주소 : 컴퓨터를 구별하는데 사용되는 고유한 값
    • URL : 여러 서버들이 제공하는 자원에 접근할 수 있는 주소를 표현한 것
      • 형식 프로토콜://호스트명:포트번호/경로명/파일명?쿼리스트링#참조
        • 프로토콜 : 통신에 대한 약속
        • 포트번호 : 80(http), 443(https)
    • API
      • 데어터를 주고받는 형식에 대한 약속
      • 응용 프로그램에서 사용할 수 있도록 운영체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 해주는 인터페이스
      • client - server 관점에서는 요청과 응답의 데이터 형식에 대한 약속임
  • Retrofit 라이브러리를 활용해 API 호출하기
    • 코드
      • 서버(RetrofitService - 인터페이스)
        import retrofit2.Call;
        import retrofit2.http.GET;
        import retrofit2.http.Query;
        
        public interface RetrofitService {
            @GET("/api/users/")  // 1. 어노테이션 붙여주고 api의 path 입력
            Call<Object> getUsers(@Query("page") int page);
        }
      • 클라이언트(RetrofitClient)
        //Retrofit 을 이용해 API 요청할 수 있는 기본 준비
        import com.google.gson.Gson;
        import com.google.gson.GsonBuilder;
        import retrofit2.Retrofit;
        import retrofit2.converter.gson.GsonConverterFactory;
          
        public class RetrofitClient {
            private static final String BASE_URL = "https://reqres.in/";
            public static RetrofitService getApi() {
                return getInstance().create(RetrofitService.class);  // api 요청, 제일 마지막에 입력함
            }
            private static Retrofit getInstance() {
                Gson gson = new GsonBuilder().setLenient().create();
                return new Retrofit.Builder().baseUrl(BASE_URL)
                          .addConverterFactory(GsonConverterFactory.create(gson))
                          .build();
            }
        }
      • Main
        import retrofit2.Call;
        import java.io.IOException;
         
        public class Main {
            public static void main(String[] args) {  // 데이터 호출
                Call<Object> result = RetrofitClient.getApi().getUsers(2);  //두 번째 페이지 요청 > 받아주는 데이터는 Call
                try {  // try-catch 문
                    System.out.println(result.execute().body());  // execute 를 해야 실제 요청이 날라감, 받은 데이터를 한번 프린트해서 출력
                } catch (IOException e) {  // IOException 이 발생해서 핸들 해줌, 익셉션 발생 시 익셉션 출력
                    System.out.println(e.getMessage());
                }
            }
        }

2) 객체지향 프로그래밍

  • 소프트웨어의 가치
    : 낮은 비용으로 변화가 가능해야 하고 앞으로의 변화에도 대응할 수 있어야 함

  • 객체지향의 비용 낮추는 방법
    : 캡슐화 + 다형성(+추상화)

  • Argument(아큐먼트) - 인자
    : 함수 호출 시, 전달 되는 값

  • Parameter(파라미터) - 매개 변수
    : 전달 되는 인자를 받아들이는 변수

  • 변수

    • 클래스 변수
      딱 한 번만 생성됨
    • 인스턴스 변수
      매번 새롭게 생성됨
    • 지역 변수
  • 접근 제어자를 사용하는 이유
    : 캡슐화가 가능할 수 있도록 돕기 위해

    • 캡슐화란?
      : 클래스 내부에 선언된 데이터의 부적절한 사용으로부터 보호하기 위해 객체들간의 관계에 따라 접근 권한을 구분하는 것
      • 데이터와 관련 기능을 묶음
      • 객체가 어떤 기능을 하는지 외부에 노출하지 않음(정보 은닉)
      • 객체 내부의 기능이 변경되더라도, 외부에 영향을 주지 않음
  • 다형성(Polymorphism)

    • 한 객체가 다양한 타입을 갖는 것
      - 한 객체가 여러 타입의 기능을 제공
      • 타입 상속으로 다형성 구현
  • 추상화

    • 의미가 비슷한 개념이나 의미 있는 표현으로 정의하는 과정
    • 특정한 성질, 공통 성질을 뽑아내는 과정
  • 타입 추상화

    • 요구사항
3) 느낀 점
  • 배울 것이 너무 많구나.. .시간이 없구나.... 근데 왜 잠은 오는 거지....?
    그래도 Java 강의 듣고 특강 듣고 비슷한 단어들 계속 들으니까 뭔가 알 거 같기도 하고?ㅎ.. 이래놓고 이게 뭐야? 하면 뭔지 모름...
  • 내일은 특강 듣고 듣자마자 복습해보고 Java 개념 봐보고,, 객체 이해해보고ㅜ 코드 쳐보고 해야지,,,~ 퐈이링

0개의 댓글

관련 채용 정보