public interface 인터페이스이름 { ... }
public interface 취업의길 {
void 공부해라();
}
public interface User {
public static final 필드타입 상수명 = 값;
String FIRST_NAME = "KIM" // 또는
public static final String FIRST_NAME = "KIM" // 은 같다.
}
public interface User {
// 디폴트 메서드
[public] default 리턴타입 메서드이름(매개변수, ...) { ... }
// 예시
public default void setStatus(Status status) {
if(statis == Status.ACTIVE) {
System.out.println("사용자가 활성화 됨");
return;
}
System.out.println("사용자 비활성화됨");
}
}
public interface User {
// 추상메서드
[public abstract] 리턴타입 메서드이름(매개변수, ...) { ... };
//예시
String endMoney(Money money); // 와
public abstract String sendMoney(Money money); //는 같다.
}
public interface User {
// 정적메서드
[public] static 리턴타입 메서드이름(매개변수, ...) { ... }
// 예시
public static void printFirstName() {
System.out.println("나의 이름은" + fistName + "입니다.");
}
}
public class 구현클래스이름 implements 인터페이스이름 {
// 인터페이스의 추상 메서드를 구현한 실체 메서드를 선언하는 부분
}
// 인터페이스
public interface User {
public static final String FIRST_NAME = "Ryan";
public abstract String sendMoney(Money money);
public default void setStatus(Status status) {
if(status == Status.ACTIVE) {
System.out.println("사용자가 활성화 되었습니다");
return;
}
System.out.println("사용자가 비활성화 되었습니다");
}
public static void printFirstName() {
System.out.println("나의 이름은 " + firstName + "입니다.");
}
}
// 구현체
public class Recipient implements User {
// 추상메서드는 다음처럼 실체 메서드를 정의해야함 !
public String sendMoney(Money money) {
thirdpartyApi.send(money.getType(), money.getAmount());
return Status.SUCCESS.name();
}
// 디폴트 메서드는 재정의 해도 되고 안해도 된다
}
public abstract class Recipient implements User {
}
// 유저 인터페이스를 구현한 구현 클래스 Recipient
public class Recipent implements User { ... }
// 유저 인터페이스를 구현한 구현 클래스 Sender
public class Sender implements User { ... }
User user = new Recipient();
User user = new Sender();
public class 구현클래스이름 implements 인터페이스이름1, 인터페이스이름2 {
// 인터페이스의 추상 메서드를 구현한 실체 메서드를 선언하는 부분
}
User user = new User() {
public String sendMoney(Money money) {
thirdpartyApi.send(money.getType(), money.getAmount());
return Status.SUCCESS.name();
}
@Override
public default void setStatus(Status status) {
if(status == Status.ACTIVE) {
System.out.println("수취인이 활성화 되었습니다");
return;
}
System.out.println("수취인이 비활성화 되었습니다");
}
};
User sender = new Sender(); // 유저 인터페이스 참조변수 sender에 Sender 객체의 번지 저장
User recipient = new Recipient(); // 유저 인터페이스 참조변수 recipient에 Recipient() 객체의 번지 저장
public class TestClass {
// 1.클래스의 필드
User user = new Recipient();
// 2.생성자의 파라미터
TestClass(User user) {
this.user = user;
// 3.생성자의 로컬변수
User recipient = new Recipient();
}
// 4.메서드의 파라미터
void methodA(User user) {
...
}
void methodB() {
// 5.메서드의 로컬변수
User user = new Recipient();
}
}
// 이 예시로 동일하게 진행하겠습니다.
public interface User {
public static final String FIRST_NAME = "Ryan";
public abstract String sendMoney(Money money);
public default void setStatus(Status status) {
if(status == Status.ACTIVE) {
System.out.println("사용자가 활성화 되었습니다.");
return;
}
System.out.println("사용자가 비활성화 되었습니다.");
}
public static void printFirstName() {
System.out.println("나의 이름은 " + firstName + "입니다.");
}
}
User.FIRST_NAME
//위 방식으로 상수는 클래스의 상수와 같은 방식으로 사용할 수 있습니다.
public class Example {
psvm() {
User user = null;
user = new Recipient();
user.sendMoney(new Money(1000L)); // Recipient가 1000원을 보냈다.
user = new Sender();
user.sendMoney(new Money(5000L)); // Sender가 5000원을 보냈다.
}
}
// 일반 예
public class Example {
psvm() {
User user = null;
user = new Recipient();
user.setStatus(Status.ACTIVE); // 사용자가 활성화 되었습니다.
user = new Sender();
user.setStatus(Status.INACTIVE); // 사용자가 비 활성화 되었습니다.
}
}
// 재정의한 예
public class Recipient implements User {
@Override
public default void setStatus(Status status) {
if(status == Status.ACTIVE) {
System.out.println("수취인이 활성화 되었습니다.");
return;
}
System.out.println("수취인이 비활성화 되었습니다.");
}
}
public class Sender implements User {
@Override
public default void setStatus(Status status) {
if(status == Status.ACTIVE) {
System.out.println("송신자가 활성화 되었습니다.");
return;
}
System.out.println("송신자가 비활성화 되었습니다.");
}
}
public class Example {
public static void main(String[] args) {
User user = null;
user = new Recipient();
user.setStatus(Status.ACTIVE); //수취인이 활성화 되었습니다.
user = new Sender();
user.setStatus(Status.INACTIVE); // 송신자가 비활성화 되었습니다.
}
}
public class Example {
public static void main(String[] args) {
User.printFirstName(); // 나의 이름은 Ryan입니다.
}
}
Interface i = new ImplementObjectA();
// i를 수정해도
i = new ImplementObjectB();
// 변경이 없습니다.
i.method1();
i.method2();
// 2. 상속에서도 부모 클래스 타입의 변수에 어떤 자식 객체를 대입하냐에 따라서 객체의 메서드 실행 결과는 달라질 수 있습니다. 결국 상속에서도 인터페이스와 마찬가지로 다형성을 구현하고 있습니다.
ParentClass p = new ChildClassA();
// 자식 객체로 대입이 가능하다. (다형성)
p = new ChildClassB();
// 다만, ParentClass안에 구현된 메서드만 호출이 가능
p.methodAInParent();
p.methodBInParent();
// 3. 인터페이스가 매개변수로 쓰이는 경우
public class UserService {
// User 인터페이스를 매개변수로 사용.
public void printUserType(User user) {
user.printType();
}
}
// User 인터페이스를 구현한 구현 객체 Recipient, Sender를 매개변수로 사용
userService.printUserType(new Recipient()); // 수취인입니다.
userService.printUserType(new Sender()); // 송신자입니다.
// 인터페이스 A
// 인터페이스 A를 구현한 클래스 B
// 인터페이스 A를 구현한 클래스 C
// 클래스 B를 상속한 자식 클래스 D
// 클래스 C를 상속한 자식 클래스 E
// B, C, D, E에는 printClassName를 자기 클래스 이름을 출력하는 로직이 재정의 되어있다고 가정합니다.
A a1 = new B(); // OK
a1.printClassName(); // B 클래스입니다.
A a2 = new C(); // OK
a2.printClassName(); // C 클래스입니다.
A a3 = new D(); // OK
a3.printClassName();
// 기본은 상속된 printClassName가 호출됩니다. "B 클래스입니다."
// 만약 클래스 D의 printClassName를 재정의하면 "D 클래스입니다."가 됩니다.
A a4 = new E(); // OK
a4.printClassName();
// 기본은 상속된 printClassName가 호출됩니다. "C 클래스입니다."
// 만약 클래스 E의 printClassName를 재정의하면 "E 클래스입니다."가 됩니다.
// 인터페이스
public interface User {
void printType();
}
// 구현 클래스 "Recipient"
public class Recipient implements User {
@Override
public void printType() {
System.out.println("수취인입니다.");
}
}
// 구현 클래스 "Sender"
public class Sender implements User {
@Override
public void printType() {
System.out.println("송신자입니다.");
}
}
public class Mail {
public void printUserType(User user) {
user.printType();
}
}
public class Main {
public static void main(String[] args) {
Mail mail = new Mail();
mail.printUserType(new Recipient()); // User user = new Recipient(); "수취인입니다."
mail.printUserType(new Sender()); // User user = new Sender(); "송신자입니다."
}
}
Recipient recipient = new Recipient();
User user = new Recipient();
Recipient recipient = (Recipient) user;
// 인터페이스
public interface User {
void printType();
}
// 구현 클래스 "Recipient"
public class Recipient implements User {
private static final String COUNTRY = "KOREA";
@Override
public void printType() {
System.out.println("수취인입니다.");
}
// 추가로 메서드 구현
public void printCountry() {
System.out.println("국가는 " + COUNTRY + "입니다.");
}
}
public class Main {
public static void main(String[] args) {
User user = new Recipient();
user.printType(); // "수취인입니다."
user.printCountry(); // 호출이 불가능합니다.
//
Recipient recipient = (Recipient) user;
recipient.printType(); // "수취인입니다."
recipient.printCountry(); // "국가는 KOREA입니다."
}
}
User user = nwe Recipient();
User user = new Recipient();
Sender sender = (Sender) user; // 에외 발생
User user = new Recipient();
if( user instanceof Recipient ) { // user 변수에 담긴 객체가 Recipient 타입이면,
Recipient recipient = (Recipient) user;
}
public interface child1 extends present1, presnet2 { ... }
하위인터페이스 변수 = new 구현클래스();
상위인터페이스1 변수 = new 구현클래스();
상위인터페이스2 변수 = new 구현클래스();
public interface InterfaceA {
public void methodA();
}
public interface InterfaceB {
public void methodB();
}
public interface InterfaceC extends ItnerfaceA, InterFaceB {
public void methodC();
}
public class ImplementationClassC implements InterFaceC {
public void methodA() {...}
public void methodB() {...}
public void methodC() {...}
}
psvm {
ImplementationClassC implC = new ImlimentationC();
InterfaceA iA = implC;
iC.methodA(); // OK
iC.methodB(); // NO
iC.methodC(); // NO
InterfaceB iB = implC;
iC.methodA(); // NO
iC.methodB(); // OK
iC.methodC(); // NO
InterfaceC iC = implC;
iC.methodA(); // OK
iC.methodB(); // OK
iC.methodC(); // OK
}