⚙️ Backend/JAVA

JAVA - 예외처리, API, 인터페이스, 오브젝트 클래스,

코너(Corner) 2021. 1. 25.
반응형

실습1-1

인터페이스 : Cafe.java (아직 구현되지 않은 3가지 기능)

클래스 : - Starbucks.java (본사), Road.java(main 메소드)

스타벅스 매장은 한 개가 아니라 여러 개이다.

각 매장은 신규 오픈 시 본사에 정보를 등록해야 한다.

등록해야 할 정보는 아래와 같다.

  1. 메뉴
  2. 가격
  3. 판매방식

본사에서는 신규 오픈 한 매장에서 전달한 3가지 정보를

직접 사용하는 등록 메소드를 구현해 놓는다.

신규 오픈한 매장은 등록 메소드 실행 시 3가지 정보를 구현하게 되고

콘솔창에 구현한 정보를 확인할 수 있다.

실습1-2

  1. 강남 매장은 메뉴별 가격이 존재한다.
  2. 잠실 매장은 무료 나눔 매장이다.(판매방식이 필요없음)

Cafe 인터페이스

package day04;

/*
 사용자가 어떤 기능을 구현할 지 알 수 없으므로
 반드시 구현해야 하는 틀만 선언하여 제공해준다.
 */
public interface Cafe {
    //메뉴
    String[] getMenu();
    //가격
    int[] getPrice();
    //판매방식
    void sell(String menu) throws Exception;
}

Road 클래스 (메인)

package day04;

public class Road {
    public static void main(String[] args) {
        Starbucks gangnam = new Starbucks();

        gangnam.register(new Cafe() {

            @Override
            public void sell(String menu) throws Exception{
                String[] arMenu = getMenu();
                boolean isOk = false;
                for (int i = 0; i < arMenu.length; i++) {
                    if(arMenu[i].equals(menu)) {
                        isOk = true;
                    }
                }

                if(!isOk) {throw new Exception();}

            }

            @Override
            public int[] getPrice() {
                int[] arPrice = {3000, 4000, 3500};
                return arPrice;
            }

            @Override
            public String[] getMenu() {
                String[] arMenu = {"아메리카노", "카페라떼", "콜라"};
                return arMenu;
            }
        });
        System.out.println("-----------잠실점-------");
        Starbucks jamsil = new Starbucks();
        jamsil.register(new CafeAdapter() {

            @Override
            public String[] getMenu() {
                String[] arMenu = {"아메리카노", "카페라떼", "콜라"};
                return arMenu;
            }

        });

    }
}

Starbucks 클래스

package day04;

public class Starbucks {
    // 신규매장 메뉴판
    String[] arMenu;
    // 신규 매장의 가격표
    int[] arPrice;


    // 신규 매장 등록하기
    /*
     Cafe는 인터페이스이기 때문에 외부에서 값을 전달받으려면
     모든 추상메소드가 구현이 되어야 한다.
     이를 이용하여, 신규 매장이라면 반드시 Cafe에 선언된 기능들을 구현해야 한다.
     외부에서 기능이 모두 구현된 필드의 주소값이 c 객체로 전달되므로, 해당 필드에 접근하여
     구현된 메소드를 사용해준다.
     */
    public void register(Cafe c) {
        arMenu = c.getMenu();
        arPrice = c.getPrice();

        // 만약 가격부분을 구현하지 않은 매장이라면 무료나눔매장
        if(arPrice == null ) {
            System.out.println("무료 나눔 확인 완료");
            return;
        }

        System.out.println("======확인중..======");
        for (int i = 0; i < arMenu.length; i++) {
            System.out.println(arMenu[i] + " : " + arPrice[i] + "원");
        }
        System.out.println("메뉴/가격 이상 없음");

        try {
//            c.sell(arMenu[new Random().nextInt(arMenu.length)]);
            c.sell("빵");
            System.out.println("판매 방식 이상 없음");
        } catch (Exception e) {
            System.out.println("등록 실패. 본사에 문의해주세요.");
            return;
        }
        System.out.println("정상 등록되었습니다.");
    }
}

