1. 개념
interface 파일
package method;
public interface inter1 {
String userid = "hong";
String username = ""; //이딴건 없음 막코드 빈값으로 상수화된것
public String names(); //무조건 이 형태로 사용
public Integer levels();
public void search();
default void setbox(String id) {
// this.userid = id; //안됨!
}
default String getbox() {
return null;
}
}
class 파일
package method;
//inter1과 연계
public class in1 {
public static void main(String[] args) {
in1_box in = new in1_box();
in.names();
}
}
class in1_box implements inter1{
//같은 이름의 변수가 있을 경우 class와 interface가 별도로 선언됨
String userid = "park"; //interface의 userid와 다른 놈임!
@Override
public String names() {
System.out.println(userid);
System.out.println(inter1.userid); //interface에 선언된 변수값 - 협업할때 가독성 좋음
System.out.println(this.userid); //이 클래스 필드에 없으면 interface에 있는 userid가 나옴
this.userid = "kim";
System.out.println(this.userid);
return null;
}
@Override
public Integer levels() {
return null;
}
@Override
public void search() {
}
}
- interface : 다른 클래스 사이의 중간 매개체 역할을 담당하는 추상 클래스 의미
- abstract와 비슷한 성격을 가지고 있음, 단 모든 메소드를 그룹화 함
- default로 선언한 메소드 외에는 모두 Override를 해야함
- interface의 변수
- 기본으로 final(상수)의 성격
- 선언만하는것도 불가능
- default : interface에서 유일하게 기본 메소드 형태로 활용할 수 있는 선언문
- implements : interface 로드
- extends : abstract 로드
- interface 규칙
1. 필드에 선언한 변수는 상수
2. default 외에는 모두 Override
3. interface에 선언한 메소드를 조금이라도 변화시킬경우 새롭게 Override 해야함 //매개변수 바꾼다던지..
4. interface 필드에 클래스 라이브러리(스캐너,클래스배열 등)를 선언시 null 사용안함 (new로 선언)
5. 즉시실행메소드 사용 불가능 //아예 없음
interface는 핸들링해서 리턴값을 쓰기위한것 그래서 void나 default 잘 안씀
interface를 왜쓰냐면
interface는 부품(큐빅)
ex) 국민, 농협,하나, 신한 은행 -> 농협 점검시 농협을 잠금
빠르게 여러 개발자들이 공유하면서 사용할수있게 명시
언제쓰냐면
- Servlet : abstract
- Spring : abstract
- Spring-boot : interface
인터페이스를 잘 알아둬야 스프링부트에서 편함
2. 확장, 유지보수
interface 파일
package method;
public interface inter2 {
String data[] = {"유재석","강호동","신동엽","정상훈","아이유"};
public void money();
}
interface inter2_2 extends inter2{ //이거 로드하면 inter2를 포함
Integer p = 1000;
public void point();
}
//interface inter2_3 extends inter2_2{}
//이런식으로 extends 많이되면 막코드임 긴급패치해야할때나 간단한거 바꿀때정도 extends사용
class 파일
package method;
import java.util.Arrays;
public class in2 {
public static void main(String[] args) {
in2_box bx = new in2_box();
bx.money();
}
}
//기본 사용
class in2_box implements inter2{
@Override
public void money() {
System.out.println(Arrays.toString(this.data));
}
}
//추가로 interface를 적용한사항을 class에 적용
class in2_box implements inter2_2{
@Override
public void money() {
System.out.println(Arrays.toString(this.data));
}
@Override
public void point() {
}
}
//interface 여러개 적용하여 사용
class in2_box implements inter2, inter1{
@Override
public void money() {
System.out.println(Arrays.toString(this.data));
}
@Override
public Integer levels() {
return null;
}
@Override
public String names() {
return null;
}
@Override
public void search() {
}
}
- 인터페이스에 메소드가 많은데 추가 메소드가 필요할때
- extends 사용 : interface에 추가코드를 이용하여 추가 메소드 및 데이터를 적용
- 유지보수시 이전에쓰던거에 메소드를 추가하면 그거 사용한 클래스파일들이 모두 오류남 //오버라이드가 필수니까
- 그래서 extends를 사용해서 그부분만 교체
- ex) 추천인 추가, 우편번호 6자리에서 5자리로 바뀌었을때 사용했었음
- implements : 여러개의 인터페이스를 로드할 수 있음
- extends : 하나의 가상 class 또는 interface민 로드할 수 있음
- -> abstract의 단점 (굳이 하려면 abstract에 abstract를 extends해서 사용해야함...)
3. 예제
interface 파일1
package method;
//국민은행
public interface inter3 {
String password = "1234";
String bankname = "국민은행";
Integer cg = 500;
public void KB_bank();
}
interface 파일2
package method;
//신한은행
public interface inter4 {
String password = "4321";
String bankname = "신한은행";
Integer cg = 0;
public void SH_bank();
}
class 파일
package method;
import java.util.Scanner;
public class in3 {
public static void main(String[] args) {
Integer bankselect = 1;
allbank ab = new allbank(bankselect);
}
}
class allbank implements inter3, inter4{
String password = ""; //비밀번호
String bankname = ""; //은행명
Integer cg = 0; //수수료
Scanner sc = new Scanner(System.in);
String userpassword = ""; //사용자가 입력한 패스워드
public allbank(Integer bankselect) {
switch (bankselect) {
case 1: //국민
this.KB_bank();
break;
case 2: //신한
this.SH_bank();
break;
default:
System.out.println("해당 은행은 서비스 정지중입니다.");
break;
}
}
@Override
public void KB_bank() { //국민은행 처리 메소드
this.password = inter3.password;
this.bankname = inter3.bankname;
this.cg = inter3.cg;
System.out.printf("%s 패스워드를 입력하세요 : %n", this.bankname);
this.userpassword = this.sc.next();
if(this.password.equals(this.userpassword)) {
System.out.println("입출금 서비스를 선택해주세요");
System.out.println("타은행 수수료는 "+ this.cg);
}else {
System.out.println("패스워드가 다릅니다.");
}
}
@Override
public void SH_bank() { //신한은행 처리 메소드
this.password = inter4.password;
this.bankname = inter4.bankname;
this.cg = inter4.cg;
System.out.printf("%s 패스워드를 입력하세요 : %n", this.bankname);
this.userpassword = this.sc.next();
if (this.password.equals(this.userpassword)) {
System.out.println("입출금 서비스를 선택해주세요");
System.out.println("타은행 수수료는 " + this.cg);
} else {
System.out.println("패스워드가 다릅니다.");
}
}
}
- 만약 신한은행 서비스 종료? 점검?이면 implements 에서 inter4빼고 신한관련 코드를 주석처리
4. 배열 interface
package method;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
//추가 데이터 배열 구조
public class array {
List<String> all = null; //이런 식으로 올려두고 선택하여 사용
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
LinkedList<String> al2 = new LinkedList<String>();
al2.add("홍길동");
al2.add("강감찬");
System.out.println(al2);
List<String> al3 = new ArrayList<String>();
List<String> al4 = new LinkedList<String>();
array_box ab = new array_box();
ab.datacheck(); //ArrayList (순차 데이터 입력 더 빠름)
ab.datacheck2(); //LinkedList (ArrayList보다 느림)
ab.datacheck3(); //ArrayList에 중간에 값 추가 -> 677
ab.datacheck4(); //LinkedList에 중간에 값 추가 ->115 (ArrayList보다 빠름)
}
}
class array_box{
List<Integer> all = null;
long start = System.currentTimeMillis();
long end = 0;
public void datacheck() {
this.all = new ArrayList<Integer>();
int f = 1;
do {
this.all.add(f);
f++;
}while(f<100000);
this.end = System.currentTimeMillis();
long total = this.end - this.start;
System.out.println(total);
}
public void datacheck2() {
this.all = new LinkedList<Integer>();
int f = 1;
do {
this.all.add(f);
f++;
}while(f<100000);
this.end = System.currentTimeMillis();
long total = this.end - this.start;
System.out.println(total);
}
public void datacheck3() {
this.all = new ArrayList<Integer>();
int f = 1;
do {
this.all.add(f);
if(f>=800) {
this.all.add(800,100);
}
f++;
}while(f<100000);
this.end = System.currentTimeMillis();
long total = this.end - this.start;
System.out.println(total);
}
public void datacheck4() {
this.all = new LinkedList<Integer>();
int f = 1;
do {
this.all.add(f);
if(f>=800) {
this.all.add(800,100);
}
f++;
}while(f<100000);
this.end = System.currentTimeMillis();
long total = this.end - this.start;
System.out.println(total);
}
}
- List (부모 interface) : ArrayList, LinkedList (자식 class) 선택하여 사용
- 중간에 넣냐 vs 순차적으로 넣냐
- ArrayList, LinkedList 사용법 동일
- 속도 차이 많이남!
- ArrayList : 순차적으로 데이터를 입력 또는 출력을 할 경우 속도가 빠름
- 순차적으로 넣을때
- LinkedList : 데이터를 검색 또는 기존 데이터에서 추가 데이터를 중간값을 처리할 경우 속도가 빠름
- 검색할때 (노드를 확인하며 데이터 처리)
- ArrayList : 순차적으로 데이터를 입력 또는 출력을 할 경우 속도가 빠름
- 인터페이스를 올려놓고 어떤 클래스배열을 사용할지 선택 !
5. Map
package method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class map1 {
public static void main(String[] args) {
map1_box mb = new map1_box();
mb.box();
mb.box2();
}
}
class map1_box{
List<String> all = null;
Map<String,String> all2 = null;
//이런식으로 인터페이스를 선언해서 사용할때 고르는것이 좋음!!!!
//map을 이용하여 사용하는 방식
public void box() {
HashMap<String, String> map1 = new HashMap<>(); //<키, 밸류>
map1.put("product1", "냉장고");
map1.put("product2", "키보드");
map1.put("product3", "마우스");
map1.put("product2", "모니터");
System.out.println(map1); // 각각의 키 데이터 배열 출력
System.out.println(map1.get("product3")); //등록된 key이름을 넣어야 데이터 출력됨
System.out.println(map1.keySet()); //등록된 key이름만 출력
//Map (interface)를 활용하여 다양한 클래스를 로드 (HashMap, Hashtable, TreeMap)
//사용법은 모두 동일
Map<String,String> map2 = new HashMap<String,String>();
}
//key 배열 + ArrayList => 1차 순차 클래스 배열을 2차 키배열로 전환
public void box2() {
ArrayList<Integer> one = new ArrayList<>();
HashMap<String, ArrayList<Integer>> data = new HashMap<>();
one.add(10);
one.add(500);
one.add(150);
one.add(null);
data.put("point", one);
System.out.println(data); //전체 배열 출력
System.out.println(data.get("point").get(1)); //해당 키에 맞는 데이터값
System.out.println(data.get("point").size()); //해당 키의 데이터 개수
//foreach : 대표키를 설정한 후 해당 대표키에 적용된 데이터를 반복문으로 출력
for(Integer no : data.get("point")) { //키에 맞는 자료형을 써야함
System.out.println(no);
}
data.remove("point"); //해당 키와 데이터를 모두 삭제
data.get("point").clear(); //해당 키의 데이터만 모두 삭제
data.get("point").remove(1); //해당 키 그룹의 데이터 특정값 삭제
data.get("point").set(2, 250); //해당 키 그룹의 데이터 값 변경
one.set(2, 300); //1차 ArrayList 배열의 인덱스의 값 변경 //윗줄과 결과 동일
System.out.println(data);
}
}
- Map(interface) : HashMap, Hashtable, TreeMap (class) //사용법 모두 동일
- 가장많이 사용하는 순서 HashMap > ArrayList > LinkedList
- Map 클래스 배열 <key, value>
- put : 데이터를 입력 //동일한 키를 사용시 기존 데이터가 삭제되고 새로운 값이 들어감
- clear : 키는 그대로 키값 모두 삭제
- remove : 키와 키값 모두 삭제
- set : 값 설정
package method;
import java.util.Hashtable;
import java.util.Map;
//Hashtable 사용법
public class map2 {
public static void main(String[] args) {
Map<Integer, String> data = new Hashtable<>();
data.put(1, "HTML");
data.put(2, "CSS");
data.put(3, "Javascript");
data.put(4, "Java"); // 오류빨간줄은 안나오지만 오류남 -> 병렬처리라서 null 사용 불가능 -> ""로 사용
//HashMap은 null가능
System.out.println(data);
int w = 0;
while(w<data.keySet().size()) { //키 개수만큼 반복문을 돌려 데이터 출력
System.out.println(data.get(w+1)); //해당 키에 맞는 데이터를 출력
w++;
}
}
}
- Hashtable : 데이터 병렬처리에 사용하는 키배열 - null X
- HashMap : 데이터 단일처리에 사용하는 키배열 - null O
😊응용문제
{"hong","kim","park","jang"}
{"M","W","W","M"}
해당 원시배열을 이용하여 다음 결과처럼 출력되는 키배열 코드 작성
{userid=["hong","kim","park","jang"], gender=["M","W","W","M"]}
package method;
import java.util.*;
public class map3 {
public static void main(String[] args) {
map3_test mt = new map3_test();
map3_t mtt = new map3_t();
mtt.keyarray();
}
}
//내 코드
class map3_test{
String id[] = {"hong","kim","park","jang"};
String gen[] = {"M","W","W","M"};
ArrayList<String> arr = null;
Map<String,ArrayList<String>> map = null;
public map3_test(){
this.map = new HashMap<>();
this.arr = new ArrayList<>(Arrays.asList(this.id));
this.map.put("userid", this.arr);
this.arr = new ArrayList<>(Arrays.asList(this.gen));
this.map.put("gender", this.arr);
System.out.println(map);
}
}
//선생님 코드
class map3_t{
String data[][] = {
{"hong","kim","park","jang"},
{"M","W","W","M"}
};
String keydata[] = {"userid", "gender"};
public void keyarray() {
Map<String,List<String>> userdata = new HashMap<>();
int w = 0;
do {
List<String> db = new ArrayList<String>();
for(int f = 0;f<this.data[0].length;f++) { //4
db.add(this.data[w][f]);
}
userdata.put(this.keydata[w], db);
w++;
}while(w <this.keydata.length); //2
System.out.println(userdata);
}
}
⭐️Map 생성시 주의사항 : 1차 클래스 배열에 대한 객체에 따른 인스턴스명을 체크!
- Map 안에 배열이 들어가는 경우 List 선언하고 ArrayList 인스턴스를 쓸때
- Map안에 ArrayList가 아니라 List로 넣어야함