2021. 04. 08(목) TIL

Dylan·2021년 4월 8일
0

Java

Is a 관계 , Has a 관계

인터페이스(Interface)

  • 인터페이스하위 클래스에 특정한 메소드가 반드시 존재하도록 강제할 때 사용한다.
  • 인터페이스는 모든 하위 클래스의 사용법(메소드의 실행방법)을 통일시키는 표준으로 사용된다.
  • 하위 클래스는 인터페이스에 정의된 추상화된 메소드를 구현(재정의)할 책임이 있다.
  • 하위 클래스는 동시에 여러 개의 인터페이스를 구현할 수 있다.

인터페이스의 특징

  • 인터페이스는 상수, 추상메소드로 구성된다.
  public interface Sample {
    public static final 데이터타입 상수명 =;
    public abstract 반환타입 추상메소드명(타입 변수, 타입변수, ...);
  }
  • 자바 8버전부터 정적 메소드디폴트 메소드가 추가되었다.
  • 인터페이스끼리는 다중 상속이 가능하다.
  • 인터페이스에서 정의하는 모든 추상메소드는 public 접근제한을 가진다.
  • 인터페이스에서 정의하는 모든 추상메소드는 접근제한자와 abstract 키워드를 생략할 수 있다.
  • 인터페이스는 new 키워드를 사용해서 객체 생성할 수 없다.
  • 인터페이스 타입의 참조변수는 하위 객체를 참조할 수 있다.

인터페이스 정의하기

  public interface Phone {
    // 상수
    public static final String MOBILE_TELECOMMUNICATION = "LTE";
    // 추상 메소드(모든 하위 클래스 반드시 존재해야하는 기능은 추상메소드로 추상화)
    void call();
    void sms();
    // 디폴트 메소드(모든 하위클래스가 동일하게 구현하는 기능은  디폴트 메소드로 인터페이스에서 구현)
    default void on() {
      전원 켜기
    }
    default void off() {
      전원 끄기
    }
  }

클래스에서 인터페이스 구현하기

  • 클래스는 implements 키워드를 사용해서 구현할 인터페이스를 지정한다.

  • 한 개의 인터페이스 구현하기

      public interface Calculatable {
        void addNumber(int x, int y);
        int plus();
        int minus();
      }
    
      public class SimpleCalculator implements Calculatable {
        int x;
        int y;
        public void addNumber(int x, int y) {
          this.x = x;
          this.y = y;
        }
        public int plus() {
          return x + y;
        }
        public int minus() {
          return x - y;
        }
      }
  • 한 개 이상의 인터페이스 구현하기

      // 모든 하위 클래스가 반드시 포함해야 되는 기능을 정의한 인터페이스
      public interface phone {
        void call();
        void sms();
      }
      // 인증 기능을 지원하는 모든 하위 클래스가 반드시 포함해야 되는 기능을 정의한 인터페이스
      public interface Authenticatable {
        void auth();
      }
      // 인터넷 기능을 지원하는 모든 하위 클래스가 반드시 포함해야 되는 기능을 정의한 인터페이스
      public interface InternetAvailable {
        void web();
      }
    
      // Phone 인터페이스를 구현한 NormalPhone
      public class NormalPhone implements Phone {
        String tel;
        public void call() {
          통화하기
        }
        public void sms() {
          문자보내기
        }
      }
      // NormalPhone 클래스를 상속받고, Authenticatable인터페이스와 IntenetAvailable인터페이스를 구현하는 클래스
      public class SmartPhone extends NormalPhone implements Authenticatable, InternetAvailable {
        String ip;
        public void auth() {
          사용자 인증하기
        }
        public void web() {
          인터넷하기
        }
      }

인터페이스의 활용

  • 인터페이스를 이용해서 하위 클래스의 사용법을 통일시킬 수 있다.
  • 인터페이스를 이용하면 클래스 개발자와 클래스 사용자의 협업이 쉬워진다.
  • 개발시간을 단축시킬 수 있다.
  • 표준화가 가능하다
    • 프로젝트에서 사용되는 구현클래스에 대한 기본 틀(기본 설계도)을 인터페이스로 작성한다.
    • 개발들에게 인터페이스를 기본 설계도로 삼아서 구현하게 하면 일관되고, 정형화된 프로그램 개발이 가능하다.
  • 인터페이스를 사용하면 클래스간의 관계를 느슨하게 유지할 수 있다.
    • 클래스간의 관계가 느슨하면 다른 클래스로 교체할 때, 수정할 코드가 줄어든다.

package day4;

