190424_Day13 복습, 예외처리, 오버라이딩, 내부클래스

복습

  • 예외

    • 프로그램 실행 중 발생하는 예기치 않은 사건 => 예외

    • 예외가 발생시 어떤 처리(대응)를 할지 추가코드 작성

    • 예외처리 : 자바언어를 더욱 강하게(robust)만드는 요소

    • 개발자 입장 : 코드량 증가

    • 사용자 입장 : 신뢰성 증가

    void hello() throws Exception
    {
        문장1;
        문장2;
        문장3;
    }
    //예외처리 전가!
    public static void main( String [] args)
    {
        hello();
    }
    • 예외처리 구문1 : try catch문
    void hello()
    {
        try
        {
        문장1;//AException 발생 가능성
        문장2;
        문장3;//BException 발생 가능성
    
        }catch(AException e)
        {
        } catch( )
        {
    
        }
    }
    //마치 if문 같은 느낌
    //e는 식별자이름규칙처럼 그냥 임의로 정해준다.
    //catch문 뒤에 이어서 catch문 작성 가능
    • 예외처리 구문2 : finally블럭

    • 혼자 사용 못하고 try catch랑 같이 사용

      void hello()
      {
        try
        {
            문장1;
            AException발생 가능 문장2;
            문장3;
            BException발생 가능 문장 4;
            문장5;
        }catch(AException e){문장6;}
        catch(BException e){문장 7;}
      }
      
      //예외발생 안함 (정상실행!) : 1;2;3;4;5;
      //AException발생! : 1; 6;
      //BException발생! : 1; 2; 3;
      //BException 발생시 만약 상속관계이고 A가 부모, B가 자식이라면 ... 안열림!
      //미션 문장5를 반드시 실행!
      //=> 이럴때 finally{} 사용한다.
      finally // catch문 뒤에
      {
        문장; // 보장해줄게!
      }
    • 에외종류

    • 체크(Checked) 예외

      public ststic void main(String[] args)
      {
        System.in.read();
      }
      //IOEception에러 발생!
      • 컴파일 에러 발생
      • 명시적으로 발생할 수 있는 예외에 대한 처리를 강요!
      • 반드시 try ~ catch 또는 throws를 사용해야함
    • 언체크(UnChecked) 예외

      public static void main( String[] args)
      {
        String []names = { "길동" , "주원" };
        System.out.println(names[3])
      };
      • 개발자실수 또는 사용자 입력데이터 예외

      • 컴파일시 에러가 발생하지 않는다.

      • 특징은 RuntimeException을 상속받는 예외 (자식)클래스!

      • try ~ catch 또는 throws 사용 가능

      • if문을 통해 처리 가능

      • 예)

      String []names = {"길동", "주원"}; //=> 배열 인덱스 0,1 생성
      System.out.println(names[2]); //=>컴파일 시에는 에러가 발생하지 않고 런타임 시 에러 발생
      • 퀴즈) 아래에서 에러가 발생하는 출력문은 무엇일까요?
      int a;
      void method()
      {
          int b;
          int c,d = 0;
          System.out.println(a); //O
          System.out.println(b); //X(에러발생), 변수를 초기화 하지 않았음
          System.out.println(c); //X, 변수를 초기화 하지 않았음
          System.out.println(d); //O
      
          int d,e;
          if(조건식) {d=100;}
          if(조건식) {e=200;}
          else {e = 300}
      
          System.out.println(e); //X, if문 실행 안할수도 있잖아, 초기화 하지 않았음
          System.out.println(f); //O, if문이나 else문 둘 중 하나는 반드시 값에 들어오기 때문에!  
      
          inf g;
      
          try
          {
              f=400;
          }catch(예외클래스명 변수명) {}
      
          System.out.println(names[2]); //X, 컴파일러 입장에서는 try도 if나 마찬가지임, 초기값 없어서 에러
      
      }
      package j0424;
      
      public class UncheckedExceptionTest 
      {
      public static void main(String[] args)
      //예외발생에 대해서 try~catch문 또는 throws를 사용하지 않고 처리하는 방법
      //=>> RuntimeException의 자식 Exception의 경우에만 가능
      {
          String names[] = { "길동", "주원" };
      
          int idx = 1;
          if (idx >= names.length)
          {
              System.out.println("인덱스를 확인하세요");
              return;
          }
      
          System.out.println(names[idx]);
      }
      }
      
      package j0424;
      
      public class UncheckedExceptionTest2
      {
      /*
       * String[] args = {"10", "4"};
       * 
       * su1 su2
       * =======
       * 10   5
       * ab   cd ==> NumberFormatException
       * 10   X ==> ArrayIndexOutofBoundsException
       * 10   0 ==> ArithmeticException
       * 
       */
      
      public static void main(String[] args)
      {
          try
          {
              System.out.println("매개변수로 받은 두개의 수");
              int su1 = Integer.parseInt(args[0]);
              int su2 = Integer.parseInt(args[1]);
              System.out.println("su1 = " + su1 + ", su2 = " + su2 );
              System.out.println("su1의 값을 su2로 나눈 몫" + (su1/su2));
              System.out.println("나눗셈을 잘 실행했니다~!");
          }
              catch (NumberFormatException e) 
          {
              //e : 에러메시지 객체
              e.printStackTrace(); // 문제가 발생한 코드와 연관된 메소드들의 호출 관계를 호출
              System.out.println("-------");
              System.out.println(e.toString()); //e.toString은 자체 프린트 기능은 없다, 예외 종류와 원인을 출력
              System.out.println("-------");
              System.out.println(e.getMessage()); //예외가 발생한 원인만 출력, 
              System.out.println("## 숫자만 입력하세요~!");
              return; // 메소드의 끝괄호 역할
          }catch (ArrayIndexOutOfBoundsException e) 
          {
              System.out.println(" ## 두개의 숫자를 반드시 입력하세요~!! ");
          }catch (ArithmeticException e) 
          {
              System.out.println(" ## 0으로 나눌 수 없습니다~!!");
          }
          //이렇게 안하고?! 이렇게 할 수도 있다!
      
          catch(Exception e)
          {
              System.out.println("모든에외처리" + e );
          }
          finally
          {
              System.out.println("Finally블록 (try 블럭내에서) 예외발생과 상관없이 반드시 실행!");
              //보통 FileSystem객체 또는 DataBase관련된 객체에 대한 반환
              //fr.close();   conn.close();
          }
      
          System.out.println("마지막 문장"); // 굳이 finally 안써도 이렇게 실행이 되네?, 단 리턴등의 값 넣었을때는 안나온다.
          //저런 ArithmeticException 이나 NUmberFormatException 모두 다 Exception에게 상속된것이기에!
          //다만 상황에 따라 다르게 쓰는것, Exception만 쓰면 간결하지만 자세하게 안됨
          //다중catch장점 : 다양한 예외에 대해 각각 알맞은 처리를 할 수 있다
      }//main
      
      }
      
    • < 사용자 정의 예외 >

    • 예외의 발생은 JVM에 의해 실행중 발생할 수도 있지만 사용자 프로그램에서 인위적으로 예외를 발생시킬 수 있다.(throw문을 제공)

    • 형식

      throw 예외객체;
      throw new 예외객체타입(매개변수);
      
      class MyException extends Exception
      {
        public ststic void main(String[] args)
        {
            super(msg);
        }
      }

