대상이 new로 만들어 질때의 생성자나 초기값은 상관없이. 현제 상태의 값 만을 복사합니다.
맴버변수와 내부의 값까지 똑같은 인스턴스를 new 없이 새롭게 만들수 있습니다.
만들어질때 대상(인스턴스)의 타입(기반이 되는 클레스)는 복사 되지 않고 object타입으로 생성됩니다. ( 완벽하게 복사하거나 원본의 메소드를 사용하기 위해서는 형변환을 해줘야 합니다)
“복사하려는 대상의 타입”+”만들려는 참조변수명” = (복사하려는 대상의 타입)대상.clone();
위치:
lang 페키지의 Object
모든 class는 object를 상속받기 때문에 별도의 임포트나 상속이 필요하지 않습니다.
사용하는 방법:
복제하려는 대상 오브젝트(인스턴스)나 기반이 되는 클레스에서 cloneable 를 implement 해야합니다.
오브젝트 내부의 정보를 전부 복사하기 때문에. 개인,기업 정보의 보안적인 관점에서 정보은닉과 캡슐화, 객체 지향의 계념과 배척적 입니다. 그렇기에 이같은 위험성을 인지하고 허가 한다는 의미에서 cloneable 이라는 인터페이스를 명시(implement)해 줘야 사용할수 있습니다.
복제하려는 대상 오브젝트(인스턴스)나 기반이 되는 클레스에서 clone메소드를 재정의(overrriding)으로 입력합니다 .( 오버라이딩 하지 않으면 작동되지 않기 때문에 필수 조건 입니다.)
에제 상황
변화 되는 오브젝트 중간 중간에서 현제 값을 저장하게 하여. 값이 변화하는 오브젝트의 상태를 시간순서에 의거하여 비교 하여 수치 변화를 조건식으로 사용하거나 관찰 할때도 사용할수 있습니다
간단한 사용법 예제
package Clone_A;
class Target implements Cloneable{
int A = 10;
void runTest() {
System.out.println("check");
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
}
public class TEST {
public static void main(String[] args) throws CloneNotSupportedException {
Target T1 = new Target();
Target T2 = (Target)T1.clone();
System.out.println(T2.A);
T1.A = 20;
System.out.println("==T1값 변조==");
System.out.println(T1.A);
System.out.println(T2.A);
}
}
이 예제 에서는 예외처리(Exception)를 try catch 하지 않고 디커렙션으로 throws 해서 간단하게 출력해 봤습니다.
이 기능을 재정의 하여 인스턴스 내의 속성값을 비교하여 boolean값을 리턴하도록 변경함으로서 얻어지는 이점은 이렇습니다.
특정 조건을 만족하는 맴버번수를 갖고있는 인스턴스를 검색할수 있습니다.
예 ) 같은 이름값을 갖고 있는 학생의 점수 객체를 검색후 정리하여. 합산하거나 통합 데이터 작성
기초 1. 재정의 하는 방법
1. equals는 lang페키지의 object 클레스에 준비되어있고. 이 두가지는 기본적으로 로드되는 요소(정확히는 모든 클레스가 object를 상속받습니다)이기 때문에 임포트 하거나 상속하지 않고도 바로 재정의 하시면 됩니다.
2. instanceof로 this의 타입이 검색하려는 속성이 있는 대상의 타입과 일치하거나 상속관계인지 확인합니다.
3. 2번의 조건이 true일경우 상속관계일 경우를 대비하여 this를 대상의 타입으로 변환(업스캐일)시킨후 대상과 this의 비교하려는 값이 일치하는지 확인합니다.
package TEST1;
class Human{
private String name ;
Human(String name){
this.name = name;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Human) {
Human H = (Human)obj;
if(this.name == H.name)
return true;
else return false;
}
return false;
}
}
public class TEST_A {
public static void main(String[] args) {
Human A = new Human("A");
Human B = new Human("B");
Human C = new Human("A");
System.out.println(A.equals(B));
System.out.println(A.equals(C));
}
}
A에 B의 인스턴스를만드는것이지만. 화살표의 방향으로 인해 상속의 계념과 햇갈릴수 있지만 가리키는 대상이 반대로 A가 주어로 작동한다. 화살표의 방향 보다 마름모의 방향이 주어가 된다.
마름모의 내부가 검은색이면 생명주기가 같고. 비어있으면 연관이없다.
정확화게는 static 이나 final 등으로 static 메모리에 B의 인스턴스를 올렸을 경우에 해당한닥 볼수도 있겠다.
슈도 코드 방식의 암기결과 : 정상 작동
package TEST2;
public class AdvancedLevel extends PlayerLevel {
@Override
public void run() {
System.out.println("빨리 달립니다");
}
@Override
public void jump() {
System.out.println("점프합니다");
}
@Override
public void turn() {
System.out.println("턴 하였습니다");
}
@Override
public void showLevelMessage() {
System.out.println("-------- 중급자 레벨 --------");
}
}
package TEST2;
public class BeginnerLevel extends PlayerLevel {
@Override
public void run() {
System.out.println("천천히 달립니다");
}
@Override
public void jump() {
System.out.println("점프할수 없습니다");
}
@Override
public void turn() {
System.out.println("턴 할수 없습니다");
}
@Override
public void showLevelMessage() {
System.out.println("-------- 초급자 레벨 --------");
}
}
package TEST2;
public class Mainboard {
/*
Player가 있고 Player는 PlayerLevel 속성을 가집니다. 각 PlayerLevel 단계 마다 run(), jump(), turn() 세 가지 기능이 업그레이드 됩니다.
초보자 레벨 : 천천히 달립니다. run() 만 가능
중급자 레벨 : 빠르게 달리고, 점프할 수 있습니다. run(), jump() 가능
고급자 레벨 : 엄청 빠르게 달리고, 높게 점프하고, 턴할 수 있습니다. run(), jump(), turn() 가능
Player는 한번에 하나의 레벨 상태만을 가질 수 있습니다.
Player가 play() 중에 레벨에 있는 go(int count) 라는 메서드를 호출하면 run() 하고 count 횟수 만큼 jump() 하고 turn() 합니다. 다음 클래스 다이어그램을 참고하여 각 레벨에서 go() 가 호출 될때 다음과 같이 출력 되도록 하세요
*
* */
public static void main(String[] args) {
Player player = new Player();
player.playerlevel.showLevelMessage();
player.playerlevel.go(1);
AdvancedLevel Alevel = new AdvancedLevel();
player.upgradeLevel(Alevel);
Alevel.go(2);
SuperLevel Slevel = new SuperLevel();
player.upgradeLevel(Slevel);
Slevel.go(3);
}
}
package TEST2;
public class Player {
PlayerLevel playerlevel ;
Player(){
playerlevel = new BeginnerLevel() ;
}
void upgradeLevel(PlayerLevel level) {
this.playerlevel = level;
level.showLevelMessage();
}
}
package TEST2;
public abstract class PlayerLevel {
public abstract void run();
public abstract void jump();
public abstract void turn();
public abstract void showLevelMessage();
public void go(int count) {
run();
for (int i = 0; i < count; i++) {
jump();
}
turn();
}
}
package TEST2;
public class SuperLevel extends PlayerLevel {
@Override
public void run() {
System.out.println("아주 빠르게 달립니다");
}
@Override
public void jump() {
System.out.println("높이 점프 합니다");
}
@Override
public void turn() {
System.out.println("턴 하였습니다");
}
@Override
public void showLevelMessage() {
System.out.println("-------- 고급자 레벨 --------");
}
}
인터페이스를 활용한 정책 프로그래밍
같은 메소드를 하위에서 필요에 따라 다르게 작동시키게 하는방법
상담원의 데이터가 어디있는지 명시가 되어있지 않다.
이런경우 이전 코드를 생각해보면. 단순히 콘솔아웃의 코드일경우가 있다.
고객의 데이터를 수기로 입력해서
여기에서 사용되는 3가지의 인터페이스를 활용하는 정책이 전부 스케듈링의 방식을 따르고 있기 때문에 좋은 복합적 이지만 재미있는 기회이다.
RoundRobin(둥근 로빈): 시간 순서대로 일장한 양의 작업을 배분
leastJob(리스트잡 :최소 작업) : 최소의 작업을 갖고있는 직원에게 배분
PriorityAllocation(우선순위할당 방식) : 등급대 등급으로 배분
새로운 문법
int ch = System.in.read();
ch에는 정말 char타입의 한글자만 입력을 받을수 있다.
예제코드
package TEST3;
public class LeastJob implements Scheduler {
@Override
public void getNextCall() {
System.out.println("다음 작업 오라 오라 !YES!");
}
@Override
public void sendCallToAgent() {
System.out.println("가장 잡업의 량이 적은 상담사에게 배분 됩니다.");
}
}
package TEST3;
public class PriorityAllocation implements Scheduler {
@Override
public void getNextCall() {
System.out.println("다음 작업 오라 오라 !YES!");
}
@Override
public void sendCallToAgent() {
System.out.println("우선순위배분 : 작업의 우선순위 등급에 맞는 프로세서(상담사)에게 배분됩니다");
}
// 우선순위 할당
}
package TEST3;
public class RoundRobin implements Scheduler {
@Override
public void getNextCall() {
System.out.println("다음 작업 오라 오라 !YES!");
}
@Override
public void sendCallToAgent() {
System.out.println("시간순으로 일정하게 작업이 배분되는 순서대로 상담사에게 배분 되었습니다. ");
}
}
학습할떄마다 속도가 붙지 않는 원인이 있습니다. 바로 언제나 궁금증이 폭발 한다는 점인데요.
이번 코드에서는 문법적인 부분은 이해하지만 구조적으로 왜 인터페이스와 클레스가 쓰일수 밖에 없었는지 같은 점들이 많은 궁금증을 갖게 합니다.
개인적으로 아직 소계되지 않은 내용에 대해서는 차근 차근 나중에 공부할수 있는 기회가 있다고 자신의 호기심을 다독이며 진행 해야 할것 같습니다 ^^
오늘부터 새로 도입한 방법은
키보드를 타이핑한 수와 . 시간을 재서 평균을 내는것입니다.
이론 정리
14 챕터 library코드 구조 해석.
현제 듣고 있는 강의의 class shelf에서 ArrayList A를 protected로 만드는데.
get set을 사용하지 않고 접근할수 있는것은 좋은데. 정보 은닉도 되면서 get set을 사용하지 않아도 된다면 매우 편하게 코딩할수 있겠다. 정확하진 않지만 더 궁금증을 해결하는데 시간을 낭비하지말고 우선은 이 코드의 형태로 코드작성법을 고착 시키고 진도를 나간후 천천히 공부할 기회가 찾아 올것을 기다리자.
BookShelf 는 인터페이스와 클레스를 상속받아서. 인스턴스로 객체 가 만들어 지면서 사용된다.
ArrayList의 자료가 비어있을때 remove를 하면 에러가 발생한다.
메소드에 하위에서 구현될 메계변수의 데이터 타입까지 구현해야 한다.
객체의 작동을 태스트 할때 객태TEST로 명명한다.
Shelf와 BookShelf의 관계에 대해서는 아직 잘 모르겠다. 그냥 BookShelf만 만들고 Queue를 상속받으면 해결되는것이지만 문법을 공부하기 위한 코드라고 이해하고 의미부여를 하지 말고 넘어가자.
자료 구조 에서 큐로 만들어진 자료가 몇개가 있는지 나타낼때 큐가 몇개가 있다는 표현을 사용한다.
왜 상위 인터페이스인 Queue 타입 참조변수에 BookShelf를 넣는걸까?
아무튼 큐 타입 이니까 큐 타입으로 업스케일을 하는데. 질문이 가능하다면 당장 물어보고 싶지만. 이 교육 플랫폼에서 감히 학생이 교사에게 질문을 할수 있는 무료 강의에도 있는 기능이 없기 때문에 다음에 알수 있는 기회가 오기를 기다려야 겠다.
# 챕터 14 도서관 코드 암기용 복습
package TEST2;
public class BookShelf extends Shelf implements Queue {
@Override
public void enQueue(String BookName) {
shelf.add(BookName);
}
@Override
public String deQueue() {
return shelf.remove(0);
}
}
package TEST2;
public class BookShelfTest {
public static void main(String[] args) {
BookShelf bookshelf = new BookShelf();
bookshelf.enQueue("백귀야행");
bookshelf.enQueue("인간의증명");
bookshelf.enQueue("우부메의 여름");
bookshelf.enQueue("황혼색의 명영사");
System.out.println(bookshelf.getCount());
System.out.println(bookshelf.deQueue());
System.out.println(bookshelf.deQueue());
System.out.println(bookshelf.deQueue());
System.out.println(bookshelf.deQueue());
}
}
package TEST2;
import java.util.ArrayList;
public class Shelf {
protected ArrayList<String> shelf ;
Shelf(){
shelf = new ArrayList<String>();
}
int getCount(){
return shelf.size();
}
ArrayList<String> getshelf() {
return shelf;
}
}
16 복습해 봅시다.
추상 클레스와 틈플릿 메소드의 활용
package TEST3;
public class SuperLevel extends PlayerLevel {
@Override
void run() {
System.out.println("엄청 빠르게 달립니다.");
}
@Override
void jump() {
System.out.println("아주 높이jump 합니다.");
}
@Override
void turn() {
System.out.println("turn 합니다.");
}
@Override
void showLevelMessage() {
System.out.println("고급자 레벨 입니다.");
}
}
package TEST3;
public class BeginnerLevel extends PlayerLevel {
@Override
void run() {
System.out.println("천천히 달립니다.");
}
@Override
void jump() {
System.out.println("Jump 하지 못합니다.");
}
@Override
void turn() {
System.out.println("Turn 하지 못합니다.");
}
@Override
void showLevelMessage() {
System.out.println("초급자 레벨 입니다.");
}
}
package TEST3;
public class MainBoard {
public static void main(String[] args) {
Player player = new Player();
player.play(1);
AdvancedLevel aLevel = new AdvancedLevel();
player.upgradeLevel(aLevel);
player.play(2);
SuperLevel sLevel = new SuperLevel();
player.upgradeLevel(sLevel);
player.play(3);
}
}
package TEST3;
public class Player {
private PlayerLevel levelB;
Player(){
levelB = new BeginnerLevel();
levelB.showLevelMessage();
}
public PlayerLevel getLevel(){
return levelB;
}
public void upgradeLevel(PlayerLevel level){
this.levelB = level;
level.showLevelMessage();
}
public void play(int level) {
levelB.go(level);
};
}
package TEST3;
public abstract class PlayerLevel {
abstract void run();
abstract void jump();
abstract void turn();
abstract void showLevelMessage();
final void go(int level) {
run();
for (int i = 0; i < level; i++) {
jump();
}
turn();
}
}
package TEST3;
public class SuperLevel extends PlayerLevel {
@Override
void run() {
System.out.println("엄청 빠르게 달립니다.");
}
@Override
void jump() {
System.out.println("아주 높이jump 합니다.");
}
@Override
void turn() {
System.out.println("turn 합니다.");
}
@Override
void showLevelMessage() {
System.out.println("고급자 레벨 입니다.");
}
}
package TESTA;
public class Do {
public static void main(String[] args) {
Sub S = new Sub();
S.Do();
SuperA A = (SuperA)S;
A.Do();
A.DoA();
// A.DoB();
}
}
extends 뒤에 여러개가 있으면 그 여러개는 인터페이스라고 알수 있다,
인터페이스와 상속의 코드 연습형의 .완.성.형
[ 실전 ] 도서관 대여 프로그램을 만들어 봅시다 ^_^.
학습목표 : 클레스와 인터페이스를 같이 갈아 넣는 방법을 익히다.
이렇게 쓰다(아이 써) : extends SuperClass implement InterfaceClass : 앞에 익스텐즈를 쓰고 뒤에 임플리멘츠를 쓰다.
구동 목표 : 책이 순서대로 대여 되는 도서관 프로그램.
계념의 구조 : 책장에 반듯이 가장 왼쪽에 책을 넣고 가장 오른쪽으로 책을 꺼낼수 있다.
책을 꽃고 맨 앞의 책만 꺼낼수 있다. Queue 구조.
Shelf(선반)을 상속 받아서 BookShelf로 기능을 “확장”하여 사용하고. Queue에는 기능이 있다.
코드의 구조 :
책의 정보를 저장할 공간이 shelf를 기반으로 ArrayList 구조로 구현 .
Queue(큐) 인터페이스를 구현.
Queue란 FIFO(First Input First Out)구조로 저장되는 방식 : 선입선출
선입선출이란 먼저 입력된 데이터가 먼저 출력되는것을 말합니다.(오래된 데이터부터 출력)
Shelf 클래스를 상속 받고 Queue를 구현합니다.
package library_A;
public class BookShelf extends Shelf implements Queue {
@Override
public void enQueue(String title) {
shelf.add(title);
}
@Override
public String deQueue() {
return shelf.remove(0);
}
@Override
public int getSize() {
return getCount();
}
}
package library_A;
public class BookShelfTest {
public static void main(String[] args) {
Queue bookQueue = new BookShelf();
bookQueue.enQueue("토지1");
bookQueue.enQueue("토지2");
bookQueue.enQueue("토지3");
bookQueue.enQueue("토지4");
bookQueue.enQueue("토지5");
System.out.println(bookQueue.getSize());
System.out.println(bookQueue.deQueue());
System.out.println(bookQueue.deQueue());
System.out.println(bookQueue.deQueue());
System.out.println(bookQueue.deQueue());
System.out.println(bookQueue.deQueue());
}
}
package library_A;
public interface Queue {
void enQueue(String title);
String deQueue();
int getSize();
}
package library_A;
import java.util.ArrayList;
public class Shelf {
protected ArrayList<String> shelf ; // 상속을 받을수 있어요.
public Shelf() {
shelf = new ArrayList<String>();
// 생성자에서 맴버변수를 초기화 하듯이 aarrayList를 초기화 하는게 좋습니다 ^_^.
}
public ArrayList<String> getShelf(){
return shelf;
}
public int getCount() {
return shelf.size();
}
}
타 JDK로 개발하는 방법 : ( 직접 알아낸 방법이라. 다른 좋은 밥법이 있을지도 모릅니다)
오라클 사이트에서 운영하고 있는 자바 아카이브(구버전) 자료실에서 필요한 JDK버전을 다운받아 설치한다.
CLASS 를 생성할때. JDK를 직접 선택하는 옵션을 선택설치한 타 버전의 파일을 자바에서 인식할수 있도록 JDK파일의 주소를 넣어 새로운 버전을 추가하고 버전을 선택한다.
TEST CODE
package TEST1;
public class Do {
public static void main(String[] args) {
Super.static_B();
// Super.static_A(); private는 static 으로 해도 당연히 다른 클레스에서 사용할수 없습니다.
}
}
package TEST1;
public class Sub implements Super {
}