public class User {

	private String id;
	private String name;
	
	public User () {}

	public User(String id, String name) {
		this.id = id;
		this.name = name;
	}

	public String getId() {
		return id;
	}

	public String getName() {
		return name;
	}
	
}
package day4;

public class UserArrayRepository implements UserRepository {

	private User[] db = new User[100];
	private int position = 0;
	
	public UserArrayRepository() {
		db[position++] = new User("hong", "홍길동");
		db[position++] = new User("kim", "김유신");
		db[position++] = new User("lee", "이순신");
	}
	
	@Override
	public void saveUser(User user) {
		db[position++] = user;
		
	}

	@Override
	public void removeUser(String id) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void updateUser(User user) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public User getUserById(String id) {
		User user = null;
		
		for (User item : db) {
			if (item == null) {
				break;
			}
			
			if (item.getId().equals(id) ) {
				user = item;
				break;
			}
		}
		
		return user;
	}
	
}
package day4;

public class UserFileRepository implements UserRepository {

	@Override
	public void saveUser(User user) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void removeUser(String id) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void updateUser(User user) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public User getUserById(String id) {
		// TODO Auto-generated method stub
		return null;
	}

	
}
package day4;

public class UserManager {
	
	// 사용자정보 등록 / 삭제 / 변경 / 조회 기능을 제공하는 객체에 대한 표준(인터페이스)사용
	private UserRepository repo;
	
	public void setRepo(UserRepository repo) {
		this.repo = repo;
	}
	
	public UserManager() {}

	public UserManager(UserRepository repo) {
		super();
		this.repo = repo;
	}

	// 새 사용자 등록하기
	public void addNewUser(String id, String name) {
		User savedUser = repo.getUserById(id);
		if (savedUser != null) {
			System.out.println("동일한 아이디로 가입한 사용자가 이미 존재합니다.");
			return; // 메소드 실행 끝내기
		}
		User user = new User(id, name);
		repo.saveUser(user);
	}
	
	// 사용자 정보 삭제하기
	public void deleteUser(String id) {
		User savedUser = repo.getUserById(id);
		if (savedUser == null) {
			System.out.println("지정된 아이디의 사용자가 존재하지 않습니다.");
			return;
		}
		repo.removeUser(id);
	}
	
	// 사용자 정보 조회하기
	public User findUser(String id) {
		User savedUser = repo.getUserById(id);
		
		return savedUser;
	}
}
package day4;

public class UserManagerApp {

	public static void main(String[] args) {
		// UserRepository의 구현객체 생성하기
		UserArrayRepository arrayRepo = new UserArrayRepository();
				
		
		// UserManager객체 생성
		UserManager userManager = new UserManager();
		// Setter 메소드를 이용해서 UserRepository구현 객체를 UserManager의 repo변수에 전달하기
		userManager.setRepo(arrayRepo);
		
		System.out.println("### 아이디로 사용자 조회하기");
		User user1 = userManager.findUser("lee");
		
		if ( user1 != null) {
			System.out.println(user1.getId() + ", " + user1.getName());
		} else {
			System.out.println("사용자가 존재하지 않습니다");
		}
		
		System.out.println("## 신규 사용자 등록하기");
		userManager.addNewUser("park", "박혁거세");
		
		System.out.println("### 아이디로 사용자 조회하기");
		User user2 = userManager.findUser("park");
		System.out.println(user2.getId() + ", " + user2.getName());
		
		// UserManager객체 생성, 생성자 메소드를 이용해서 UserRepository구현객체를 UserManager의
		// repo 변수에 전달하기
		UserManager userManager2 = new UserManager(arrayRepo);
	}
}
package day4;

public interface UserRepository {

	/**
	 * 사용자정보를 전달받아서 저장소에 저장한다
	 * @param user 사용자정보가 저장된 User객체
	 */
	void saveUser(User user);
	
	/**
	 * 지정된 아이디의 사용자를 저장소에서 삭제한다
	 * @param id 삭제할 사용자 아이디
	 */
	void removeUser(String id);
	
	/**
	 * 변경된 정보를 포함하고 있는 사용자저보를 전달받아서 저장소에 반영한다
	 * @param user 변경된 사용자 정보를 포함하고 있는 User객체
	 */
	void updateUser(User user);
	
	/**
	 * 지정된 아이디의 사용자 정보를 저장소에서 찾아서 반환한다
	 * @param id 조회할 사용자 아이디
	 * @return 사용자정보를 포함하고 있는 User객체
	 */
	User getUserById(String id);
}

0개의 댓글