[스터디할래] whitesheep #8 인터페이스

인터페이스.. 아는 내용은 생략 내지 짧게 !

인터페이스는 OOP를 공부하면서 알게 된 내용들이 많다 !

java8 이상의 내용에 대해 보자

사실.. 보기만 해도 이해가 되기 때문에 굳이 설명을 첨언하지는 않았다 !!

JAVA8의 기능을 지원하지 않던 시절

아래와 같이

public interface JoinMember {
	void preJoin();

	void afterJoin();
}

해당 인터페이스에 위 두 추상 메서드가 있다고 할때

인터페이스를 상속받는 클래스는 두 행위를 모두 구현해야만 한다

그런데 하나만 구현하고 싶을때도 있잖아..?

그럴떄는 이렇게 작성한다

public class JoinMid implements JoinMember {
	@Override
	public void preJoin() {
		// System.out.println("들어 올떄는 마음대로지만");
	}

	@Override
	public void afterJoin() {
		// System.out.println("나갈때는 .. 무슨 말하려는 지 알지? ㅎ");
	}
}

중간에 해당하는 클래스 정의후에

해당 클래스의 구현하고 싶은 행위만 선택한다

public class HelloJoinMember extends JoinMid {

	@Override
	public void preJoin() {
		System.out.println("들어 올떄는 마음대로지만");
	}
}

선택

HelloJoinMember helloJoinMember = new HelloJoinMember();
helloJoinMember.preJoin();

JAVA8 (메서드) default와 static의 등장

java8부터 default 메서드와 static 메서드를 등장시켰다

따라서 interface 자체에서도 구현부를 동시에 지닐 수 있게된 것이다

public interface Java8Interface {
	void method();

	default void defaultMethod() {
		System.out.println("this is default method");
	}

	static void staticMethod() {
		System.out.println("this is static method");
	}
}
public class Java8Impl implements Java8Interface {
	@Override
	public void method() {
		System.out.println("this is method");
	}
}
public class InterfaceMain {
	public static void main(String[] args) {
		new Java8Impl().method();
		new Java8Impl().defaultMethod();
		Java8Interface.staticMethod();
	}
}

다만 static 메서드는 구현부에서 호출할 수 없다

Java8Interface.staticMethod();

와 같은 호출이 안 되고

인터페이스에서 바로 호출해야 한다

Java8Impl.staticMethod();

왜 저런 메서드가 생겼는가?

예를들어 ListMap같은 자료형에 추가적인 기능을 필요로 한다고 하였을 때

어떤 한 메서드를 추가하게 되면 필수적으로 구현해야하기 때문에 모든 자손 구현체들이 컴파일 에러가 떨어진다..

인터페이스를 구현하고 있는 자손 클래스들에게 하위 호환성을 지키기 위하여 만들었다고 볼 수있다

image

ListforEach 메서드도 8버전 이후 default가 등장하면서 생겼다

JAVA9 (메서드) private과 private static의 등장

public interface Java9Interface {
	default void defaultMethod() {
		privateMethod();
		privateStaticMethod();
	}

	private void privateMethod() {
		System.out.println("this is private method");
	}

	private static void privateStaticMethod() {
		System.out.println("this is private static method");
	}
}
public class Java9Impl implements Java9Interface {
}
public class InterfaceMain {
	public static void main(String[] args) {
		new Java9Impl().defaultMethod();
	}
}

두 인터페이스를 상속받는다면

두 인터페이스 중 구현할 내용을 취사선택할 수 있다

실행부

JoinImpl join = new JoinImpl();
join.preJoin();
join.afterJoin();
public interface JoinGroup {
	default void preJoin() {
		System.out.println("그룹에 가입 전");
	}

	default void afterJoin() {
		System.out.println("그룹에 가입 후");
	}
}
public interface JoinMember {
	default void preJoin() {
		System.out.println("회원 가입 전");
	}

	default void afterJoin() {
		System.out.println("회원 가입 후");
	}
}
public class JoinImpl implements JoinGroup, JoinMember {
	@Override
	public void preJoin() {
		JoinGroup.super.preJoin();
		JoinMember.super.preJoin();
	}

	@Override
	public void afterJoin() {
		JoinGroup.super.afterJoin();
		JoinMember.super.afterJoin();
	}
}

인터페이스들끼리도 상속이 된다

public interface Join {
	default void preJoin() {
		System.out.println("Join 클래스의 preJoin");
	}
}
public interface JoinMember extends Join {
	default void preJoin() {
		System.out.println("회원 가입 전");
	}
	...
}

추상 클래스와 인터페이스

  • 추상 클래스는 IS-A 관계이고
    • TV는 가전제품이다
Tv extends ElectronicProduct { }
  • 인터페이스는 HAS-A 관계이다
    • TV는 영상을 보여줄 수 있다
    • TV는 소리를 재생시킬 수 있다
Tv implements Video, Audio { }

Lambda 와 인터페이스를 이용한 Custom 계산기

수업중에 나온 프로그램인데 한번 모방해보았다 (1:44) https://www.youtube.com/watch?v=v2BXL6SYaBc&list=PLfI752FpVCS96fSsQe2E3HzYTgdmbz6LU&index=16

public interface CustomCalculator {

	default int addEvenNumbers(int... nums) {
		return add(x -> x % 2 == 0, nums);
	}

	default int addOddNumbers(int... nums) {
		return add(x -> x % 2 == 1, nums);
	}

	private int add(IntPredicate predicate, int... nums) {
		return IntStream.of(nums)
			.filter(predicate)
			.reduce((a, b) -> a + b)
			.getAsInt();
	}
}
public class CustomCalculatorImpl implements CustomCalculator {
}
private static void test3() {
	CustomCalculatorImpl calculator = new CustomCalculatorImpl();
	int[] nums = {1, 2, 3, 4};
	// odd sum = 4
	// even sum = 6
	int oddSum = calculator.addOddNumbers(nums);
	System.out.println("oddSum = " + oddSum);
	int evenSum = calculator.addEvenNumbers(nums);
	System.out.println("evenSum = " + evenSum);
}

추상클래스는 그럼 필요 없는고야?

위 질문은 인터페이스가 추상클래스의 모든 기능을 대체할 수 있는가로 바뀐다

그렇지는 않다

private String name = "foo";

메서드가 아닌 위와 같은 private 필드는 지원해주지 않는다 !

위와 같은 경우에는 추상 클래스를 사용하면 해결할 수 있다




© 2020.12. by 따라쟁이

Powered by philz