추상클래스 CafeAdapter.class

package day04;

/*
 카페를 등록할 때 반드시 구현해야하는 메소드가 매장별로 다를 수 있다.
 따라서 무료나눔 카페인 경우 getMenu만 구현해야 하고, 이를 위해
 모든 메소드에 강제성을 없애준다.
 */
public abstract class CafeAdapter implements Cafe {

    @Override
    public String[] getMenu() {
        return null;
    }

    @Override
    public int[] getPrice() {
        return null;
    }

    @Override
    public void sell(String menu) throws Exception {}

}

마커 인터페이스(Marker)

특정 클래스들을 그룹화하기 위하여 사용한다.

인터페이스도 부모이고 타입으로 볼 줄 알아야 한다.


예외처리

에러 : 심각한 오류

예외 : 덜 심각한 오류

예외 발생 시 해당 예외 필드가 메모리에 할당되고,

할당된 필드의 주소 값이 예외가 발생된 곳으로 날아온다.

이를 잡아주는 문법이 try ~ catch문이다.

--문법--

try {
오류가 날수 있는 문장 
} catch (예외이름 객체명) {
객체명.필드명;
오류 발생 시 실행할 문장
}

외부 장치(드라이버)를 직접 연결 했을 대

사용 후 반드시 장치를 닫아주어야 한다.

  1. 이때 finally 문법을 사용한다.
finally { 
외부 장치 닫기
}
  1. 이 때 tret statement 문법을 사용한다.
try(연결 객체) {
} catch() {
}

API(Application Programming Interface)

직역 > 응용프로그램 프로그래밍 인터페이스

==> 프로그램을 제작할 때, 선배 개발자가 이미 구현한 소스코드를

그대로 사용할 수 있도록 제공받는 틀이다.

내부 API (기본제공)

  • java.lang

    • 자바 프로그래밍을 위한 가방 기본적인 패키지와 클래스를 포함
  • java.util

    • 데이터를 효율적으로 저장하기 위한 패키지와 클래스를 포함
  • java.io

    • 키보드, 모니터, 프린터, 파일 등을 제어할 수 있는 패키지와 클래스를 포함
  • java.net

    • 통신을 위한 패키지와 클래스를 포함

외부 API

  • 구글맵, 카카오맵, SMS전송, 결제, 인증, 보안, 등등

어노테이션 주석

범위 주석에서 *이 하나 더 붙는 것이 어노테이션 주석이다.

@ 은 어노테이션이다.

/**  
    @author 개발자
    @param 메소드의 매개변수
    @return 메소드의 반환값
    @see 참고할 만한 링크 저장
    @since 릴리즈 기록(JDK 기준)
    @throws 메소드에서 발생할 수 있는 예외
    @version 클래스 버전(1.0.0)
*/
package api;
/**
 * 
 * @author corner 
 *    @since JDK8
 *    <br>Calculator 
 */
public class Calc {

    /**
     * To div the following numbers.<br>
     * For example<br>
     * <code> div(10,3) : 3 </code>
     * @param num1 : First integer for div
     * @param num2 : Last integer for div
     * @return : int
     * 
     * @see Math
     * @throws ArithmeticException
     * 
     */
    public int div(int num1, int num2) {
        return num1 / num2;
    }

}

클래스 파일 --> export --> javadoc --> 문서화로 만든다.

어노테이션 주석을 코드에 작성을 해도 자동으로 문서화되지 않는다.

따라서 javadoc.exe 프로그램을 통해 배포해야 한다.

배포할 패키지 혹은 클래스 우클릭 > export > java > javadoc > 경로 (jdk경로\bin\javadoc.exe) 설정 > Finish

프로젝트 폴더 > doc > index.html로 확인 가능하다.

