22.11.14 인터페이스, 컬렉션프레임워크
p356 다중인터페이스 구현클래스 진행.
클래스인데 인터페이스를 2개이상 구현하면
다중인터페이스 구현클래스라고 함.
교재에서는 스마트TV생성
리모트 컨트롤, 서치가능 인터페이스 구현
기존 텔레비전 클래스 파일을 복사하여 활용!
searchable 인터페이스 존재해야 구현클래스를 만들 수 있다.
고로 p356 인터페이스 생성 필요!!!
15장 컬렉션 프레임 워크 --->게시판 작성 시 많이 씀
컬렉션 -> 리스트계열, 셋계열
그외 맵계열.맵은 컬렉션 자식은 아니다.
List계열 = 순서는 유지한채로 저장, 중복허용
---> 입력된 대로 순차적으로 출력된다. (ex 병원 접수 목록, 병원진료 목록, 식당 웨이팅 목록, 대기목록)
---> 제일 만만하다 ㅎㅎ 많이 쓴다는 뜻
Set 계열 = 순서 유지 안된채로 저장., 중복 허용 안됨.
---> 단순데이터 자장 (ex 반려동물 목록, 우리집에 물건 목록 등등)
---> 조금 불편하다.. 내가 원하는 값 언제 나와? 잘 판단이 안됨.(빈도상 셋이 제일 안씀)
Map 계열 --> DB쪽 개념과 유사하다.
(값인 홍길동은 여러명이어도 상관없지만 고유한 유니크한 데이터 키값은 유일해야한다.주민번호 같은 데이터가 키다)
--->키를 알아야 데이터를 추출 하거나 검색이 가능해서 작업 코드량이 많다.
(키, 값)
(key, value) => 키와 밸류를 한 쌍(pair)로서 같이 묶여서 움직인다.
key ==> 중복허용X, 키명은 유일한 값이어야 한다. => unique
value ==> 중복허용
831123
, 홍길동
801123
, 홍길동
package ch08;
//348
//리모트컨트롤 인터페이스이다.
public interface RemoteControl {
//필드 -> 인터페이스에서는 오직 [public] static final 상수(constant field)가 존재한다. 상수필드만 존재.
//private int a=10;----> 사용할 수 없다.
//Illegal modifier for the interface field RemoteControl.a;
//only public, static & final are permitted
//상수는 대문자로...
//static 필드는 모든 객체에서 공동(공유)으로 사용되는 값
//객체를 생성하지 않고 ==> 객체의 참조주소를 이요하지 않고
//=>클래스명으로 통해서 접근한다.
//=>클래스명.필드명
//static 필드 = 클래스필드 = 정적필드
int MAX_VOLUME = 10; //이런식으로 상수 선언 한것은 아래와 같은 형태이다.자동처리!!!
// public static final int MAX_VOLUME=10;
int MIN_VOLUME = 0;
//생성자-> 인터페이스에서는 생성자 존재하지 않는다.
//RemoteControl(){}
//Interfaces cannot have constructors
//메소드
//[접근제한자][제어자] 리턴유형 메소드명(매개변수리스트); --->X기본형태는 안된다.
// 리턴유형 메소드명(매개변수리스트); //추상메소드 //접제, 제어는 모두 퍼블릭 abstract
// default 리턴유형 메소드명(매개변수리스트); //default메소드//접제,제어 모두 퍼블릭 default
// static 리턴유형 메소드명(매개변수리스트); //static메소드 //접제, 제어는 모두 퍼블릭 static
//리턴유형 메소드명(매개변수리스트); //추상메소드 //접제, 제어는 모두 퍼블릭 abstract
//전원켜기
public abstract void turnOn(); //아래 처럼 생략해도 public abstract로 자동 인식
//void turnOn();
//public void turnOn();
//전원끄기
public void turnOff();
//볼륨조절하기
public abstract void setVolume(int volume);
//추상클래스 추상 메소드는 구현클래스에서 하면된다.
}
package ch08;
//p359
//이 클래스는 RemoteControl interface를 구현한 구현클래스들의 실행클래스이다.
public class RemoteControl_Main {
public static void main(String[] args) {
//안된다는 예시를 보여주기위한 것... 신경쓰지 않아도 된다.
//참조변수선언 및 객체생성
// RemoteControl rc = new RemoteControl();
//Cannot instantiate the type RemoteControl
//생성자가 존재하지 않는 인터페이스에서는 인스턴스화 할 수 없다!!!!!
//컨트롤 누르고 클릭하면 해당 인터페이스로 이동하기는 하지만... 이것은 자바 고유문법이 아닌 그냥 이클립스 기능... 못한다.
// rc.turnOff();
//에러가안나긴 하는데 위에서 에러가 뜨기 때문에.. 객체 생성이 제대로 됐다고 볼 수 없다.. 안된다,
//RemoteControl rc = new RemoteControl();
//인터페이스는 생성자가 없으므로 객체를 생성할 수 없다.
//Cannot instantiate the type RemoteControl
//=>따라서 구현클래스의 객체를 생성하고
//생성된 구련클래스의 객체를 통하여
//필드와 메소드를 이용
//이때 인터페이스의 필드는 static final필드로서 상수이다.
//static키워드로 인해 인터페이스명.상수명에 접근가능
System.out.println(RemoteControl.MAX_VOLUME);
//구현클래스의 객체를 생성
//여기에서는 Television, Audio클래스
Television objTV = new Television();
objTV.turnOn();
objTV.setVolume(100); //맥스볼륨이 10이므로 100을 입력해도 10으로 출력된다.
objTV.turnOff();
System.out.println("-----------------------------------------------");
//Audio 작동!
Audio objAudio = new Audio();
objAudio.turnOn();
objAudio.setVolume(-10); //맥스볼륨이 10이므로 100을 입력해도 10으로 출력된다.
objAudio.turnOff();
System.out.println("-----------------------------------------------");
//다형성 적용시켜보기 // 부모타입 참조변수안에 다양한형태의 자식클래스가 들어갈수 있는것.
//상위클래스명 참조변수 = new 하위클래스명(); 상위클래스만 되는것이 아니라 상위 인터페이스도 가능.
//인터페이스명 참조변수 = new 하위클래스명(); 하위에는 인터페이스 못옴!!!! 그래서 인터페이스가 오면 구현(실체)클래스가 하위클래스 자리에 온다.
//인터페이스명 참조변수 = new 구현(실체)클래스명(); 이렇게 구현!!! 구현(실체)클래스는 생성자가 있으므로
//RemoteControl rc = new Television(); -->이러한 식으로 계속 new해버리면 힙영역 넘쳐난다.. 그래서 함부로 생성 못하게 private으로 막아버린다는데? 이해를 해야할듯.
RemoteControl rc = objTV; // 위에 만들어놓은 텔레비전 객체를 다시 리모트컨트롤 인터페이스타입 객체에 넣는것. 이것과 위에것과 동일!!!
rc.turnOn();
rc.setVolume(60);
rc.turnOff();
System.out.println("--------------------------------------새로 객체 생성---------");
RemoteControl rc2 = new Audio();// -->이러한 식으로 계속 new해버리면 힙영역 넘쳐난다.. 그래서 함부로 생성 못하게 private으로 막아버린다는데? 이해를 해야할듯.
rc2.turnOn();
rc2.setVolume(5);
rc2.turnOff();
System.out.println("--------------------------------------기존 객체 이용---------");
RemoteControl rc3 = objAudio; // 위에 만들어놓은 오디오 객체를 다시 리모트컨트롤 인터페이스타입 객체에 넣는것. 이것과 위에것과 동일!!! //또는 위에 rc1에 그대로 넣어도 무방. RemoteControl rc2 = rc;
rc3.turnOn();
rc3.setVolume(5);
rc3.turnOff();
System.out.println("--------------------------------------위에는 다형성 이용을 해본것... 아래처럼 구현클래스 로 객체 만드는것이 맞다.---------");
SmartTelevision st = new SmartTelevision();// --> 이것이 맞는것..
st.turnOn(); //RemoteControl인터페이스의 추상메소드 재정의한것을 호출
st.setVolume(3); //RemoteControl인터페이스의 추상메소드 재정의한것을 호출
st.search("www.naver.com"); // Searchable인터페이스의 추상메소드 재정의한것을 호출
st.turnOff();//RemoteControl인터페이스의 추상메소드 재정의한것을 호출
Searchable st2 = new SmartTelevision(); //--->이렇게 하면 서치기능만 사용 가능...
}
}
package ch08;
//p351
//이 클래스는 구현클래스이다.
//구현클래스명 implements 인터페이스명1, 인터페이스명2, ~ .........인터페이스명n
public class Television implements RemoteControl {
//구현클래스에서는 인터페이스에서 상속받은 추상클래스를 반드시 구현해야한다.
//=>추상메소드를 반드시 오버라이딩해야한다는 의미!!!! => 메소드 재정의!!!!!
//특정인터페이스를 구현한다고 implements 작성하면 반드시 인터페이스에서 선언한 추상클래스를 오버라이딩해야한다는 멘트가 이클립스에서 제공
/The type Television must implement
* the inherited abstract method
* RemoteControl.setVolume(int)/
//필드
private int volume; //현재볼륨
//추상클래스 추상 메소드는 구현클래스에서 하면된다. 단 위에 Television에 빨간 밑줄이 안가려면 RemoteControl 인터페이스에서 선언한 메소드를 모두 오버라이딩 해야한다.!!!!
//전원켜기 메소드 재정의
public void turnOn() {
System.out.println("TV 전원이 켜졌습니다.");
};
//전원끄기 메소드 재정의
public void turnOff() {
System.out.println("TV 전원이 꺼졌습니다.");
};
//불륨조절하는 메소드를 재정의 하세요.
//MAX_VOLUME과 MIN_VOLUME은 Static이므로
//클래스명.필드명으로 접근
public void setVolume(int volume) {
// if(volume > 클래스명.필드명) {
if(volume > RemoteControl.MAX_VOLUME) {
//제시된 volume이 최대볼륨보다 크면
//최대볼륨으로 현재 volume 으로 설정
this.volume = RemoteControl.MAX_VOLUME;
}else if(volume < RemoteControl.MIN_VOLUME) {
//제시된 volume이 최저볼륨보다 작다면
//최저볼륨으로 현재 volume 으로 설정
this.volume = RemoteControl.MIN_VOLUME;
}else {
//제시된 볼륨이 최저볼륨과 최대볼륨 사이라면
//제시된 볼륨으로 현재 volume으로 설정
this.volume = volume;
}
//위에서 if조건에 따라 설정된 필드값이 출력되어야 하므로
//this.volume을 출력한다.
System.out.println("현재 TV VOLUME은 "+this.volume+" 이다.");
}
}
package ch08;
//p352
//이 클래스는 구현클래스이다.
//구현클래스명 implements 인터페이스명
public class Audio implements RemoteControl {
//구현클래스에서는 인터페이스에서 상속받은 추상클래스를 반드시 구현해야한다.
//=>추상메소드를 반드시 오버라이딩해야한다는 의미!!!! => 메소드 재정의!!!!!
//특정인터페이스를 구현한다고 implements 작성하면 반드시 인터페이스에서 선언한 추상클래스를 오버라이딩해야한다는 멘트가 이클립스에서 제공
/The type Television must implement
* the inherited abstract method
* RemoteControl.setVolume(int)/
//필드
private int volume; //현재볼륨
//추상클래스 추상 메소드는 구현클래스에서 하면된다. 단 위에 Television에 빨간 밑줄이 안가려면 RemoteControl 인터페이스에서 선언한 메소드를 모두 오버라이딩 해야한다.!!!!
//전원켜기 메소드 재정의
public void turnOn() {
System.out.println("Audio 전원이 켜졌습니다.");
};
//전원끄기 메소드 재정의
public void turnOff() {
System.out.println("Audio 전원이 꺼졌습니다.");
};
//불륨조절하는 메소드를 재정의 하세요.
//MAX_VOLUME과 MIN_VOLUME은 Static이므로
//클래스명.필드명으로 접근
public void setVolume(int volume) {
// if(volume > 클래스명.필드명) {
if(volume > RemoteControl.MAX_VOLUME) {
//제시된 volume이 최대볼륨보다 크면
//최대볼륨으로 현재 volume 으로 설정
this.volume = RemoteControl.MAX_VOLUME;
}else if(volume < RemoteControl.MIN_VOLUME) {
//제시된 volume이 최저볼륨보다 작다면
//최저볼륨으로 현재 volume 으로 설정
this.volume = RemoteControl.MIN_VOLUME;
}else {
//제시된 볼륨이 최저볼륨과 최대볼륨 사이라면
//제시된 볼륨으로 현재 volume으로 설정
this.volume = volume;
}
//위에서 if조건에 따라 설정된 필드값이 출력되어야 하므로
//this.volume을 출력한다.
System.out.println("현재 Audio VOLUME은 "+this.volume+" 이다.");
};
}
package ch08;
//p356
//서치기능 선언한 인터페이스이다.
public interface Searchable {
//추상메소드 문법.
//문법 > public abstract 리턴유형 메소드명(매개변수리스트);
public abstract void search(String url);
}
package ch08;
//p357
//이 클래스는 다중인터페이스 구현클래스이다.
//구현클래스명 implements 인터페이스명1, 인터페이스명2, ~ .........인터페이스명n
public class SmartTelevision implements RemoteControl, Searchable {
//구현클래스에서는 인터페이스에서 상속받은 추상클래스를 반드시 구현해야한다.
//=>추상메소드를 반드시 오버라이딩해야한다는 의미!!!! => 메소드 재정의!!!!!
//특정인터페이스를 구현한다고 implements 작성하면 반드시 인터페이스에서 선언한 추상클래스를 오버라이딩해야한다는 멘트가 이클립스에서 제공
/The type Television must implement
* the inherited abstract method
* RemoteControl.setVolume(int)/
//필드
private int volume; //현재볼륨
//추상클래스 추상 메소드는 구현클래스에서 하면된다. 단 위에 Television에 빨간 밑줄이 안가려면 RemoteControl 인터페이스에서 선언한 메소드를 모두 오버라이딩 해야한다.!!!!
//전원켜기 메소드 재정의
public void turnOn() {
System.out.println("TV 전원이 켜졌습니다.");
};
//전원끄기 메소드 재정의
public void turnOff() {
System.out.println("TV 전원이 꺼졌습니다.");
};
//불륨조절하는 메소드를 재정의 하세요.
//MAX_VOLUME과 MIN_VOLUME은 Static이므로
//클래스명.필드명으로 접근
public void setVolume(int volume) {
// if(volume > 클래스명.필드명) {
if(volume > RemoteControl.MAX_VOLUME) {
//제시된 volume이 최대볼륨보다 크면
//최대볼륨으로 현재 volume 으로 설정
this.volume = RemoteControl.MAX_VOLUME;
}else if(volume < RemoteControl.MIN_VOLUME) {
//제시된 volume이 최저볼륨보다 작다면
//최저볼륨으로 현재 volume 으로 설정
this.volume = RemoteControl.MIN_VOLUME;
}else {
//제시된 볼륨이 최저볼륨과 최대볼륨 사이라면
//제시된 볼륨으로 현재 volume으로 설정
this.volume = volume;
}
//위에서 if조건에 따라 설정된 필드값이 출력되어야 하므로
//this.volume을 출력한다.
System.out.println("현재 TV VOLUME은 "+this.volume+" 이다.");
}
//Searchable 인터페이스의 search()를 재정의
public void search(String url) {
System.out.println(url+ "검색");
};
}
package ch15_collection;
//java.lang패키지를 제외한 그 외 패키지는 import해야한다.
//모든 클래스의 조상클래스는 Object클래스, wrapper 클래스 또한 java.util 안에 있다.
import java.util.ArrayList; //컬렉션 프레임워크를 쓰려면 java.util에서 import 해줘야 한다.
import java.util.Date;
//import java.util.*; 귀찮으면 이렇게 쓴다.
//import 패키지명.Date;
/*collection Framework(컬렉션 프레임워크)
-3가지 인터페이스
-List : 순서유지, 중복허용 예)대기자 List
-Set : 순서유지X, 중복허용X 예)
-Map : Key와 value가 한 pair
key는 중복허용X
value는 중복허용
*/
public class ArrayList01 {
public static void main(String[] args) {
//java.util.ArrayList list = new java.util.ArrayList(); //----> import 하기 싫다면 매번 이런형식으로 써야한다. ......ㅎㅎ
//그냥 import하자..
ArrayList list = new ArrayList();
System.out.println(list); //
System.out.println(list.toString()); // --> 주소는 담았지만 해시코드가 아니라 배열형태로 출력.비어있다~~ 컬렉션에서 toString은 이런형태로 오버라이딩 된 것. 배열형태
//size():리스트안에 저장된 (item)의 개수를 리턴
//참고> .length:배열(Array)에 저장된 요소(item)의 개수를 리턴
//Returns the number of elements in this list.
int size = list.size(); //size메소드라서 ()가 있고 , length는 괄호가 없다. 어레이 리스트에서는 랭쓰가 아니라 size를 쓴다>?
System.out.println("list.size()="+size);
//.add() : value추가
//List에는 다양한 타입의 value를 추가가 가능!
//비교> 배열(array)에는 동일한 타입의 value를 추가 // 컬렉션은 다른타입도 다 들어간다?
list.add("홍길동"); //add(Object)형태이기 때문에 (래퍼)클래스 변수 숫자 다 들어올 수 있다.
list.add(new String("서울시 강남구"));
list.add("hid");
list.add("h123");
list.add(20); //int 인트형태 리터럴 Integer 래퍼클래스로 변환
list.add(182.9); //double -> 더블형태 리터럴 Double 래퍼클래스로 변환
list.add('남'); //char -> Character 래퍼클래스로 변환
list.add(true); //boolean -> Boolean 래퍼클래스로 변환
list.add(new Date()); //현재 날짜와 시간 객체 생성 java.util에 있는 Date를 쓴다.
size = list.size(); //이렇게 하거나 위에 0개일때 size에 담았기 때문에 다시 담아줘야한다.
System.out.println("list.size()="+size);
// System.out.println("list.size()="+list.size()); //이렇게 하거나~
//특정위치에 있는 요소(item, element)를 가져오기
//get(인덱스)
Object data = list.get(0); //배열처럼 특정 타입의 데이터만 담기는게 아니라서 리턴을 Object라고 되어있다.(모든~데이터~ 어떤타입이 담길지 모르기때문에)
System.out.println(data); //홍길동
//오브젝트에는 글자길이를 구하는 필드나 오브젝트가 없다. 그러면 String으로 down casting. 강제 형변환.
//(강제형변환하고자 하는 클래스명) 변수
//여기에서는 String으로 강제형변환하여
//String 클래스의 length()메소드를 호출하였다.
//Object에는 length()메소드가 없기 때문에.
String strData = (String)data; //한마디로 글자길이 보려면 스트링형태로 형변환하고서 출력해야한다는 뜻.
System.out.println("글자길이 = "+strData.length()); //글자길이
// Animal = new Animal();
// Animal a = new Cat(); a.sound();
// Animal a = new Dog(); a.sound();
// Animal a = new Bird(); ((Bird)a).fly(); //-->모든 동물에 나는 기능이 없으므로 출력전에 Bird타입으로 강제 형변환 다운캐스팅 해야한다. 강제 형변환
//String 타입으로 글자길이 출력하는 것을 설명하기 위한 강제형변환 내용
// data = list.get(1); 이렇게 계속 같은 변수에 넣어도 되지만 보기 좋게 다른 변수에 담아보자~!
Object data1 = list.get(1);
System.out.println(data1); //서울시 강남구 (공백까지 총 7글자)
String strData1 = (String)data1;
System.out.println("글자길이 = "+strData1.length());
// System.out.println("글자길이 = "+((String)data1).length()); //--->변수에 안담고 이렇게 한번에 해도 된다.
Object data2 = list.get(2);
System.out.println(data2); //hid
String strData2 = (String)data2;
System.out.println("글자길이 = "+strData2.length());
Object data3 = list.get(3);
System.out.println(data3); //h123
//인덱스 4,5,6,7 에 담긴 value는
//Object타입의 변수 date4에 저장 후 출력 --->변수 하나로 계속 저장!!
//instanceof 클래스명 : 특정클래스의 객체이면 true 리턴
// Object data4 = list.get(4);
//// System.out.println(data4); //20
//// if(~~이 instanceof 클래스명) {
// if(data4 instanceof Integer) { //int의 래퍼클래스야? int의 객체야? 라고 물어보는것.
// System.out.println("정수 : "+data4);//20
// }else if(data4 instanceof Double) {
// System.out.println("실수 : "+data4);//182.9
// }else if(data4 instanceof Character) {
// System.out.println("문자 : "+data4);//남
// }else if(data4 instanceof Boolean) {
// System.out.println("불리언 : "+data4);//true
// }
//
// data4 = list.get(5);
//// System.out.println(data4); //182.9
// if(data4 instanceof Integer) { //int의 래퍼클래스야? int의 객체야? 라고 물어보는것.
// System.out.println("정수 : "+data4);//20
// }else if(data4 instanceof Double) {
// System.out.println("실수 : "+data4);//182.9
// }else if(data4 instanceof Character) {
// System.out.println("문자 : "+data4);//남
// }else if(data4 instanceof Boolean) {
// System.out.println("불리언 : "+data4);//true
// }
//
//
// data4 = list.get(6);
//// System.out.println(data4); //남
// if(data4 instanceof Integer) { //int의 래퍼클래스야? int의 객체야? 라고 물어보는것.
// System.out.println("정수 : "+data4);//20
// }else if(data4 instanceof Double) {
// System.out.println("실수 : "+data4);//182.9
// }else if(data4 instanceof Character) {
// System.out.println("문자 : "+data4);//남
// }else if(data4 instanceof Boolean) {
// System.out.println("불리언 : "+data4);//true
// }
//
// data4 = list.get(7);
//// System.out.println(data4); //true
// if(data4 instanceof Integer) { //int의 래퍼클래스야? int의 객체야? 라고 물어보는것.
// System.out.println("정수 : "+data4);//20
// }else if(data4 instanceof Double) {
// System.out.println("실수 : "+data4);//182.9
// }else if(data4 instanceof Character) {
// System.out.println("문자 : "+data4);//남
// }else if(data4 instanceof Boolean) {
// System.out.println("불리언 : "+data4);//true
// }
//1. 포문으로 돌려서 위와 동일한 결과 출력!!!!
// Object data4 = null;
// for(int i=4; i<8;i++) {
// data4 = list.get(i);
// if(data4 instanceof Integer) { //int의 래퍼클래스야? int의 객체야? 라고 물어보는것.
// System.out.println("정수 : "+data4);//20
// }else if(data4 instanceof Double) {
// System.out.println("실수 : "+data4);//182.9
// }else if(data4 instanceof Character) {
// System.out.println("문자 : "+data4);//남
// }else if(data4 instanceof Boolean) {
// System.out.println("불리언 : "+data4);//true
// }
// }
//2. 포문으로 돌려서 위와 동일한 결과 출력!!!! 더 간소화
Object data4 = null;
String type="";
for(int i=4; i<8;i++) {
data4 = list.get(i);
if(data4 instanceof Integer) { //int의 래퍼클래스야? int의 객체야? 라고 물어보는것.
type="정수 : ";//20
}else if(data4 instanceof Double) {
type="실수 : ";//182.9
}else if(data4 instanceof Character) {
type="문자 : ";//남
}else if(data4 instanceof Boolean) {
type="불리언 : ";//true
}
System.out.println(type+data4);
}
// Object data4 = list.get(4);
// System.out.println(data4); //20
//
// Object data5 = list.get(5);
// System.out.println(data5); //182.9
//
// Object data6 = list.get(6);
// System.out.println(data6); //남
//
// Object data7 = list.get(7);
// System.out.println(data7); //true
//
// Object data8 = list.get(8);
// System.out.println(data8); //Mon Nov 14 16:35:51 KST 2022
}
}
래퍼클래스 내용 페이지 527