ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 인터페이스, 내부클래스, 예외
    JAVA 2021. 7. 23. 09:33

    interface 두번째

    인터페이스끼리 상속하는 이유?

    설계도인 인터페이스들을 메서드의 기능을 다 다르게하여 부품화시키고

    상속받는 인터페이스는 건드리지 않고 기능을 추가 삭제 가능하다.

    default 메서드:

    예를 들어 기존에 인터페이스를 구현한 클래스 말고 새로 그 기능을

    구현할 새로운 클래스가 생겼는데 그 클래스를 위해 추가로 메서드를 생성시 기존의 클래스에

    영향이 가지 않도록 default 메서드를 생성해 이 인터페이스를 사용한다면 기본으로 사용

    할 수 있는 메서드를 제공한다.(default 메서드는 인터페이스에서 구현해야한다!!)

    디폴트메서드는 오버라이딩도 가능하기 때문에 사용할 클래스에서 고쳐쓰는게 가능하다.

    상속받은 default 메서드를 자식인터페이스에서 다시 추상메서드로 바꾸는 오버라이딩도 가능하다.


    nested 중첩(내부클래스)

    내부클래스도 바이트 코드 따로 생성(사실 잘 사용안 함)

    1. 멤버 클래스

    - 인스턴스 클래스: 외부클래스 생성자 생성시 사용가능, 당연히 static 사용가능.

    외부클래스의 멤버변수,메서드와 같은 영역이니까 내부클래스에서 외부멤버 사용가능하다.

    - 정적(static) 클래스: 외부클래스 생성안해도 따로 사용가능. 클래스가 static 메서드도 static을 가질 수 있다.

    외부클래스의 멤버영역은 사용 불가하고, static멤버면 사용가능하다.(같은 static멤버만 가능)

    2. 로컬 클래스

    - 메서드내에서 적용하는 클래스, 외부클래스의 메서드 안에서만 사용가능하다.

    메서드 안에서만 생성자 생성, 필드사용, 메서드사용 가능하다.(접근이 제한되어 있다)


    exception

    오류

    1.에러: 문법오류, 바이트코드로 run되지 못함, 정상상태로 못 돌아감

    2.예외(exception): 문법오류는 아니지만 사용자가 코드오류시 런타임 중 발생

    발생되면 프로그램 종료

    예외처리시 다시 정상으로 돌아감

    java목록에 : Java: Exception 문서 확인!!


    interface 1

    casting(강제형변환)

    인터페이스 형에서 구현한클래스형으로

    인터페이스

    1
    2
    3
    4
    public interface Vehicle {
        
        void run();
    }
    cs

    구현클래스

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class Bus implements Vehicle{
     
        @Override
        public void run() {
            System.out.println("버스를 운전합니다.");
        }
        
        public void checkFare() {
            System.out.println("버스요금을 확인합니다!");
        }
        
    }
    cs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class DriverMain {
     
        public static void main(String[] args) {
     
            Vehicle run = new Bus();
            run.run();
    //        run.checkFare();    Vehicle 인터페이스 타입에는 없는 메서드
            
            Bus bus;
            bus = (Bus)run;    //강제형변환
            bus.run();
            bus.checkFare();
            //Bus 형에는 checkFare() 메서드가 존재한다.
     
        }
     
    }
    cs

    interface 2

    instanceof

    인터페이스

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class Bus implements Vehicle{
     
        @Override
        public void run() {
            System.out.println("버스를 운전합니다.");
        }
        
        public void checkFare() {
            System.out.println("버스요금을 확인합니다!");
        }
        
    }
    cs
    1
    2
    3
    4
    5
    6
    7
    8
    public class Taxi implements Vehicle{
     
        @Override
        public void run() {
            System.out.println("택시를 운전합니다.");
        }
     
    }
    cs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class Driver {
     
        public void drive(Vehicle vehicle) {
            if(vehicle instanceof Bus) {
                //Bus 의 객체일 경우 checkFare() 메서드를 실행
                Bus bus = (Bus)vehicle;
                bus.checkFare();
            }
            //Bus 객체와 다른 객체들 공통적으로 run()메서드를 실행
            vehicle.run();
        }
    }
     
    cs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class DriverMain {
     
        public static void main(String[] args) {
     
            Driver driver = new Driver();
            driver.drive(new Taxi());
            driver.drive(new Bus());
        }
     
    }
    cs

    1번 : 택시를 운전합니다. 2번 : 버스를 운전합니다.


    interface 3

    인터페이스 상속

    여러 인터페이스를 상속(extends!!) 받은 인터페이스 하나를

    클래스가 구현한다(implements!!)

    상속받은 인터페이스는 당연히 본인도 인터페이스니까 상속받은

    추상메서드 구현 따로 안함.

    1
    2
    3
    public interface InterfaceA {
        void methodA();
    }
    cs
    1
    2
    3
    public interface InterfaceB {
        void methodB();
    }
    cs
    1
    2
    3
    public interface InterfaceC extends InterfaceA,InterfaceB{
        void methodC();
    }
    cs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class ImplementC implements InterfaceC{
     
        @Override
        public void methodA() {
            System.out.println("InterfaceA.methodA() 호출");
        }
     
        @Override
        public void methodB() {
            System.out.println("InterfaceA.methodB() 호출");
        }
     
        @Override
        public void methodC() {
            System.out.println("InterfaceA.methodC() 호출");
        }
    }
    cs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
        public static void main(String[] args) {
            
            ImplementC impl = new ImplementC();
            impl.methodA();
            impl.methodB();
            impl.methodC();
            System.out.println();
            
            InterfaceA ia =impl;
            ia.methodA();
    //        ia.methodB();    (x)
    //        ia.methodC();    (x)
            System.out.println();
            
            InterfaceB ib =impl;
    //        ib.methodA();    (x)
            ib.methodB();
    //        ib.methodC();    (x)
            System.out.println();
            
            InterfaceC ic =impl;
            ic.methodA();
            ic.methodB();
            ic.methodC();    
        }
    }
    cs

    interface 4

    default 메서드

    인터페이스

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public interface MyInterface {
        void method1();
     
        default void method2() {
            System.out.println("1년후에 새로운 업무가 추가!!!");
        }
        
        default void method3() {
            System.out.println("MyInterface.method3() 실행!!");
        }
    }
    cs
    1
    2
    3
    4
    5
    6
    7
    public class MyClassA implements MyInterface{
     
        @Override
        public void method1() {
            System.out.println("MyClassA.method1() 실행");
        }
    }
    cs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class MyClassB implements MyInterface{
     
        @Override
        public void method1() {
            System.out.println("MyClassB.method1() 실행");        
        }
     
        @Override
        public void method2() {
            System.out.println("MyClassB.method2() 실행");
        }
    }
    cs

    default method의 필요성

    인터페이스에서 디폴트메서드를 허용한 이유는 기존의 인터페이스를 확장해서

    새로운 기능을 추가할 수 있도록 하기 위해서이다.

    존 인터페이스의 이름과 추상메서드의 변경없이 디폴트메서드만 추가할 수 있기 때문에

    이전에 개발된 구현클래스들을 그대로 사용할 수 있으면서 새롭게 개발된 클래스에서는

    디폴트 메서드를 활용할 수 있도록 한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public class DefaultMethodMain {
     
        public static void main(String[] args) {
            
            MyInterface mia = new MyClassA();
            mia.method1();
            mia.method2();
            mia.method3();
            System.out.println();
            
            MyInterface mib = new MyClassB();
            mib.method1();
            mib.method2();
            mib.method3();        
        }
    }
    cs

    내부클래스

    내부클래스의 위치

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    public class A {
        
        //A생성자
        public A() {
            System.out.println("A객체 생성");
        }
        
        //1. 인스턴스 멤버 클래스
        //A의 멤버, A가 생성되야 사용가능
        public class B{
            
            //B필드
            int field1;
            
            //B생성자
            public B() {
                System.out.println("B객체 생성");
            }
            
            //B메서드
            void method1() {
                System.out.println("B.method1() 실행");
            }
            
            //static void method2(){} (X)
            
            
        }
        
        //2. 정적 멤버 클래스
        //정적 멤버, A 생성안되도 사용가능
        public static class C{
            
            //C필드
            int field1;
            
            //C생성자
            public C() {
                System.out.println("C객체 생성");
            }
            
            //C메서드
            void method1() {
                System.out.println("C.method1() 실행 !!");
            }
            
            static void method2() {
                System.out.println("C.method1() 실행 !!");
            }
        }
        
        //3. 로컬 클래스
        //A의 메소드의 클래스, A생성후 메서드를 쓸 때 사용.
        //로컬클래스는 접근제한자를 사용할 수 없다.
        void method() {
            class D{
                
                //D필드
                int field1;
                
                //D생성자
                public D() {
                    System.out.println("D객체 생성");
                }
                
                //D메서드
                void method1() {
                    System.out.println("D.method1() 실행!!");
                }
                
                //static void method2(){} (X)
            }
            
            //메소드는 단순히 호출만 가능, 메서드 안에서 생성, 호출해야 함
            D d = new D();
            d.field1 = 10;
            d.method1();
        }
    }
     
    cs

    내부클래스의 접근범위

    : 로컬 클래스는 외부클래스멤버들에 아예 접근 불가

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    public class A {
        
        int field1;
        void method1() {}
        
        static int field2;
        static void method2() {}
        
        //인스턴스클래스
        //인스턴스, static인 필드와 메서드에 모두 접근 가능
        class B{
            void method() {
                
                field1 = 10;
                method1();
                
                //외부클래스의 static 멤버는 어차피 데이터영역에 올라가 있으므로 사용 가능
                field2 = 200;
                method2();
            }
        }
        //정적멤버클래스
        //외부클래스의 필드,메서드도 정적필드,메서드만 접근 가능
        static class C{
            
            void method() {
                //field1 = 10;    (X)
                //method1();    (X)
                
                field2 = 200;
                method2();    
            }
        }
    }
     
    cs

    내부인터페이스

    외부클래스에서 하는 역할

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class Button {
     
        //내부 인터페이스
        interface OnClickListner{
            void method();
        }
        
        //필드
        OnClickListner listner;
        
        //메서드
        void touch() {
            listner.method();
        }
        
        void setOnClickListner(OnClickListner listner) {
            this.listner = listner;
        }
    }
    cs
    1
    2
    3
    4
    5
    6
    7
    public class CallListner implements Button.OnClickListner{
     
        @Override
        public void method() {
            System.out.println("전화를 겁니다.");
        }
    }
    cs
    1
    2
    3
    4
    5
    6
    7
    public class MessageListner implements Button.OnClickListner{
     
        @Override
        public void method() {
            System.out.println("메시지를 보냅니다.");
        }
    }
    cs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class ButtonMain {
     
        public static void main(String[] args) {
     
            Button button = new Button();
            
            button.setOnClickListner(new CallListner());
            button.touch();
            
            button.setOnClickListner(new MessageListner());
            button.touch();
        }
    }
    cs

    예외1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class ArrayIndexOutOfBoundsMain {
     
        public static void main(String[]args) {
            
    //        현재 메인보드의 args 배열에 값이 없으므로 ArrayIndexOutOfBoundsException이 걸림
            String data1 = args[0];
            
    //        현재값이 null이므로 NullPointerException이 걸림
            String data = null;
            System.out.println(data.toString());
        }
    }
    cs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class NumberFormatExceptionMain {
     
        public static void main(String[] args) {
            
            String data1 = "100";
            String data2 = "100a";
        
            int val1 = Integer.parseInt(data1);
            System.out.println(val1);
            
            //NumberFormatException 발생
            int val2 = Integer.parseInt(data2);
            System.out.println(val2);
        }
    }
    cs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public class ClassCastingExceptionMain {
     
        public static void main(String[] args) {
            
            Dog dog = new Dog();
            Cat cat = new Cat();
            
            changeDog(dog);
            
            //ClassCastException 발생, 같은 부모를 가져도 자식객체들 끼리는 당연히 형변환 못함.
            changeDog(cat);
        }
     
        private static void changeDog(Animal animal) {
            Dog dog =(Dog)animal;
            System.out.println(dog.toString());
        }
    }
     
    class Animal{}
    class Dog extends Animal{}
    class Cat extends Animal{}
    cs

    예외2

    throws

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class TryCatchMain {
     
        //예외를 호출한 곳에서 Main으로 던져서 해결
        public static void main(String[] args) ClassNotFoundException {
     
            //Dog dog = new Dog(); 이런 형식과 동일
            //Class형 안에 forName("패키지.클래스")으로 접근한 객체 생성 
            //Class 객체 생성자가 private 이기 때문에 이렇게 접근해야 생성됨
            Class cls = Class.forName("java.lang.String");
            System.out.println(cls.toString());
        }
    }
    cs

    try-catch

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public class TryCatchMain {
     
        //예외를 호출한 곳에서 Main으로 던져서 해결
        public static void main(String[] args){
     
            //Dog dog = new Dog(); 이런 형식과 동일
            //Class형 안에 forName("패키지.클래스")으로 접근한 객체 생성 
            //Class 객체 생성자가 private 이기 때문에 이렇게 접근해야 생성됨
     
            try {
                Class cls = Class.forName("java.lang.Stringxxx");
                System.out.println(cls.toString());
            } catch (ClassNotFoundException e) {    //위의 발생한 에러를 매개변수자리에 넣음
                System.out.println("클래스를 찾지 못했습니다.");
                e.printStackTrace();//어디서 에러걸렸는지 추적 및 알려줌
                
                System.out.println(e.getMessage());//매개변수로 온 Class의 정보가 나옴
            }
             
        }
    }
    cs

     


    예외3

    throws

    계속 떠넘기기

    예외떠넘기기(throws)

    메서드 내부에서 예외가 발생할 경우 코딩을 할 때 try~catch 블럭으로 예외처리를 하는 것이 기본이지만

    경우에 따라서는 메서드를 호출한 곳으로 예외를 떠 넘길 수가 있다.

    이 때 사용하는 키워드가 throws 이다.

     

    throws키워드는 메서드 선언부 끝에 작성되어 메서드에서 처리하지 않은 예외를 호출한 곳으로 떠넘기는 역할을 한다. throws 키워드에는 떠넘길 예외클래스를 쉼표로 구분해서 나열해주면 된다.

    throws 키워드가 붙어 있는 메서드는 반드시 try 블럭내에서 호출되어야 한다.

    그리고 catch블럭에서 떠넘긴 예외를 처리해야 한다.

     

    하지만 보통 안쓰이고 아래와 같이 쓰이는 경우 대부분이다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        //계속 떠넘겨서 Main까지 넘겨버리기
        public static void main(String[] args) throws ClassNotFoundException {
            findClass();
        }
     
        private static void findClass() throws ClassNotFoundException {
            Class cls = Class.forName("java.lang.Stringxxx");
            
        }
     
    }
     
    cs

    예외4

    try-catch-finally문

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    public class TryCatchFinallyMain {
     
        public static void main(String[] args) {
     
            String data1 = null;
            String data2 = null;
     
            try {
                data1 = args[0];
                data2 = args[1];
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("실행시 매개변수가 부족합니다!");
                e.getMessage();
                return;
            }
            System.out.println(data1 + "," + data2);
     
            try {
                String str1 = "aaa";
                String str2 = "bbb";
     
                int val1 = Integer.parseInt(str1);
                int val2 = Integer.parseInt(str2);
                int result = val1 + val2;
                System.out.println(result);
     
            } catch (NumberFormatException e) {
                System.out.println("숫자로 변환이 불가능 합니다.");
            } finally {
                System.out.println("무조건 한번은 실행됩니다!!");
            }
        }
     
    }
    cs

    예외5

    다중예외 catch 문

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    public class MultiException {
     
        public static void main(String[] args) {
     
            try {
                String data1 = args[0];
                String data2 = args[1];
     
                String str1 = "aaa";
                String str2 = "bbb";
     
                int val1 = Integer.parseInt(str1);
                int val2 = Integer.parseInt(str2);
                int result = val1 + val2;
                System.out.println(result);
     
    //        } catch (ArrayIndexOutOfBoundsException e) {
    //            System.out.println("실행매개 변수가 부족합니다!");
    //
    //        } catch (NumberFormatException e) {
    //            System.out.println("숫자로 변환이 불가능합니다!");
    //
    //        } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
    //            System.out.println("배열 또는 숫자변환시에 예외가 발생했습니다.");
     
            } catch (Exception e) {
                System.out.println("예외가 발생했습니다.");
                e.getMessage();
                e.printStackTrace();
                //이렇게 추적을 통해 어떤 예외인지 알 수 있어서 위처럼 말고 그냥 Exception 클래스로 다 잡는게 편하다.
            } finally {
                System.out.println("무조건 한번은 실행됩니다!");
     
            }
     
        }
    }
    cs

    'JAVA' 카테고리의 다른 글

    정규표현식,Arrays,java.lang 패키지  (0) 2021.07.23
    java.lang.Object 클래스  (0) 2021.07.23
    상속, instanceof, 추상, interface  (0) 2021.07.22
    set,get,상속,overriding & overloading  (0) 2021.07.22
    메서드,싱글톤,static,상수  (0) 2021.07.22

    댓글

Designed by Tistory.