<오버라이딩(메소드 재정의) 규칙>

class Parent
{
   접근제한자 void hello() throws A,B,C // throws는 책임전가!
   {

   }
}


class Child extends Parent
{
    //오버라이딩 메소드
    //오버라이딩시 주의할 점
    //  1.접근제한자는 부모와 동일한거나 확장해야 한다!
    //  2.throws는 부모와 동일하거나 또는 축소해야 합니다.

   접근제한자 void hello() throws A,B,C 
   {

   }
}
//=================
부모가 public hello(){} // 라면 
자식은 public hello(){} // 자식도 퍼블릭이어야 한다. 퍼블릭 이상은 없으니까!

부모가 protected hello(){} //라면
자식은 protected, public hello(){} //protected 이상이어야 한다.

부모가 hello(){} //라면 자식은 default(생략가능), protected, public
부모가 private 라면 상속 안되니 무효!

부모가 public hello() throws AException, BException, CException {} 이라면

[정상 오버라이딩 throws]
자식 public hello() throws AException, BException, CException {}
자식 public hello() throws AException, BException{}
자식 public hello() throws AException{}
자식 public hello(){}

[에러나는 오버라이딩 throws]
자식 public hello() throws AException, BException, CException, DException {}// 처럼 다 넣어버리면....
자식 public hello() throws Exception{}// 도 마찬가지

