자바 reflection

리플렉션(reflection)은 자바 프로그래밍 언어의 기능 중 하나다. 리플렉션을 사용하면 자바 프로그램을 실행해서 해당 프로그램을 조사하거나 스스로를 살펴볼(introspect) 수 있다. 또한 프로그램의 내부 프로퍼티를 조작할 수도 있다. 예를 들어 리플렉션을 사용하면 자바 클래스에서 해당 클래스의 멤버의 이름을 모두 획득해서 표시할 수 있다.


자바 클래스에서 스스로를 조사하고 조작하는 이러한 기능이 그리 대단해 보이지 않을 수도 있다. 하지만 이러한 기능을 지원하지 않는 프로그래밍 언어도 있다. 예를 들어 파스칼, C, C++ 프로그램에서는 해당 프로그램 안에 정의된 함수에 대한 정보를 얻을 수 있는 방법이 없다.


실제로 자바 빈(JavaBeans)에서 리플렉션을 적용했다. 자바 빈을 사용하면 소프트웨어 컴포넌트를 빌더 툴을 사용해서 시각적으로 조작할 수 있다. 이러한 빌더 툴은  자바 컴포넌트(클래스)가 동적으로  로드될 때, 리플렉션을 사용해서 해당 컴포넌트의 프로퍼티를 획득한다.


간단한 예제

