cf> OOP의 4가지 특징
1) Encapsulation
accesss modifier에 의해 필요한 것만 접근 가능하게 한다.
2) Abstraction
interface : a specification without implementation (명세만 되어있고 구현되어 있지 않은)
abstract classes (interface와 유사)
3) Inheritance
4) Polymorphism
4. Interface
1) Interface의 정의
만드려는 method에서 argument의 type이 매번 바뀌는 경우 method를 여러번 정의해야 할 수 있다.
이 때, implement(구체적 구현)없이 specification(method를 declare)을 하는 것을 interface라고 한다.
interface IntSequence {
boolean hasNext();
int next();
}
1> default access modifier: public
2> default : abstact (구현이 되지 않은 method라는 의미의 keyword)
interface IntSequence {
public abstract boolean hasNext();
public abstract int next();
}
→ 그래서 위 두 코드는 같다.
2) interface로 class 정의
class 정의로 interface를 implement 한다.
class SquareSequence implements IntSequence {
private int i;
public boolean hasNext() {
return true;
}
public int next() {
i++;
return i*i;
}
}
1> class 정의
class SquareSequence implements IntSequence
=> 이 class가 interface(IntSequence)를 implement한다.
2> method 구현
기존 interface 내의 method를 모두 구현해야 한다. (그러지 않으면 error 발생)
그 외에 다른 method를 추가하는 것도 가능하다.
3) static method 정의 및 사용
만들고자 하는 class의 instance가 같은 interface에서 나왔다면
static method에서 argument의 type이 달라도 함수의 argument로 사용이 가능하다.
1> static method 정의
interface의 이름으로 argument type을 사용한다.
public static double average(IntSequence seq, int n) {
int count = 0;
double sum = 0;
while(seq.hasNext() && count < n) {
count++;
sum += seq.next();
}
return count == 0 ? 0 : sum / count;
}
2> static method 호출
해당 interface를 기반으로 정의된 class(type)의 instance라면
충분히 static method의 argument로 올 수 있다.
SquareSequence squares = new SquareSequence();
double avg = average(squares, 100);
4) supertype & subtype
0> (class 이외에)interface로도 implement된 class의 instance의 type을 정할 수 있다.
DigitSequence digits = new DigitSequence();
IntSequence digits = new DigitSequence();
<아래 case에 대해 설명을 덧붙이자면>
digits : IntSequence의 type, DigitSequence의 instance
- supertype (여기서는 IntSequence)
- subtype (여기서는 DigitSequence)
1> subtype object -> supertype variable 할당
supertype(IntSequence) variable(digits)에 subtype(DigitSequence) object(new와 대입연산자로)를 할당할 수 있다.
IntSequence digits = new DigitSequence();
2> interface type object -> ??? (X)
interface type(IntSequence()) 으로 object로 만들 수 없다.
IntSequence() interface는 specification(method를 declare)만 있고 implement(실체)가 없다.
IntSequence seq = new IntSequence(); // impossible
5) typecasting
3> subtype object -> supertype variable -> subtype variable 할당 (두 subtype이 같은 type이어야 한다.)
- 정상 예시
IntSequence sequence = new DigitSequence(2345);
DigitSequence digits = (DigitSequence)sequence;
- 오류 (classCastExepttion)
IntSequence sequence = new SquareSequence();
DigitSequence digits = (DigitSequence)sequence;
cf> ClassCastExeption 오류를 피하기 위해 class의 instance가 맞는지 미리 확인하는 방법
instanceof
IntSequence sequence = new DigitSequence(2345);
if (sequence instanceof DigitSequence) { // true
DigitSequence digits = (DigitSequence)sequence;
System.out.println(digits.rest());
}
IntSequence sequence = new SquareSequence();
if (sequence instanceof DigitSequence) { // false
DigitSequence digits = (DigitSequence)sequence;
System.out.println(digits.rest());
}
6) extends
다른 interface의 method를 그대로 써서 새로운 interface를 정의하고 싶을 경우 extend를 사용한다.
interface Closeable {
void close();
}
interface Channel extends Closeable {
boolean isOpen();
}
→ Channel은 close() method도 사용할 수 있다.
7) 여러개의 interface를 implement 하는 경우
implements 뒤에 2개의 interface를 쓴다.
public class FileSequence implements IntSequence, Closeable {
...
}
8) interface의 variable
interface를 정의할 때 interface variable도 정의할 수 있다.
0> 기본적으로 public static final variable이다.
1> public : 어디서든 접근이 가능합니다.
2> static : class의 실체와 상관없이 사용가능하다.
3> final : 해당 variable의 값을 바꾸지 않음
9) interface의 method
1> 기본 : abstact (구현이 되지 않은 method라는 의미의 keyword)
2> static method : (abstract와 달리) interface에서 implement(구현)을 한다. (factory method라고 부르기도 한다.)
interface IntSequence {
static IntSequence digitsOf(int n) {
return new DigitSequence(n);
}
boolean hasNext();
int next();
}
IntSequence digits = IntSequence.digitsOf(1729);
3> default method :
나중에 inteface를 implement할 때,
method를 구현하지 않으면, interface의 default method를 그대로 사용하고
method를 구현하면, interface의 default method를 덮어쓴다.
interface IntSequence {
default boolean hasNext() { return true; }
int next();
}
class SquareSequence implements IntSequence {
private int i;
public int next() {
i++;
return i*i;
}
}
4> private : 밖에서 접근이 불가능하다.
- [1] interface 내부에서 구현을 다 해야 한다. (abstract가 아니기 때문)
- [2] interface 내부에서만 사용할 수 있다.
- [3] static 여부 (static : object의 실체가 없는 형태)
- private static : 다른 static & non-static method에서 접근(호출) 가능
- private non-static : private static method에서 접근 불가능(호출 불가능)
- [실체가 없는 static이 실체가 있는 non-staticd을 호출할 수 없다.)
10) default method로 인한 collision 현상
동시에 2개의 interface를 implement 하는 상황이라고 가정하겠습니다. 각 interface 내부의 method가 중복되는 문제를 보게 됩니다.
1> 2개의 interface의 method 각각 default method
-> error
2> 1개는 default method, 1개는 abstract method + class에서 이 method를 재정의 X
-> error
3> 1개는 default method, 1개는 abstract method + class에서 이 method를 재정의 O
-> 재정의된 method가 각 interface의 method를 덮어 써서 error가 없다.
4> 2개의 interface의 method 각각 default method + parameter 개수 혹은 type이 다르다.
-> 모호성이 없어서 error가 없다.
'JAVA' 카테고리의 다른 글
[Java] 5-1강 - Generic Programming 1 (generic의 기본) (0) | 2020.11.17 |
---|---|
[Java] 4-1강 - 예외 처리 (0) | 2020.11.17 |
[Java] 2-1강 - 객체 지향 프로그래밍 1 (Encapsulation - Access Modifier) (0) | 2020.10.16 |
[Java] 1-5강 - Inputs and Outputs (0) | 2020.10.06 |
1-4강 - String (0) | 2020.10.06 |