<내부클래스(중첩클래스)>

  • 중첩클래스, 포함, Nested

  • 클래스 내에 또 다른 클래스를 구성하는 것.

  • 마치 뻐꾸기 같아,, 남의 집에 터를 잡고 아우터클래스(밖에 있는 클래스)의 메소드를 자기것처럼 써버리는것!

    [public/final/abstract] class A //외부클래스, Outer클래스, Top-level클래스
    {
      //필드
      //생성자
      //메소드
      //1차 자원 정의
    
      [protected, static가능]class B //내부클래스, Inner클래스, [protected, static가능] 외부는 불가
      {
          //2차 자원 정의
      }
    }
  • 보통 이와 같은 경우, 사용자가 내부로 바로 호출하는것이 아니라 외부를 거쳐서 내부를 호출함.

    • 외부 호출할때에는
    A a = new A();
    a.hello();
    • 내부 호출할때에는
    B b = new B();
    b.print();
    package j0424;
    
    
    
    class NestingClass
    {
        int i = 11;
    
        void hello()
        {
            System.out.println( "하이" );
            //외부클래스에서 내부클래스 자원 사용
    //      print();// 바로 에러남!, 내부클래스 직접접근 불가!
            NestedClass Nested = new NestedClass();
            Nested.print();
        }
    
    
        //===============
        class NestedClass //내부(inner) 클래스
        {
            int j = 22;
            void print()
            {
                System.out.println( "프린트~" );
            }
    
            //내부클래스에서 외부클래스 자원 사용!
            void callTest()
            {
                hello();
                System.out.println("i = " + i);
            }
        } //Nested
    }
    
    public class NestedCalssTest
    {   
        public static void main(String[] args)
        {
            //외부클래스에 정의되어있는것 int i , hello(), 내부클래스
            //내부클래스에 정의되어있는것 int j, print()
    
            //외부 클래스의 메소드 호출
            NestingClass nesting = new NestingClass();
            nesting.hello(); // 하이, 프린트~ 같이 출력됨
            System.out.println("=====================");
    
            //내부클래스의 메소드를 main()에서 직접호출 ~! 체크체크~!★
            //=>> 객체생성 : 외부클래스명.내부클래스명 참조변수명 = new 외생성자().new 내부생성자();
            NestingClass.NestedClass nested = new NestingClass().new NestedClass();
            nested.print();
        }
    
    }

