ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 인터페이스
    BackEnd/자바 2021. 1. 9. 12:14

     

    • class는 인터페이스를 implments 키워드를 통해 상속받을 수 있다. 하지만 인터페이스가 인터페이스를 상속할 땐 class 끼리 상속하는 것과 동일하게 extends 를 사용한다.

    - 모든 멤버변수는 public static final 이어야 하며, 이를 생략할 수 있다.

    - 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다.

    - 인터페이스는 객체의 타입으로만 사용된다.

    - 인터페이스에는 추상 메소드만 존재한다.   자바8부터 default, static 으로 method 구현 가능 

    - 인터페이스의 상수는 private으로 만들 수 없다  자바 9 부터 private method, private static method 가능 

    interface 안에서 default 와 static 으로 선언하면 메서드를 구현할 수 있다.

    public interface Bank {
    	
      
    	public int MAX_INTEGER = 1000000;
    	
    	public void withDraw(int price) ;
    	
    	public void deposit(int price) ;
    	
    	default String Auth() {
    		return "default Auth method";
    	}
    	
    	default int calculate(int a,int b) {
    		return a+b;
    	}
    	
    	public static int dormancyAcc() {
    		System.out.println("static dormancyAcc");
    		return 30;
    	}
    }
    

     

    인터페이스를 상속하면 자동으로 ovverride 되는 메서스는 추상 메서드인 withDraw 와 deposit 만 나오지만

    default 메서드인 Auth 도 override 를 할 수 있다.

    또 override 한 deposit 안에서 default 인 calculate 도 호출해 사용해보고,

    myBank 에서 가지고 있는 메서드에서 인터페이스 Bank 의 static 메서드인 dormacyAcc 를 호출해보기도 하였다.

    public class myBank implements Bank {
    
    	private int myacc = 1000;
    	@Override
    	public void withDraw(int price) {
    		System.out.println("implements 하면 withDraw 만 자동 override");
    		System.out.println("Bank 에 있는 상수 " + MAX_INTEGER);
    		
    	}
    	
    	@Override
    	public String Auth() {
    		return Bank.super.Auth();
    	}
    
    	@Override
    	public void deposit(int price) {
    		int value = calculate(price,myacc); //Bank 의 default 메서드 사용
    		System.out.println(value);
    		
    	}
    	
    	public void useStatic() {
    		Bank.dormancyAcc(); //Bank 의 static 메서드 사용
    	}
    
    }
    

     

    • 인터페이스가 변경이 되면, 인터페이스를 구현하는 모든 클래스들이 해당 메소드를 구현해야 하는 문제가 있다. 이런 문제를 해결하기 위하여 인터페이스에 메소드를 구현해 놓을 수 있도록 하였다.
    • 인터페이스에 static 메소드를 선언함으로써, 인터페이스를 이용하여 간단한 기능을 가지는 유틸리티성 인터페이스를 만들 수 있게 되었다.

    ※ 다이아몬드 문제 

    다중 상속을 지원하게 되면 하나의 클래스가 여러 상위 클래스를 상속 받을 수 있다. 이런 특징 때문에 발생하게 되는 문제를  '다이아몬드 문제' 라고 한다.

    GrandParent이라는 클래스가 myMethod() 라는 이름의 메소드를 가지고 있는데,

    Father 와 Mother 가 이를 각각 상속받는다. 

    그런데 Father 와 Mother 둘 다 상속받은 Child 클래스 입장에서는 양쪽 부모에 동일한 메서드가 있기때문에 충돌이 발생한다.

    기존 인터페이스에서는 기능만 선언하기 때문에 이런 문제가 발생할 여지가 없었지만 , default 로 메서드 내용을 선언할 수 있기 때문에 충돌할 수 있다.

    =>  컴파일 오류

     Duplicate default methods named ccc with the parameters () and () are inherited from the types Father and Mother

    public interface GrandParent {
    
    	default void myMethod(){
            System.out.println("GrandParent");
        };
        
    }
    
    public interface Father extends GrandParent{
    
    	@Override
    	default void myMethod(){
            System.out.println("Father");
        };
    }
    
    public interface Mother extends GrandParent{
    
    	@Override
    	default void myMethod() {
    		 System.out.println("Mother");
    	}
    }
    
    public class Child implements Mother,Father{
    
    }
    
    => Duplicate default methods named ccc with the parameters () and () are inherited from the types Father and Mother

     

    Child 에 GrandParent 와 Mother 를 implements 하고 myMethod 를 실행하니 

    Mother 에 있는 myMethod 가 실행되었다.

    public interface GrandParent {
    
    	default void myMethod(){
            System.out.println("GrandParent");
        };
        
    }
    
    public interface Mother extends GrandParent{
    
    	@Override
    	default void myMethod() {
    		 System.out.println("Mother");
    	}
    }
    
    public class Child implements GrandParent,Mother{
    	
    }
    
    public class Test {
    
    	public static void main(String[] args) {
    
    		Child c = new Child();
    		c.myMethod(); //Mother
    	}
    }
    

     

    자바 9부터 인터페이스 private method 와 private static method 구현이 가능하다. (private 변수는 안됨)

    public interface Bank {
    	
    	private int calculate2(int a) {
    		int interest = 300;
    		return interest + a;
    	}
    	
    	private static int calculate3(int a) {
    		return a;
    	}
    
    }

     

     

    • 인터페이스 구현 

    - 인터페이스  Bank 를 클래스 myBank 의 타입으로 구현

    public class Test {
    
    	public static void main(String[] args) {
    		
    		Bank bank = new myBank();
    		bank.withDraw(1000);
    		String auth = bank.Auth();
    		System.out.println(auth);
    		
    		int value = Bank.dormancyAcc();
    		System.out.println(value);
    
    	}
    }
    

    -인터페이스 직접 override 해서 구현 

    public class Test {
    
    	public static void main(String[] args) {
    
    		Bank bank  = new Bank() {
    			
    			@Override
    			public void withDraw(int price) {
    				System.out.println("인터페이스 구현 withDraw");
    				
    			}
    			
    			@Override
    			public void deposit(int price) {
    				System.out.println("인터페이스 구현 deposit");
    				
    			}
    		};
    		
    		bank.withDraw(2000);
    		bank.deposit(1000);
    	}
    }
    

     

    -인스턴스 레퍼런스와 클래스 타입 레퍼런스의 차이 

    public class myBank implements Bank {
    
    	private int myacc = 1000;
    	@Override
    	public void withDraw(int price) {
    		System.out.println("implements 하면 withDraw 만 자동 override");
    		System.out.println("Bank 에 있는 상수 " + MAX_INTEGER);
    		
    	}
    
    	@Override
    	public void deposit(int price) {
    		int value = calculate(price);
    		System.out.println(value);
    		
    	}
    	
    	public void useStatic() {
    		Bank.dormancyAcc();
    	}
    }

    Interface Bank 를 타입으로 구현하면 class myBank 에 구현한 메서드는 호출할 수 없고,

    Bank 안에 있는 메서드만 가능하다.

    하지만  class myBank 를 타입으로 구현하면  Bank와 myBank 에 구현한 메서드를 모두 사용 가능하다.

    public class Test {
    
    	public static void main(String[] args) {
    	
    		// 인스턴스  레퍼런스 
    		Bank bank = new myBank();
    		bank.withDraw(1000);
    		String auth = bank.Auth();
    		System.out.println(auth);
    		bank.useStatic(); // useStatic is undefined for the type Bank
    		System.out.println("------------------------------");
    
    		//클래스 타입 레퍼런스
    		myBank myBank = new myBank();
    		myBank.useStatic();
    		
    	}
    }
    
    

     

     

    출처:

    programmers.co.kr/learn/courses/5/lessons/241

    kbs0327.github.io/blog/technology/java8-default-interface/

    siyoon210.tistory.com/125

    https://devbox.tistory.com/entry/Java-인터페이스

    반응형

    'BackEnd > 자바' 카테고리의 다른 글

    Enum  (0) 2021.01.31
    예외처리  (0) 2021.01.16
    자바 기초 (패키지, import , classpath, 접근제어자)  (0) 2021.01.01
    중첩클래스의 쓰임 > 이펙티브 자바 아이템 24  (0) 2020.12.26
    상속 , dynamic dispatch  (0) 2020.12.26
Designed by Tistory.