[소스코드 배포]

배포할 패키지 우클릭 > Export > Java > Jar > 저장될 경로 설정 > Finish

[API import]

프로젝트 우클릭 > build path > add External JARs > .jar파일 추가 > apply


Object 클래스(최상위 클래스)

  1. equals() : 주소 비교 (==)

    • String 클래스에서는 값 비교로 재정의 한 것이다.
    package obj;
    
    import java.util.Random;
    
    public class ObjectTest {
        public static void main(String[] args) {
            String data1 = "ABC";
            String data2 = "ABC"; 
    
            String data3 = new String("ABC");
            String data4 = new String("ABC");
    
            System.out.println(data1==data2); 
            // data1과 data2는 true가 뜬다면, 값이 우선되어 값이 비교되어 true가 뜬 것이다.
    
            System.out.println("=====어떻게 컨스턴트 훌의 주소를 가져오는가 ? ====");
            System.out.println(data3==data4);
            System.out.println(data3.intern() == data4.intern());
            System.out.println(data1 == data3.intern());
            // data3와 data4가 false가 뜬다면, 값이 아닌 주소를 먼저 비교하기 때문에 false가 뜨는 것이다.
            // String 클래스의 equals는 값을 비교하기 위해 재정의 하였다.
            System.out.println(data3.equals(data4));
    
    
       System.out.println("====================");
       System.out.println(data1.hashCode());
       System.out.println(data2.hashCode());
       System.out.println("====================");
       System.out.println(data3.hashCode());
       System.out.println(data4.hashCode());
       // data1,2,3,4의 hashcode가 필드 주소가 다른데 hashCode가 왜 같냐면
       // String 클래스에서 재정의 하였기 때문에 data1, data2는 해쉬코드가 비교된거지만
       // data3, data4는 그렇지 않다. 즉, new 연산으로 선언된 것과, 바로 "값"이 들어간 포커스에 따라 다르다.
       System.out.println("====================");


       // Object equals는 주소를 비교하기 위한 것이다.
       Random r1 = new Random();
       Random r2 = new Random();
       System.out.println(r1==r2);
       r1 = r2;
       System.out.println(r1.equals(r2));
   }

}




2. hashCode()

   - 메모리에 할당된 필드의 주소값을 리턴한다.

   ```java
   package obj;

   public class Student {
       // alt + shift + a  커서를 축소하여 필드에 동시 입력을 해야할 때
       public int num;
       public String name;
       public Student() {
           // TODO Auto-generated constructor stub
       }
       public Student(int num, String name) {
           this.num = num;
           this.name = name;
       }

       @Override
       public boolean equals(Object obj) {
           if(obj instanceof Student) {
               Student std = (Student) obj;
               if(this.num==std.num) {
                   return true;
               }
           } 
           return false;
       }

       @Override
       public int hashCode() {

           return this.num;
       }

   }
   package obj;

   import java.util.HashSet;
   import java.util.Set;

   public class School {
       public static void main(String[] args) {

           Student 한동석 = new Student(1, "한동석");
   //        System.out.println(한동석.equals(new Student(1,"한동석")));
           // false 가 나오는 것을 true로 바꾸어야 한다.
           // equals와 hashcode를 재정의한다.

           Set<Student> stdSet = new HashSet<>();
           stdSet.add(한동석);
           stdSet.add(new Student(1,"한동석")); 

           System.out.println(stdSet.size());
           // 두개가 같은 객체인데 둘다 들어가므로 해쉬코드도 재정의 해야한다.


       }
   }
  1. toString()

    • 객체명을 출력할 때 항상 toString()이 생략된다.
    • 디폴트로 출력되는 문자열 값을 변경하고 싶을 때에는
      해당 클래스의 필드에서 재정의하여 사용한다.
      클래스의 필드들을 간단하게 확인해보고자 할 때에 많이 사용된다.

 

반응형

댓글