인터페이스

  • TUI ( Text User Interface )

    • 프로그램 실행을 Text에 의존해서 실행.
    • ex) 메뉴에서 1을 누르면 추가, 2를 누르면 검색, 3을 누르면 종료
  • AWT( Abstract Window Toolkit )

    • GUI( Graphic User Interface ) 환경을 구축하기 위한 class들의 묶음

    • GUI와 관련된 class들의 묶음. java.awt.*;

      1. Component : Menu, Button, Label, Choice, Checkbox, List, TextField, TextArea, Scrollbar… (전부 앞문자 대문자?! 클래스네!)

      2. Container : Component의 객체를 생성한 후에 그 객체를 배치한다. (여기서는 도화지 판 정도로 생각!, 다른곳에서는 서버 관련 단어로 쓰인다.)

      Object

    ​ |

    ​ Component

    ​ |

    ​ Container

    | |

    Panel Window

    | |

    Applet Frame

    | |

    FlowLayout BorderLayout (Default)

    Panel : display(x) , 한 영역에 두개 이상의 컴포넌트를 붙일때 사용.
    컴포넌트 속성을 지정하기위해 사용.
    Frame : display(o)

    1. Event 처리: Component에 기능을 실제로 부여하는 것.

      • Container의 배치방법(LayoutManager)
        —-> 컴포넌트를 컨테이너에 어떻게 위치시킬지 방법을 정의.
      FlowLayout(가운데 정렬)
    가운데를 기준으로 해서 Component들이 배치.
    (Frame크기에 따라 배치가 변경)
      BorderLayout(방위정렬)
    방위에 따라 사용자가 임의 배치 가능 (동,서,남,북, 중앙)
    상대적으로 큰 영역데 강조할 컴포넌트를 배치.
      GridLayout(같은 크기 정렬, 행열표현 정렬)
    Container의 크기를 같은 크기로 나누어 Component를 붙인다.
      CardLayout(같은 위치 정렬)

    같은 위치에 여러개의 Component를 배치할 때 사용.

    package j0424;
    
    import java.awt.BorderLayout;
    import java.awt.Button;
    import java.awt.Frame;
    
    //BorderLayout : "Center"(주된 데이터, 컴포넌트를 표현)를 기준으로 동서남북 위치를 설정하는것.
    public class BorderTest extends Frame//필요한 객체 ( 컴포넌트, 컨테이너 ) 선언
    {
    Button b1, b2, b3, b4, b5;
    
    public BorderTest(String title)
    {
        //상위클래스 생성자 호출
        super(title); //유의할 점 super는 항상 맨 윗라인에!
        setTitle(" 새로운 타이틀 "); // 위처럼 상위 클래스 생성자 안 부르더라도 괜찮아! setTitle사용하면 위치도, 횟수도 상관이 없어!
    
        //멤머 객체 생성
        b1 = new Button("1");
        b2 = new Button("2");
        b3 = new Button("3");
        b4 = new Button("4");
        b5 = new Button("5");
    
        //속성설정 ( 프레임에 대한 레이아웃, 붙이기 )
    //        this.setLayout( new BorderLayout() );
        setLayout(new BorderLayout());
    
    //        this.add(b1);
        //BorderLayout (방위정렬)의 경우 컴포넌트를 붙일 위치( 동서남북 중앙 ) 를 함께 설정.
        //주의 ) 위치 문자열을 표현 할 때 첫글자 대문자 사용, 철자가 틀리면 에러!
        add("North", b1); //this생략 가능
        add("East",b2);
        add("South",b3);
        add("West",b4);
        add("Center",b5);
    
        //마무리 2개 ( 프레임 사이즈, 프레임 보이기 )
        setSize( 300, 300 );
        setVisible(true);
    
    }//생성자
    
    public static void main(String[] args)
    {
        new BorderTest("Border테스트");
    }
    }
    
    //상속은 부모가 갖는 속성을 다 가져오는것인데 생성자는 안따라 옴! 그래서 super사용 14번 line처럼! 상위클래스 생성자 호출
    
    • mission
    package j0424;
    
    import java.awt.Color;
    import java.awt.FlowLayout;
    import java.awt.Frame;
    import java.awt.Label;
    import java.awt.Panel;
    import java.awt.TextArea;
    import java.awt.TextField;
    
    public class TextFieldAreaTest extends Frame
    {
        TextField tf1, tf2;
        TextArea ta;
        Label la;
    
            public TextFieldAreaTest(String title)
            {
                super(title);
                tf1 = new TextField("기본값", 10); //상단
    //          new TextField(int columns); // columns 는 열이지만 여기서는 글자수가 들어가는 너비
    //          tf2 = new TextField(10); 
                tf2 = new TextField("하이.txt", 10);//하단
    
                ta = new TextArea();
                la = new Label ("파일 이름 : ");
    
                Panel northP,southP; //1. 작은 도화지, 언제사용? 한 영역에 두개 이상의 컴포넌트를 붙일 때
                         //2. 컴포넌트 속성을 지정하기 위해 사용
    
    
                northP = new Panel();
    
    //          northP.setLayout(new FlowLayout()); //한번 안쓰고 작업 해봄 밑에, Panel의 기본 레이아웃이 FlowLayout이기에 생략 가능
                northP.add(tf1);
                Color c1 = new Color(90,225,90); //매개변수의 각 정수는 0~255의 값
                northP.setBackground(c1);
                northP.setBackground(Color.pink);
                northP.setForeground(new Color(240,90,90));
    
    
    
                southP = new Panel(); //컨테이너
                southP.setLayout(new FlowLayout());
                southP.add(la);
                southP.add(tf2);
                southP.setBackground(new Color(240,90,90));
                southP.setForeground(Color.pink);
    
    //          setLayout(new BorderLayout()); //Frame의 기본 레이아웃 : BorderLayout이기에 생략 가능
                //BorderLayout의 경우, '위치설정;을 함께
    
    
                add("North", northP);
                add("Center", ta);
    //          add("South", tf2);
    //          add("South", la);
                add("South", southP);
    
                setSize(300,300);
                setVisible(true);
            }
    
    
        public static void main(String[] args)
        {
            new TextFieldAreaTest("TextFieldArea테스트");
        }//main
    
    }
    
궁금상자
    - 레이아웃에서 NorthSouth가 윈단 다 먹는데 좌우가 영역 다 먹으려면 어떻게 해야 할까

+ Recent posts