Home [Java 프로그래밍] 5강 - 인터페이스와 다형성
Post
Cancel

[Java 프로그래밍] 5강 - 인터페이스와 다형성

💡해당 게시글은 방송통신대학교 김희천 교수님의 'Java 프로그래밍' 강의를 개인 공부 목적으로 메모하였습니다.



학습 개요


  • 객체 지향 개념을 적절히 활용하여 클래스를 정의하려면 상속, 메소드 재정의, 메소드 오버로딩, 인터페이스의 구현, 다형성의 활용법 등을 숙지해야 함
  • 유사 객체들의 공통 행위 양식을 정의하기 위한 인터페이스 개념을 이해하고 다형성을 활용한 객체 지향 프로그래밍 기법을 익히도록 함



학습 목표


  • 추상 클래스의 의미를 설명할 수 있음
  • 인터페이스의 선언과 사용법을 설명할 수 있음
  • 다형성을 활용하는 프로그램을 작성할 수 있음
  • 열거 자료형과 익명 클래스의 용도를 설명할 수 있음
  • 내부 클래스의 의미를 설명할 수 있음



강의록


추상 클래스와 인터페이스

추상 메소드

  • 메소드 선언에 abstract키워드를 사용
  • 몸체의 구현이 없는 형식만 존재하는 메소드
    • 반환형, 메소드 이름과 인자에 관한 선언만 존재
    • 자식 클래스에 상속될 때, 몸체의 구현이 필요함
    • 상반된 의미의 final과 함께 사용 불가
    • 추상 메소드는 추상 클래스 또는 인터페이스에서 선언되어야 함
    class="highlight">
    1
    2
    3
    4
    
      abstract public class Shape {
          // 모양이 정해지지 않았기 때문에 면적 계산 불가
          abstract public double getArea(); // 추상 메소드
      }
    

    추상 클래스

    • 클래스 정의에 abstract키워드 사용
      • 추상 메소드를 포함할 수 있음
      • 데이터 필드나 일반 메소드를 포함할 수 있음
      • 객체 생성을 할 수 없음
        • 구체적이지 못한 불완전한 클래스라는 의미
        • ex) Shape이 추상 클래스라 가정

          class="highlight">
          1
          
            Shape s = new Shape("red"); // 컴파일 오류 발생
          

          추상 클래스의 사용

          • 의미적으로 유사한 클래스(자식 클래스)를 묶고자 할 때 사용
            • 공통으로 사용할 데이터 필드와 메소드를 추상 클래스에서 정의
          • 추상 클래스는 불완전한 클래스
            • 기능적으로 구현하기 어려운 메소드가 존재
          • 추상 클래스는 자식 클래스로 상속되어 사용됨
            • 자식 클래스에서 추상 메소드를 구현해야 함
            • 그러면 자식 클래스는 객체 생성이 가능
            • 자식 클래스가 추상 메소드를 구현하지 않으면 계속해서 자식 클래스도 추상 클래스이어야 함
          • 추상 클래스는 일반 클래스와 인터페이스의 중간적 성격을 가짐

          인터페이스

          • 100% 추상적 클래스
            • 인터페이스의 모든 메소드가 추상 메소드(public abstract)
          • 몸체 없이 구현되어야 할 메소드의 형식만 정의해 둠
            • 단, default 인스턴스 메소드와 static메소드는 몸체를 구현함
              • 모든 메소드의 기본 접근 제어자는 public
            • 데이터 필드는 클래스 상수만 가능
              • public static final
          • 참조형이며 직접적 객체 생성 불가
          • 인터페이스의 이름은 보통 형용사
            • Runnable
            • Serializable
            • Comparable

          인터페이스의 정의

          • 문법은 클래스 정의와 유사함
          • 정의할 때 키워드 class 대신에 interface를 사용
            • abstract는 생략하는 것이 일반적임
          • 메소드의 접근 제어자는 기본적으로(생략하더라도) public abstract
            • 몸체가 없으며, 반환형, 이름, 매개변수 목록만 표시
          • default 인스턴트 메소드와 static메소드도 가능
            • 이 경우 몸체 구현해야 함
            • 기본적으로(생략하더라도) 접근 제어자는 public
          • 데이터 필드는 항상(생략 가능) public static final
            • 클래스 상수만 가능함

          인터페이스의 사용

          • 추상 클래스와 마찬가지로 자식 클래스에 상속(구현)되어 사용됨
            • 인터페이스를 상속(부모 인터페이스를 구현)받은 자식 클래스는 모든 추상 메소드를 구현해주어야함
          • 의미적으로는 관련이 없으나 기능적으로 유사한 클래스들을 묶을 때 인터페이스를 사용할 수 있음
            • ex) 대소 비교가 가능한 클래스(사각형, 사람…)
          • 인터페이스를 상속 받아 자식 인터페이스를 정의할 수 있음
            • 인터페이스의 상속(또는 확장)
          class="highlight">
          1
          2
          3
          4
          
          interface Comparable<T> {
              //다른 객체와 크기를 비교하는 메서드
              boolean isLargerThan(T o);
          }
          
          class="highlight">
          1
          2
          3
          4
          5
          6
          7
          
          class Box implements Comparable<Box> {
              private int length, width, height;
              
              public boolean isLargerThan(Box otherBox) {
          
              }
          }
          

          인터페이스의 상속

          • 자식 인터페이스가 부모 인터페이스를 상속 받는 경우
            • 기존 인터페이스를 상속 받아 인터페이스를 정의할 때, 키워드 extends사용

              class="highlight">
              1
              
                interface 자식 인터페이스 extends 부모 인터페이스 { }
              
            • 여러 부모 인터페이스를 상속 받는 다중 상속 가능

              class="highlight">
              1
              2
              3
              4
              
                interface SuperInterface {
                    public void func1();
                    public void func2();
                }
              
              class="highlight">
              1
              2
              3
              
                interface SubInterface extends SuperInterface {
                    public void func3();
                }
              

              인터페이스의 구현

              • 자식 클래스가 부모 인터페이스를 상속 받는(구현 하는) 경우
                • 자식은 부모가 나열한 기능(추상 메소드)을 구현해야 함
                • 구현을 통해 클래스를 정의할 때 implements를 사용

                  class="highlight">
                  1
                  2
                  3
                  
                    class 자식클래스 extends 부모클래스 implements 부모인터페이스1, 부모인터페이스2 {
                          
                    }
                  
                  class="highlight">
                  1
                  2
                  3
                  4
                  
                    interface Movable {
                        void add(double dx, double dy);
                        void sub(double dx, double dy);
                    }
                  
                  class="highlight">
                  1
                  2
                  3
                  4
                  
                    interface Scalable {
                        void mul(double s);
                        void div(double s);
                    }
                  
                  class="highlight">
                  1
                  2
                  3
                  4
                  5
                  6
                  7
                  8
                  9
                  10
                  11
                  12
                  13
                  14
                  15
                  16
                  17
                  18
                  19
                  20
                  21
                  22
                  
                    class Point implements Movable, Scalable {
                      
                        @Override
                        public void add(double dx, double dy) {
                  
                        }
                  
                        @Override
                        public void sub(double dx, double dy) {
                  
                        }
                  
                        @Override
                        public void mul(double s) {
                  
                        }
                  
                        @Override
                        public void div(double s) {
                  
                        }
                    }
                  

                  인터페이스의 구현의 예

                  class="highlight">
                  1
                  2
                  3
                  
                  interface Figure {
                      double getArea();
                  }
                  
                  class="highlight">
                  1
                  2
                  3
                  4
                  5
                  6
                  7
                  8
                  9
                  10
                  11
                  12
                  
                  class Triangle implements Figure {
                      private double height, width;
                      
                      public Triangle(double h, double w) {
                          height = h;
                          width = w;
                      }
                      
                      public double getArea() {
                          return height * width * 0.5;
                      }
                  }
                  
                  class="highlight">
                  1
                  2
                  3
                  4
                  5
                  6
                  7
                  8
                  9
                  
                  public class Main {
                      public static void main(String args[]) {
                          Triangle t = new Triangle(3.0, 4.0);
                          
                          System.out.println(t.getArea());
                      }
                  }
                  
                  // 6.0
                  

                  디폴트 메소드

                  • 인터페이스에서 선언하는 메소드에 기본 구현(몸체)을 넣을 수 있음
                    • 자식 클래스에서 상속 받을 때, 디폴트 메소드를 그대로 사용할 수 있음
                    • 메소드 선언 시 default를 사용하고 몸체를 구현해 줌
                  • 인터페이스에 새 메소드를 추가할 때, 기존 코드(클래스 정의)의 수정을 피하기 위함
                    • 단순히 추상 메소드가 추가된다면, 이전 인터페이스를 구현한 클래스를 수정해야 함
                    class="highlight">
                    1
                    2
                    3
                    4
                    5
                    6
                    7
                    8
                    9
                    10
                    
                      interface DoIt {
                          void doSomething(); // 추상 메소드
                    
                          int doSomethingElse(String s); // 추상 메소드
                            
                          // 아래를 새로 추가한다면?
                          default boolean didItWork(int i, String s) {
                              return true;
                          }
                      }
                    

                    추상 클래스, 인터페이스, 클래스의 형변환

                    • 인터페이스와 클래스는 모두 사용자 정의형
                    • extendsimplements에 따라 상위/하위 자료형(부모/자식) 관계가 설정 됨
                    • 상위 유형의 변수는 하위 객체의 참조 값을 가질 수 있음
                    • 상위 유형의 변수가 가리키는 객체의 실제 유형에 따라 수행되는 메소드가 결정됨(동적 바인딩)
                      • 실행 중 메소드 호출 시, 변수의 선언 유형으로 정하지 않음
                      class="highlight">
                      1
                      2
                      3
                      
                          
                        SuperClass super = new SubClass(); // 자동 형 변환 upcasting
                        super.method(); // method()를 SubClass에서 찾음
                      
                      • 컴파일할 때는 method()가 sup의 선언 유형에 정의되어 있는지 확인함

                      다형성

                      다형성

                      • 유사하지만 다양한 형상이나 다양한 기능을 가진다는 뜻
                        • 한 부모에서 나온 두 자식 객체는 비슷하지만 다름
                        • 하나의 클래스에서 오버로딩된 메소드들은 유사하지만 조금씩 다른 기능을 수행함
                        • 자식 클래스에서 재정의된 메소드는 부모의 것과 유사하지만 다른 기능을 수행함

                      다형성과 형변환

                      • 형변환
                        • 상속 관계에 있는 클래스 간에는 타입 변환이 가능함
                          • 전혀 다른 두 클래스 간에는 타입 변환이 금지됨
                        • 자식(하위) 클래스에서 부모(상위) 클래스로의 형 변환은 문제 없음
                          • 업캐스팅이라 하며 자동으로 형 변환 가능함
                          • 참조형 변수는 같은 유형 또는 자식 유형의 객체를 참조할 수 있음
                          class="highlight">
                          1
                          
                            Animal animal = (Animal) new Dog(); // 하위 객체 참조
                          
                        • 다형성의 활용 효과
                          • 코드의 유연성과 재 사용성
                          • 동적 바인딩을 통해 실제 유형을 명시적으로 다룰 필요가 없음

                          다형성과 오버라이딩

                          • 클래스의 다형성
                            • 부모 클래스로부터 상속받은 메소드를 자식 클래스에서 오버라이딩할 수 있음
                            • 부모와 자식에서 같은 이름의 메소드가 다른 기능을 수행
                              • 메소드 이름, 매개 변수, 반환형은 같으나 몸체의 구현이 다름
                            • 서로 다른 자식 간에도 같은 이름의 메소드가 다른 기능을 수행
                          • 인터페이스의 다형성
                            • 자식 클래스들에서 상위 인터페이스의 메소드를 다르게 구현함

                          클래스 상속과 다형성 사용 예시

                          • ex)

                            class="highlight">
                            1
                            2
                            3
                            4
                            5
                            
                              class A {
                                  public void func() {
                                      System.out.println("A");
                                  }
                              }
                            
                            class="highlight">
                            1
                            2
                            3
                            4
                            5
                            
                              class B extends A {
                                  public void func() {
                                      System.out.println("B");
                                  }
                              }
                            
                            class="highlight">
                            1
                            2
                            3
                            4
                            5
                            
                              class C extends B {
                                  public void func() {
                                      System.out.println("C");
                                  }
                              }
                            
                            class="highlight">
                            1
                            2
                            3
                            4
                            5
                            6
                            7
                            8
                            9
                            10
                            11
                            
                              public class Main {
                                  public static void main(String args[]) {
                                      A a = new B();
                                      a.func(); // B 클래스의 func 메소드 호출
                                      a = new C();
                                      a.func(); // C 클래스의 func 메소드 호출
                                  }
                              }
                                
                              // B
                              // C
                            
                          • ex)

                            class="highlight">
                            1
                            2
                            3
                            4
                            5
                            6
                            7
                            8
                            
                              class Employee {
                                  int nSalary;
                                  String szDept = null;
                                
                                  public void doJob() {
                                      System.out.println("Do something");
                                  }
                              }
                            
                            class="highlight">
                            1
                            2
                            3
                            4
                            5
                            6
                            7
                            8
                            9
                            
                              class Sales extends Employee {
                                  public Sales() {
                                      szDept = "Sales Dept"; 
                                  }
                                    
                                  public void doJob() {
                                      System.out.println("Do sales");
                                  }
                              }
                            
                            class="highlight">
                            1
                            2
                            3
                            4
                            5
                            6
                            7
                            8
                            9
                            
                              class Development extends Employee {
                                  public Development() {
                                      szDept = "Sales Dept";
                                  }
                                    
                                  public void doJob() {
                                      System.out.println("Do development");
                                  }
                              }
                            
                            class="highlight">
                            1
                            2
                            3
                            4
                            5
                            6
                            7
                            8
                            9
                            10
                            11
                            12
                            13
                            14
                            
                              public class Main {
                                  public static void main(String args[]) {
                                      Employee emp1, emp2; // 클래스 객체 변수 정의
                                
                                      emp1 = new Sales();
                                      emp2 = new Development();
                                
                                      emp1.doJob(); // Employee의 doJob 메소드 존재 확인 후 Sales 클래스의 doJob 메소드 호출
                                      emp2.doJob(); // Development 클래스의 doJob 메소드 호출
                                  }
                              }
                                
                              // Do sales
                              // Do development
                            

                            열거 자료형

                            열거형

                            • 미리 정의된 상수 값의 집합을 만들기 위한 자료형
                              • enum을 사용하여 정의
                              • 열거형으로 선언된 변수에는 미리 지정된 값만 대입 가능
                              • 상수 값을 배열로 리턴하는 static메소드인 values()를 제공
                              class="highlight">
                              1
                              2
                              3
                              
                                enum Day { // Enum 유형 Day
                                    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
                                }
                              
                              class="highlight">
                              1
                              2
                              3
                              4
                              5
                              6
                              7
                              8
                              
                                public class Main {
                                    public static void main(String[] args) {
                                        Day day = Day.MONDAY;			
                                        for (Day d : Day.values()) {
                                            System.out.println(d); // 각 원소 출력
                                        }
                                    }
                                }
                              

                              열거형 정의 하기

                              • 열거형 정의에 필드와 메소드를 포함할 수 있음
                              • 상수 선언이 필드나 메소드보다 먼저 정의되어야 하며 이때 세미콜론(;)으로 끝나야 함
                              • 열거형에서 상수 값은 마치 하나의 객체와 같음
                                • 열거형이름.상수값의 형식을 사용
                                • 열거형이름.상수값은 그 자체가 열거형의 인스턴스
                              • 생성자는 열거형과 같은 이름을 가지며 접근 제어자는 생략 또는 private이어야 함
                              • 열거형의 생성자는 열거형 상수(객체)에 대한 초기화를 수행함
                                • 생성자는 상수가 사용될 때 한꺼번에 자동 호출 됨
                              • 열거형 사용

                                class="highlight">
                                1
                                2
                                3
                                4
                                5
                                6
                                7
                                8
                                9
                                10
                                11
                                12
                                13
                                14
                                15
                                
                                  enum BaseballTeam {
                                      LG(40, 30), SS(30, 40), KT(20, 50),	SK(35, 35), NC(55, 15); // 상수 값 선언
                                    
                                      private final int win; // 데이터 필드 선언
                                      private final int lose;
                                    
                                      private BaseballTeam(int win, int	lose) { // 생성자
                                          this.win = win; 
                                          this.lose = lose;
                                      }
                                    
                                      public double winsRate() {
                                          return (win * 100.0) / (win + lose);
                                      }
                                  }
                                
                                class="highlight">
                                1
                                2
                                3
                                4
                                5
                                6
                                7
                                8
                                9
                                
                                  public class Main {
                                      public static void main(String args[]) {
                                          BaseballTeam bt = BaseballTeam.LG;
                                    
                                          System.out.println(bt.winsRate());
                                      }
                                  }
                                    
                                  // 57.142857142857146
                                

                                익명 클래스

                                익명 클래스

                                • 일회성으로 1개의 객체를 생성하기 위한 클래스
                                  • 익명 클래스 정의와 동시에 객체 생성할 수 있음
                                • 부모 클래스를 상속 받거나 인터페이스를 구현하도록, 익명 클래스를 정의함
                                • 익명 클래스의 정의 방법
                                  • 아래에서 중괄호가 익명 클래스의 몸체가 됨
                                  • 부모 클래스를 상속 받는 (익명 서브 클래스) 객체를 생성할 때

                                    class="highlight">
                                    1
                                    2
                                    3
                                    
                                      new 슈퍼클래스 () {
                                            
                                      } // 슈퍼클래스의 자식 객체 생성
                                    
                                  • 인터페이스를 구현 하는 (익명 구현 클래스) 자식 객체를 생성할 때

                                    class="highlight">
                                    1
                                    2
                                    3
                                    
                                      new 인터페이스 () {
                                            
                                      } // 인터페이스를 구현하는 자식 객체 생성
                                    

                                    익명 서브 클래스의 객체 생성

                                    class="highlight">
                                    1
                                    2
                                    3
                                    4
                                    5
                                    6
                                    7
                                    8
                                    9
                                    10
                                    11
                                    12
                                    13
                                    14
                                    15
                                    16
                                    17
                                    18
                                    19
                                    20
                                    21
                                    22
                                    23
                                    
                                    public class Main {
                                        public static void main(String args[]) {
                                            CSuper sub = new CSuper() { // CSuper를 상속 받는 익명 클래스 정의 후 객체 생성
                                                public int b = 20;
                                                
                                                public void method1() {
                                                    System.out.println("sub1"); 
                                                }
                                                
                                                public void method3() {
                                                    System.out.println("sub3"); 
                                                }
                                        };
                                        
                                        sub.method1(); // CSuper를 상속 받는 하위 클래스의 객체를 가리킴
                                        sub.method2(); // CSuper를 상속 받는 하위 클래스의 객체에 method2가 없어 부모 클래스에서 호출
                                        
                                        System.out.println(sub.a); // sub의 선언 유형인 CSuper에서 데이터 필드 호출
                                        
                                        // sub.method3(); 컴파일 오류
                                        // System.out.println(sub.b); 컴파일 오류
                                    }
                                    }
                                    
                                    class="highlight">
                                    1
                                    2
                                    3
                                    4
                                    5
                                    6
                                    7
                                    8
                                    9
                                    10
                                    11
                                    12
                                    13
                                    14
                                    15
                                    
                                    class CSuper {
                                        public int a = 10;
                                        
                                        public void method1() {
                                            System.out.println("super1");
                                        }
                                        
                                        public void method2() {
                                            System.out.println("super2");
                                        }
                                    }
                                    
                                    // sub1
                                    // super2
                                    // 10
                                    

                                    익명 구현 클래스의 객체 생성

                                    class="highlight">
                                    1
                                    2
                                    3
                                    
                                    interface MyInterface {
                                        public void method(); // 추상 메소드
                                    }
                                    
                                    class="highlight">
                                    1
                                    2
                                    3
                                    4
                                    5
                                    6
                                    7
                                    8
                                    9
                                    10
                                    11
                                    12
                                    13
                                    
                                    public class Main {
                                        public static void main(String args[]) {
                                            MyInterface sub = new MyInterface() {
                                                public void method() {
                                                    System.out.println("sub1");
                                                }
                                            };
                                    
                                            sub.method();
                                        }
                                    }
                                    
                                    // sub1
                                    

                                    중첩 클래스

                                    중첩 클래스

                                    • 외부 클래스 정의 내부에서 정의된 또 다른 클래스
                                      • 내부(inner) 클래스라고 하며, 외부(outer) 클래스의 멤버가 됨
                                        • 논리적 그룹화를 위한 것
                                      • 내부 클래스는 보통의 클래스와 다르게 private또는 protected클래스가 될 수 있음
                                      • 일반적으로 내부 클래스는 외부 클래스의 필드와 관련된 작업을 처리
                                    • non-static 중첩 클래스
                                      • 외부 클래스의 객체가 생성된 이후 사용 가능
                                        • 외부 클래스의 객체와 연관
                                      • 객체 생성 방법은 외부클래스객체변수.new 내부 클래스()
                                      • 메소드는 this 외에 외부 클래스 객체의 참조(외부클래스.this)를 가지고 있음
                                      • 외부 클래스의 모든 멤버에 접근할 수 있음
                                    • static 중첩 클래스
                                      • 외부 클래스의 객체 생성과 무관하게 사용 가능
                                      • 외부 클래스의 정적 멤버에 접근할 수 있음

                                    중첩 클래스에서 같은 이름의 필드 참조하기

                                    class="highlight">
                                    1
                                    2
                                    3
                                    4
                                    5
                                    6
                                    7
                                    8
                                    9
                                    10
                                    11
                                    12
                                    13
                                    
                                    class OuterClass {
                                        public int x = 0;
                                        
                                        class InnerClass {
                                            public int x = 1;
                                            
                                            void methodInnerClass(int x) {
                                                System.out.println("x = " + x);
                                                System.out.println("this.x = " + this.x);
                                                System.out.println("OuterClass.this.x = " + OuterClass.this.x);
                                            }
                                        }
                                    }
                                    
                                    class="highlight">
                                    1
                                    2
                                    3
                                    4
                                    5
                                    6
                                    7
                                    8
                                    9
                                    10
                                    11
                                    12
                                    
                                    public class Main {
                                        public static void main(String args[]) {
                                            OuterClass oc = new OuterClass();
                                            OuterClass.InnerClass ic = oc.new InnerClass();
                                            
                                            ic.methodInnerClass(2);
                                        }
                                    }
                                    
                                    // x = 2
                                    // this.x = 1
                                    // OuterClass.this.x = 0
                                    

                                    내부 클래스의 사용

                                    class="highlight">
                                    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
                                    
                                    import java.util.Iterator;
                                    
                                    /**
                                     * 배열의 짝수 인덱스 요소들을 반복적으로 접근하기 위한 반복자 패턴 구현
                                     */
                                    public class NestedClassTest {
                                        // 배열의 크기를 상수로 정의
                                        private final static int SIZE = 15;
                                        // 데이터를 저장할 배열 선언
                                        private int[] data = new int[SIZE];
                                    
                                        /**
                                         * 배열을 초기화하여 인덱스 값을 배열 요소에 저장
                                         */
                                        public NestedClassTest() {
                                            for (int i = 0; i < SIZE; i++)
                                                data[i] = i;
                                        }
                                    
                                        /**
                                         * 짝수 인덱스 요소들을 출력하는 메서드
                                         * 내부 클래스인 EvenIterator를 생성하여 짝수 인덱스의 요소들에 접근
                                         */
                                        public void printEven() {
                                            // 내부 클래스의 인스턴스 생성
                                            EvenIterator iterator = this.new EvenIterator();
                                    
                                            // 반복자를 사용하여 다음 요소가 있는 동안 반복
                                            while (iterator.hasNext())
                                                System.out.print(iterator.next() + " ");
                                            System.out.println();
                                        }
                                    
                                        /**
                                         * 짝수 인덱스 요소에만 접근하기 위한 내부 클래스(Inner Class)
                                         * 외부 클래스의 private 멤버(data 배열)에 직접 접근 가능
                                         */
                                        private class EvenIterator implements Iterator<Integer> {
                                            // 다음 접근할 인덱스를 저장 (0부터 시작)
                                            private int nextIndex = 0;
                                    
                                            /**
                                             * 다음 요소가 있는지 확인하는 메서드
                                             * 접근할 수 있는 요소가 남아있으면 true, 그렇지 않으면 false 반환
                                             */
                                            public boolean hasNext() {
                                                return (nextIndex <= SIZE - 1);
                                            }
                                    
                                            /**
                                             * 다음 요소를 반환하고 내부 인덱스를 2 증가시키는 메서드
                                             * 2씩 증가시켜 짝수 인덱스만 접근
                                             */
                                            public Integer next() {
                                                // 현재 인덱스 위치의 데이터를 Integer 객체로 변환
                                                Integer ret = Integer.valueOf(data[nextIndex]);
                                                // 다음 짝수 인덱스를 가리키도록 2 증가
                                                nextIndex += 2;
                                    
                                                return ret;
                                            }
                                        }
                                    
                                        public static void main(String args[]) {
                                            // NestedClassTest 객체 생성
                                            NestedClassTest nc = new NestedClassTest();
                                            // 짝수 인덱스 요소들 출력 (0, 2, 4, 6, 8, 10, 12, 14의 값)
                                            nc.printEven();
                                        }
                                    }
                                    
                                    // 0 2 4 6 8 10 12 14
                                    



                                    학습 정리


                                    • 몸체가 없는 메소드를 추상 메소드라고 하며, 추상 클래스 또는 인터페이스에 포함될 수 있음
                                    • 인터페이스는 추상 메소드로만 구성됨
                                      • 단, default 인스턴스 메소드와 static메소드는 몸체가 있어야 함
                                    • 의미적으로 유사한 클래스를 묶을 때는 추상 클래스로, 기능적으로 유사한 클래스를 묶을 때는 인터페이스를 사용함
                                    • 다형성은 메소드 오버라이딩과 오버로딩, 클래스 간 상속과 형변환, 인터페이스의 구현과 형변환, 메소드 동적 바인딩을 통해 구현될 수 있음
                                    • 열거 자료형은 여러 상수 값을 미리 정의하기 위한 자료형이며, 각 상수 값은 하나의 객체와 같음
                                    • 익명 클래스는 이름이 없는 클래스로, 일회성으로 상속 또는 구현을 통해 자식 객체를 생성하는 용도로만 사용되는 클래스를 의미 함



                                    연습 문제


                                    1. 다음 프로그램을 실행했을 때 예상되는 출력은?

                                      class="highlight">
                                      1
                                      2
                                      3
                                      4
                                      5
                                      6
                                      7
                                      8
                                      9
                                      10
                                      11
                                      12
                                      13
                                      14
                                      15
                                      16
                                      17
                                      18
                                      19
                                      20
                                      21
                                      
                                       class A { 
                                           public void func() { 
                                               System.out.print("a"); 
                                           }
                                       }
                                          
                                       class B extends A {
                                           public void func() {
                                               System.out.print("b");
                                           }
                                       }
                                          
                                       class C extends B {
                                       }
                                          
                                       public class PolymorphTest{
                                           public static void main(String args[]) {
                                               A a = new C();
                                               a.func();
                                           }
                                       }
                                      

                                      a. B

                                    2. 밑줄 친 ㄱ에 ㄴ에 들어갈 키워드는 순서대로 무엇인가?

                                      class="highlight">
                                      1
                                      2
                                      3
                                      
                                       interface Able { }
                                       interface B /** ㄱ **/ Able { }
                                       class C /** ㄴ  **/ Able { }
                                      

                                      a. implements, extends

                                    3. 밑줄 친 부분의 의미를 정확히 설명하시오. 단, CSuper는 클래스 이름이다.

                                      class="highlight">
                                      1
                                      
                                       CSuper sub = new CSuper() {  } ;
                                      

                                      a. CSuper 클래스를 상속받는 익명 클래스를 정의하고, 동시에 익명 클래스의 객체를 생성한다.

                                      Contents

                                      [데이터베이스 시스템] 4강 - SQL

                                      [파이썬 프로그래밍 기초] 5강 - 순차 구조