리플렉션이 어떻게 동작하는지 아래의 간단한 예를 통해 살펴보자:

   import java.lang.reflect.*;
 
   public class DumpMethods {
      public static void main(String args[])
      {
         try {
            Class c = Class.forName(args[0]);
            Method m[] = c.getDeclaredMethods();
            for (int i = 0; i < m.length; i++)
            System.out.println(m[i].toString());
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }


아래와 같이 실행해 보면

java DumpMethods java.util.Stack


결과는 다음과 같다:

public java.lang.Object java.util.Stack.push(java.lang.Object)
public synchronized java.lang.Object java.util.Stack.pop()
public synchronized java.lang.Object java.util.Stack.peek()
public boolean java.util.Stack.empty()
public synchronized int java.util.Stack.search(java.lang.Object)


보다시피 java.util.Stack 클래스의 메서드 명이 출력된다. 메서드의 파라미터와 리턴 타입 또한 패키지 명을 포함해서 출력된다.


이 프로그램은 Class.forName을 사용해서 기술된 클래스를 로드한 후, getDeclaredMethods를 호출해서 해당 클래스에 정의된 메서드 목록을 얻는다. java.lang.reflect.Method는 클래스에서 단일 메서드를 나타내는 클래스다.



리플렉션 사용을 위한 설정

Method와 같이 리플렉션을 위한 클래스는 java.lang.reflect 패키지에서 찾을 수 있다. 이 패키지에 있는 클래스를 사용하려면 세 단계를 거쳐야만 한다. 첫 단계로 조작하려는 클래스에 해당하는 java.lang.Class 객체를 얻어야 한다. java.lang.Class는 실행 중인 자바 프로그램에서 클래스 또는 인터페이스를 나타내기 위해 사용한다.


Class 객체를 얻을 수 있는 한 가지 방법은 다음과 같다:

Class c = Class.forName("java.lang.String");


와 같이 사용하면 String에 대한 Class 객체를 얻을 수 있다. 또는 다음과 같이 사용할 수도 있다:

Class c = int.class;   // 또는
Class c = Integer.TYPE; 


와 같이 사용하면 기본형에 대한 Claass 정보를 얻을 수 있다. 두 번째 방법의 경우, 기본현에 대한 래퍼 클래스(Integer와 같이)에 미리 정의된 TYPE 필드에 접근한다.


두 번째 단계는 getDeclaredMethods와 같은 메서드를 호출하는 작업으로, getDeclaredMethods를 호출하면 해당 클래스에 선언된 메서드의 목록을 모두 얻을 수 있다.


이러한 정보를 모두 얻고 나면, 세 번째 단계로 리플렉션 API를 사용해서 해당 정보를 조작할 수 있다. 예를 들어 아래와 같은 일련의 문장을 실행하면,


Class c = Class.forName("java.lang.String");
Method m[] = c.getDeclaredMethods();
System.out.println(m[0].toString());


String에 선언된 첫 번째 메서드를 텍스트 형식으로 표시하게 된다.


이후에 다룰 예제에서는 지금 설명한 세 단계를 결합해서 사용한다. 이를 통해 특정한 목적에 맞게 리플렉션을 활용하는 방식을 효과적으로 처리하는 예제를 한꺼번에 보여주고자 한다.


결론

자바 리플렉션을 사용하면 클래스와 데이터 구조에 대한 정보를 이름을 기반으로 동적으로 얻을 수 있다는 점에서 매우 유용하다. 뿐만 아니라 리플렉션을 사용하면 자바 프로그램을 실행하는 동안에 해당 클래스를 조작할 수 있다. 이 기능은 믿을 수 없을 정도로 강력하며, C, C++, 포트란, 파스칼과 같은 자바 이외의 언어에서는 리플렉션에 해당하는 기능이 전혀 없다.



'Develop > Java' 카테고리의 다른 글

String, StringBuffer, StringBuilder  (0) 2016.12.01
Quick sort  (0) 2016.11.21
자바 reflection  (0) 2016.11.17
문자열 "ABCDEFG"를 역순으로 출력  (0) 2016.11.17
JAVA의 접근제한자  (0) 2016.11.15

String, StringBuffer, StringBuilder 




모두 문자열을 저장하고, 관리하는 클래스 이다. char와 String의 가장 큰 차이점도 이점에 있다.


char는 문자 함수이고 

String은 클래스라는 차이를 알아야 한다.


char와 String의 차이는 다음 기회에 다시 안내하기로 하겠다.

 

먼저 String 과 다른 클래스(StringBuffer, StringBuilder)의 차이점을 알아보겠다. 

두 문자열 클래스의 아주 기본적인 차이는 String은 immutable(불변함)하고, StringBuffer는 mutable(변함,변하기쉬움)하다는 것이다.


결론부터 말하자면, 

단순하게 성능으로 따지면 StringBuilder > StringBuffer >>> String 이지만

각 문자열 클래스들은 성능 이슈 외에도 사용 편의성, 멀티스레드 환경 등 여러가지 고려해야할 요인이 있으므로 이에 적합한 것을 사용하면 될 것이다.

한마디로 StringBuilder와 StringBuffer는 사용 목적에 따라 다르다라는 것이다.


먼저 스트링은  

String 객체는 한 번 생성되면 할당된 메모리 공간이 변하지 않는다. + 연산자 또는 concat 메서드를 통해 기존에 생성된 String 클래스 객체 문자열에 다른 문자열을 붙여도 기존 문자열에 새로운 문자열이 붙는 것이 아니라, 새로운 String 객체를 만든 후, 새 String 객체에 연결된 문자열을 저장하고, 그 객체를 참조하도록 한다. (즉, String 클래스 객체는 Heap 메모리 영역(가비지 컬렉션이 동작하는 영역)에 생성되며, 한 번 생성된 객체의 내부 내용을 변화시킬 수 없다. 기존 객체가 제거 되면 Java의 가비지 컬렉션이 회수한다.)

 

String 객체는 이러한 이유로 문자열 연산이 많은 경우, 그 성능이 좋지 않지만, Imuutable한 객체는 간단하게 사용가능하고, 동기화에 대해 신경쓰지 않아도 되기 때문에(Thread-Safe), 내부 데이터를 자유롭게 공유할 수 있다.

 

StringBuffer 와 StringBuilder 차이점

기본적으로 두 클래스가 제공하는 메소드는 동일하지만 StringBuffer는 멀티 쓰레드 상태에서 동기화를 지원한다. (각 메소드 별로 synchronized 키워드가 존재)

String 을 + 를 활용해 합치는 경우 매번 인스턴스를 생성하기 때문에 성능상에 이슈가 많다. 이런 성능 이슈를 개선하기위해 JDK 1.5 버전 이후에는 컴파일 단계에서 StringBuilder로 컴파일 되도록 변경되기 때문에 + 를 활용해도 성능상에 큰 이슈는 없다.


사실 두 클래스의 가장 큰 차이점은 동기화 여부이다.

 

StringBuffer는 각 메서드 별로 Synchronized Keyword 가 존재하여, 멀티스레드 환경에서도 동기화를 지원한다. 하지만, StringBuilder는 동기화를 보장하지 않는다.

그렇기 때문에 멀티스레드 환경이라면 값 동기화 보장을 위해 StringBuffer를 사용하고, 단일스레드 환경이라면 StringBuilder를 사용하는 것이 좋다. 단일스레드환경에서 StringBuffer를 사용한다고 문제가 되는 것은 아니지만, 동기화 관련 처리로 인해 StringBuilder에 비해 성능이 좋지 않다.


 


'Develop > Java' 카테고리의 다른 글

자바 reflection  (0) 2018.05.17
Quick sort  (0) 2016.11.21
자바 reflection  (0) 2016.11.17
문자열 "ABCDEFG"를 역순으로 출력  (0) 2016.11.17
JAVA의 접근제한자  (0) 2016.11.15

퀵소트 정렬

자바로 코딩한 정렬



'Develop > Java' 카테고리의 다른 글

자바 reflection  (0) 2018.05.17
String, StringBuffer, StringBuilder  (0) 2016.12.01
자바 reflection  (0) 2016.11.17
문자열 "ABCDEFG"를 역순으로 출력  (0) 2016.11.17
JAVA의 접근제한자  (0) 2016.11.15

자바 reflection




리플렉션(reflection) 자바 프로그래밍 언어의 기능 하나다. 리플렉션을 사용하면 자바 프로그램을 실행해서 해당 프로그램을 조사하거나 스스로를 살펴볼(introspect) 있다. 또한 프로그램의 내부 프로퍼티를 조작할 수도 있다. 예를 들어 리플렉션을 사용하면 자바 클래스에서 해당 클래스의 멤버의 이름을 모두 획득해서 표시할 있다.

자바 클래스에서 스스로를 조사하고 조작하는 이러한 기능이 그리 대단해 보이지 않을 수도 있다. 하지만 이러한 기능을 지원하지 않는 프로그래밍 언어도 있다. 예를 들어 파스칼, C, C++ 프로그램에서는 해당 프로그램 안에 정의된 함수에 대한 정보를 얻을 있는 방법이 없다.

실제로 자바 (JavaBeans)에서 리플렉션을 적용했다. 자바 빈을 사용하면 소프트웨어 컴포넌트를 빌더 툴을 사용해서 시각적으로 조작할 있다. 이러한 빌더 툴은  자바 컴포넌트(클래스) 동적으로  로드될 , 리플렉션을 사용해서 해당 컴포넌트의 프로퍼티를 획득한다.

간단한 예제
리플렉션이 어떻게 동작하는지 아래의 간단한 예를 통해 살펴보자:

   import java.lang.reflect.*;
 
   public class DumpMethods {
      public static void main(String args[])
      {
         try {
            Class c = Class.forName(args[0]);
            Method m[] = c.getDeclaredMethods();
            for (int i = 0; i < m.length; i++)
            System.out.println(m[i].toString());
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }


아래와 같이 실행해 보면

java DumpMethods java.util.Stack


결과는 다음과 같다:

public java.lang.Object java.util.Stack.push(java.lang.Object)
public synchronized java.lang.Object java.util.Stack.pop()
public synchronized java.lang.Object java.util.Stack.peek()
public boolean java.util.Stack.empty()
public synchronized int java.util.Stack.search(java.lang.Object)


보다시피 java.util.Stack 클래스의 메서드 명이 출력된다. 메서드의 파라미터와 리턴 타입 또한 패키지 명을 포함해서 출력된다.

프로그램은 Class.forName 사용해서 기술된 클래스를 로드한 getDeclaredMethods를 호출해서 해당 클래스에 정의된 메서드 목록을 얻는다. java.lang.reflect.Method는 클래스에서 단일 메서드를 나타내는 클래스다.


리플렉션 사용을 위한 설정
Method
같이 리플렉션을 위한 클래스는 java.lang.reflect 패키지에서 찾을 있다. 패키지에 있는 클래스를 사용하려면 단계를 거쳐야만 한다. 단계로 조작하려는 클래스에 해당하는 java.lang.Class 객체를 얻어야 한다java.lang.Class는 실행 중인 자바 프로그램에서 클래스 또는 인터페이스를 나타내기 위해 사용한다.

Class
객체를 얻을 있는 가지 방법은 다음과 같다:

Class c = Class.forName("java.lang.String");


같이 사용하면 String 대한 Class 객체를 얻을 있다. 또는 다음과 같이 사용할 수도 있다:

Class c = int.class;   // 또는
Class c = Integer.TYPE; 


같이 사용하면 기본형에 대한 Claass 정보를 얻을 있다. 번째 방법의 경우, 기본현에 대한 래퍼 클래스(Integer 같이) 미리 정의된 TYPE 필드에 접근한다.

번째 단계는 getDeclaredMethods와 같은 메서드를 호출하는 작업으로, getDeclaredMethods를 호출하면 해당 클래스에 선언된 메서드의 목록을 모두 얻을 수 있다.

이러한 정보를 모두 얻고 나면, 번째 단계로 리플렉션 API 사용해서 해당 정보를 조작할 있다. 예를 들어 아래와 같은 일련의 문장을 실행하면,

Class c = Class.forName("java.lang.String");
Method m[] = c.getDeclaredMethods();
System.out.println(m[0].toString());


String
선언된 번째 메서드를 텍스트 형식으로 표시하게 된다.

이후에 다룰 예제에서는 지금 설명한 단계를 결합해서 사용한다. 이를 통해 특정한 목적에 맞게 리플렉션을 활용하는 방식을 효과적으로 처리하는 예제를 한꺼번에 보여주고자 한다.

결론
자바 리플렉션을 사용하면 클래스와 데이터 구조에 대한 정보를 이름을 기반으로 동적으로 얻을 있다는 점에서 매우 유용하다. 뿐만 아니라 리플렉션을 사용하면 자바 프로그램을 실행하는 동안에 해당 클래스를 조작할 있다. 기능은 믿을 없을 정도로 강력하며, C, C++, 포트란, 파스칼과 같은 자바 이외의 언어에서는 리플렉션에 해당하는 기능이 전혀 없다.

'Develop > Java' 카테고리의 다른 글

String, StringBuffer, StringBuilder  (0) 2016.12.01
Quick sort  (0) 2016.11.21
문자열 "ABCDEFG"를 역순으로 출력  (0) 2016.11.17
JAVA의 접근제한자  (0) 2016.11.15
오버로딩 vs 오버라이딩  (0) 2016.11.14

문자열 "ABCDEFG"를 역순으로 출력


void ReversString()





'Develop > Java' 카테고리의 다른 글

Quick sort  (0) 2016.11.21
자바 reflection  (0) 2016.11.17
JAVA의 접근제한자  (0) 2016.11.15
오버로딩 vs 오버라이딩  (0) 2016.11.14
Java Collection Framework  (0) 2016.11.14

 JAVA 접근제한자


접근제한자(접근지정자)?

접근제한자란 클래스 내에서 멤버의 접근을 제한하는 역할을 하는 기능. public, private, protect, default등이 있다.


접근제한자 종류

접근제한자

클래스 내부

같은 패키지

하위 클래스

외부 클래스

public

O

O

O

O

protect

O

O

O

X

default

O

O

X

X

private

O

X

X

X


1. public : 모든 접근을 허용모든 클래스가 접근이 가능함.

2. protect : 상속받은 클래스  같은 패키지에서만 접근이 가능함

3. default ; 기본 제한자로 같은 클래스 맴버와 패키지에서 접근이 가능함.

4. private : 외부에서 접근불가같은 클래스 맴버만 접근이 가능함.



'Develop > Java' 카테고리의 다른 글

자바 reflection  (0) 2016.11.17
문자열 "ABCDEFG"를 역순으로 출력  (0) 2016.11.17
오버로딩 vs 오버라이딩  (0) 2016.11.14
Java Collection Framework  (0) 2016.11.14
Abstract class vs Interface  (0) 2016.11.01


오버로딩(Overloading) vs 오버라이딩(Overriding)

 

자바에서 다형성을 지원하는 방법으로 메소드 오버로딩(Overloading) 오버라이딩(Overriding)이 있다.

 

결론부터 말하자면,


오버로딩(Overloading)은 기존에 없던 새로운 메서드를 정의하는 것이고,


오버라이딩(Overriding)은 상속 받은 메서드의 내용만 변경 하는 것이다.

 


간단하게는, 


오버로드(Overload)

메서드의 이름은 같고 파라메터의 갯수나 타입이 다른 함수를 정의하는 것을 의미한다.

(리턴값만을 다르게 갖는 오버로드는 작성 할 수 없다.)



오버라이드(Override)

상위 클래스의 메서드를 재정의 하는 것이다.

메서드의 이름은 물론 파라메터의 갯수나 타입도 동일해야 하며주로 상위 클래스의 동작을 상속받은 하위 클래스에서 변경하기 위해 

사용된다.


 


좀 더 자세하게 가보자면,

 

1. 오버로딩 (Overloading)

오버로딩(Overloading)은 메소드 오버로딩과 생성자 오버로딩이 있다. 하지만 둘다 같은 개념이다.

같은 이름의 함수를 여러 개 정의하고, 매개변수의 유형과 개수를 다르게 하여 다양한 유형의 호출에 응답하게 한다.

 

2. 오버라이딩 (Overriding)

상위 클래스가 가지고 있는 멤버변수가 하위 클래스로 상속되는 것처럼 상위 클래스가 가지고 있는 메소드도 하위 클래스로 상속되어 하위 클래스에서 사용할 수 있다. 하지만, 하위 클래스에서 메소드를 재정의해서 사용할 수 있다.

상속 관계에 있는 클래스 간에 같은 이름의 메소드를 정의하는 기술을 오버라이딩(Overriding) 이라고 한다.

 

오버로딩(Overloading)과 오버라이딩(Overriding) 성립조건


구분

오버로딩 

오버라이딩 

메소드 이름 

동일 

동일 

매겨변수, 타입 

다름 

동일 

리턴 타입 

상관없음 

동일 

 

 



'Develop > Java' 카테고리의 다른 글

자바 reflection  (0) 2016.11.17
문자열 "ABCDEFG"를 역순으로 출력  (0) 2016.11.17
JAVA의 접근제한자  (0) 2016.11.15
Java Collection Framework  (0) 2016.11.14
Abstract class vs Interface  (0) 2016.11.01

Java Collection Framework




1. 정의

 다수의 데이터를 쉽게 처리할  있는 표준화된 방법을 제공하는 클래스들을 말한다컬렉션(Collecion) 다수의 데이터  데이터 그룹프레임워크(Framework) 표준화된 방식을 의미한다.



2. 종류


1. List  순서가 있는 데이터의 집합데이터의 중복을 허용한다.
 원소의 순서가 정의되어 있으며컬렉션상의 위치를 통해 원소에 접근할  있다따라서 List 사용하면 컬렉션 상에서의 인덱스를 통해 어떤 원소를 접근   있다원소간의 순서가 중요한 경우예를 들어 도착 순서대로 메세지를 처리하는 큐의 경우에는 리스트를 사용해야 한다.


2. Set  순서를 유지하지않는 데이터의 집합데이터의 중복을 허용하지 않는다.
 중복원소(상호간 equals() 결과가 참인 원소) 허용하니 않는 컬렉션원소 사이의 순서가 없으므로이전 순차 열람할 때의 원소 순서가 다음 순차 열람할  보장되지 않는다.


3. Map  (key) (value) 쌍으로 이루어진 데이터집합순서는 유지되지않으며 키는 중복이 허용하지 않는다값의 중복은 허용.
 Map List처럼 키를 사용해서 원소를 저장하지만, List 정수만을 키로 사용할  있는 반면 Map 임의의 객체를 키로 사용할  있다 Map 다른 컬렉션 인터페이스와는 형태가 상이하여 다른 컬렉션 인터페이스를 상속하지 않고내부적으로 키에 대한 컬렉션과 데이터에 대한 컬렉션의 2 컬렉션을 유지한다.


 JDK 1.2 이전 까지는 Vector, Stack, Hashtable, Properties 같은 컬렉션 클래스들을 서로 다른 각자의 방식으로 처리해야 했으나, JDK 1.2부터 컬렉션 프레임워크가 등장하면서 다양한 종류의 컬렉션 클래스가 추가되고 모든 컬렉션 클래스들이 표준화된 방식으로 다룰  있도록 체계화 되었다따라서 컬렉션 프레임워크가 만들어지기 이전에 존재하던 것이기 떄문에 컬렉션 프레임워크 명명법을 따르지 않는다



3. 구현

1.List 구현

 ArrayList LinkedList.

 ArrayList 원소 접근이 빠르고 원소 추가  제거가 느린 반면 LinkedList 원소 접근이 느리지만 원소 추가와 제거는 빠르다.

 

2. Set, SortedSet 구현

 HashSet 가장 빠르지만 원소간의 순서를 보장해주지 않는다. LinkedHashSet 원소  순서를 보장해 주지만 원소 추가 삭제  30% 정도 시간이  걸린다. TreeSet Comparator 따라서 원소를 정렬하지만 원소 추가 삭제 시간이 logn(n 컬렉션의 크기) 비례해서 커진다.

 

3. Map 구현

 Map 구현은 Set 구현과 비슷한 패턴을 보인다. HashMap 가장 빠르고 단순하다. LinkedHashMap 컬렉션에 추가된 원소 간의 순서를 보장한다. TreeMap(SortedMap 구현) 키의 순서에 따라 순차 열람이 가능하지만 원소의 추가 제거 시간이 logn(n 컬렉션의 크기) 비례한다.


'Develop > Java' 카테고리의 다른 글

자바 reflection  (0) 2016.11.17
문자열 "ABCDEFG"를 역순으로 출력  (0) 2016.11.17
JAVA의 접근제한자  (0) 2016.11.15
오버로딩 vs 오버라이딩  (0) 2016.11.14
Abstract class vs Interface  (0) 2016.11.01

추상클래스 인터페이스

:

추상클래스는 추상메소드를 1개이상 가진 클래스로 이미 구현된 메소드가 있을수도 있다.


인터페이스는 일종의 명세서로 내부의 모든 메소드가 구현되지않고 선언만 되있다. 


눈에 보이는 차이로는 추상클래스는 extend를 통해 1개만을 상속받을수있고 인터페이스는 implement를 통해 여러개 확장받을수 있다. 


또한 인터페이스는 일종의 가이드 라인으로 확장을 받는 서브클래스들이 대략적으로 어떤 구조와 기능을 가진지 알수있는 역할을 한다.



인터페이스와 추상클래스의 차이


추상클래스(abstract class)?

추상클래스란 추상메소드를   이상 포함하고있는 클래스로써객체화할  없는 클래스이다추상 메소드랑 메소드명과 자료형매개변수만이 정해져있고 내용이  비어있는 메소드로써 오버라이딩을 통해 내용을 채워 재정의를 해야 사용할  있다추상클래스나 추상메소드를 선언하기 위해서는 이름 앞에 abstract이라는 키워드를 추가하면 된다.

추상클래스 구현 예제

public class Test {

public static void main(String[] args) { // 메인 클래스내의 메인 메소드

Rectangle r = new Rectangle(); // 서브클래스 객체생성

Circle c = new Circle(); // 서브클래스 객체생성

r.draw(); // 서브클래스의 상속받은 메소드 호출

c.draw(); // 서브클래스의 상속받은 메소드 호출

}

}

abstract class Shape { // 추상클래스 (슈퍼클래스)

int x, y;

public void move(int x, int y){

this.x=x;

this.y=y;

}

public abstract void draw(); // 추상메소드

}

class Rectangle extends Shape { // 서브클래스

int width,height;

public void draw() { // 추상메소드 재정의

System.out.println("사각형 그리기 메소드");

}

}

class Circle extends Shape { // 서브클래스

int radius;

public void draw() { // 추상메소드 재정의

System.out.println("원그리기메소드");

}

}

추상클래스는 슈퍼클래스의 용도로 사용되며 일반 메소드를 가질  있다추상클래스를 상속받는다면 반드시 추상클래스의 추상메소드를 재정의하여 구현하여야한다.


인터페이스란? (Interface)

추상메소드(내용이없는 메소드) 상수로만 이루어진 클래스이다인터페이스 내에 메소드는 모두 추상메소드이기 때문에 abstract 붙이지 않는다. interface 인터페이스명{ } 형태로 구현하며 인터페이스를 사용하는 클래스들은 implement 사용해야한다

인터페이스 구현 예제

public class Test {

public static void main(String[] args) { // 메인 클래스내의 메인 메소드

/* 각클래스별로 객체생성 */

Television tv = new Television();

Refrigerator r = new Refrigerator();

/* 상속받은 메소드 호출 */

tv.turnOn();

r.turnOn();

tv.turnOff();

r.turnOff();

}

}

interface RemoteControl { // 인터페이스

public void turnOff(); // 메소드선언

public void turnOn(); // 메소드선언

}

class Television implements RemoteControl {

/* 상속받은 메소드 재정의 */

public void turnOff() {System.out.println("TV 끔니다.");}

public void turnOn() {System.out.println("TV 켭니다.");}

}

class Refrigerator implements RemoteControl {

/* 상속받은 메소드 재정의 */

public void turnOff() {System.out.println("냉장고를 끔니다.");}

public void turnOn() {System.out.println("냉장고를 켭니다.");}

}


인터페이스는 모든 메소드가 추상메소드이므로 구현(인터페이스는 상속이 아닌 구현이라 표현) 클래스들에서 재정의가 이루어져야한다이는 코드의 중복이 일어나 단점이 되기도 한다.


추상클래스와 인터페이스 비교


추상클래스

인터페이스

공통점

- 모두 클래스임

- 하위클래스에서 모든 추상메서드를 구현해야 

차이점

- 멤버변수와 일반 메서드를 가질  있다.

extends 사용

- 작업의 레벨 분할을 위해서 사용

- 단일 상속

- 추상메서드와 static final 변수만 사용가능

- Implements 사용

- 중복 구현 가능

- 공동 작업을 위한 상호간의 인터페이스를 위해 사용

- 다중 상속 가능

 

 인터페이스와 추상클래스의 사용에 있어서 가장  차이점은 다중상속 여부이다자바는 다중상속을 할수없는데 인터페이스는 다중구현으로 가능하다이에 대한 자세한 예시는 다음과 같다.



오리 기어다닐수도헤엄칠수도 있다 



 위의 그림은 다중상속을 하지 않고 추상클래스로 구현될  생기는 문제이다다음과 같이 중복을 제거하기위해 추상클래스로 상속을 이용하여 구현할  오리는 육상동물과 수중동물 클래스 2가지의 메소드를 동시에 가져야한다하지만 다중상속은 불가능하므로 애완동물을 상속받는 수륙동물클래스를 추가해야한다하지만 이는 처음에 중복을 피하고자  의도에서 벗어나며 상속을 최소화해야 하는 좋은 프로그래밍의 방법에도 벗어난다.



인터페이스의 다중상속을 이용한 구현


 반면 인터페이스는 다중 상속이 가능하므로 위의 그림처럼 간결한 설계를   있다상속의 단계를 줄였고 앞으로 추가적인 다중상속이 필요할시 상속의 단계를 늘일 필요가 없다.


'Develop > Java' 카테고리의 다른 글

자바 reflection  (0) 2016.11.17
문자열 "ABCDEFG"를 역순으로 출력  (0) 2016.11.17
JAVA의 접근제한자  (0) 2016.11.15
오버로딩 vs 오버라이딩  (0) 2016.11.14
Java Collection Framework  (0) 2016.11.14

+ Recent posts