3:1:05 ~ 3:1:07


이론 정리

다형성이란?

  • 객체지향의 특징으로 형변환을 통해 다양한 타입으로 변경할수 있는것으로 얻어지는 이득적인 측면
  • 부모타입으로 모둔 자식 객체를 규격화 시킬수 있기 떄문에. 코드의 부품, 규격화가 가능하다.

재정의_예제 코드

public class Musician {
    public void play(){
        System.out.println("음악가 연주하다.");
    }
}
public class Musician {
    public void play(){
        System.out.println("음악가 연주하다.");
    }
}
public class Musician {
    public void play(){
        System.out.println("음악가 연주하다.");
    }
}

제정의후에도 원래의 메서드를 사용하는 방법 : SUPER

public class Musician {
    public void play(){
        System.out.println("음악가 연주하다.");
    }
}
public class Pianist extends Musician {
    @Override public void play(){
        super.play();
        System.out.println("딩동댕");
    }
}
public class Program {
    public static void main(String[] args){
        Pianist pianist = new Pianist();
        pianist.play();
    }
}

오버라이딩은 Final 속성은 할수 없다.

다형성

같은 타입이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질

하나의 타입에 여러 객체를 대입함으로써 다양한 기능을 이용할 수 있도록 해준다.

다형성을 위해 자바는 부모 클래스로 타입 변환을 허용한다.

즉 부모 타입에 모든 자식 객체가 대입될 수 있다. (부모 타입의 규격화)

이것을 이용하면 객체는 부품화가 가능하다.

ex) 타이어 클래스 타입을 적용했다면 이 클래스를 상속한 실제 타이어들은 어떤 것이든

상관 없이 장착(대입) 가능하다.

자동차는 타이어 타입으로 Hankook 타이어와 Kumho 타이어를 사용하지만,

각 타이어의 성능은 다르게 나온다. <다형성>

위 그림은 아래 코드처럼 표현된다.

public class Car {
    Tire t1 = new HankookTire();// 자식 타입 객체 대입
    Tire t2 = new KumhoTire();
}

타입 변환

데이터 타입을 다른 데이터 타입으로 변환하는 행위

클래스 타입도 기본 데이터 타입 변환과 마찬가지로 타입 변환이 있다. (기본 데이터 타입 변환)

클래스 타입 변환은 상속 관계에 있는 클래스 사이에서 발생한다.

자식 타입은 부모 타입으로 자동 타입 변환이 가능하다!! ( 자식 < 부모)

위의 그림에서 HankookTire와 KumhoTire 는 Tire 를 상속했기 때문에, Tire 변수에 대입할 수 있다.

자동 타입 변환 (Promotion)

프로그램 실행 도중 자동적으로 타입 변환이 일어나는 것을 말한다.

자동 타입 변환은 아래와 같은 조건에서 일어난다.

부모 클래스 타입으로 자동 타입 변환

자동 타입 변환 개념은

자식은 부모의 특징과 기능을 상속받기 때문에 부모와 동일하게 취급될 수 있다.

ex) 고양이는 동물의 특징과 기능을 상속 받았다. 따라서 "고양이는 동물이다." 가 성립된다.

Animal 과 Cat 클래스가 아래와 같이 상속 관계에 있을 때

Animal 클래스와 Cat 클래스 상속 관계

Cat 클래스로부터 Cat 객체를 생성하고, 이것을 Animal 변수에 대입하면 자동 타입 변환이 일어난다.

Cat cat = new Cat();
Animal animal = cat;// Animal animal = new Cat(); 도 가능하다.

위의 코드의 메모리 상태는 아래와 같다. cat 과 animal 변수는 타입만 다를 뿐, (Cat, Animal)

동일한 Cat 객체를 참조한다.

Cat 타입 변수 cat = Cat 객체 참조 주소 값

Animal 타입 변수 animal = Cat 객체 참조 주소 값

동일한 Cat 객체를 참조한다.

즉, Animal 타입 변수 amimal 은 Cat 객체를 참조할 수 있다. <자동 타입 변환>

왜냐하면, Cat 객체는 Animal 객체를 상속 받았기 때문이다. (상속 관계이어야 한다.)

animal 변수가 Animal 타입이므로

당연히 부모인 Animal 객체를 참조하는 것이 맞다라고 생각할 수 있지만, 그렇지 않다!!

cat, animal 변수를 == 연산해보면, true 가 리턴되는데,

참조 변수의 == 연산은 참조 주소값이 같으면 true 를 반환하므로,

두 변수가 동일한 객체를 참조하고 있다.

cat == animal;// true

바로 위의 부모가 아니더라도, 상속 계층에서 상위 타입이라면, 자동 타입 변환이 일어날 수 있다.

ex)

D 객체는 B, A 타입으로 자동 타입 변환이 될 수 있고,

E 객체는 C, A 타입으로 자동 타입 변환 될 수 있다.

하지만, D 객체는 C 타입으로 변환될 수 없고, E 객체는 B 타입으로 변환될 수 없다.

<상속 관계가 아니기 때문!!>

ex) PromotionExample.java

class A { }

Class B extends A { }
Class C extends A { }

class D extends B { }
class E extends C { }

public class PromotionExample {
    public static void main(String[] args) {
        B b = new B();
        C c = new C();
        D d = new D();
        E e = new E();

        A a1 = b;
        A a2 = c;
        A a3 = d;
        A a4 = e;

        B b1 = d;
        C c1 = e;

// B b3 = e;  컴파일 에러 (상속 관계가 아니다.)// C c2 = d;  컴파일 에러 (상속 관계가 아니다.)
    }
}

자동 타입 변환 후 주의할 점!!

부모 타입으로 자동 타입 변환된 변수는 부모 클래스에 선언된 필드와 메소드만 접근 가능하다.

비록 변수는 자식 객체를 참조하지만,

변수로 접근 가능한 멤버는 부모 클래스 멤버로 한정된다.

예외) 메소드가 자식 클래스에서 오버라이딩되었다면, 자식 클래스의 메소드가 대신 호출된다.

(다형성과 관련)

오버라이딩되었다면, 자식 클래스의 메소드에 접근 가능하다.

ex)

자동 타입 변환 시 부모 클래스 멤버만 접근 가능하다. (오버라이딩 예외)

child 객체는 method3( ) 메소드를 가지고 있지만,

Parent 타입으로 변환된 이후에는 method3( ) 을 호출할 수 없다.

하지만 method2( ) 메소드는 부모와 자식 모두가 가지고 있다.

이렇게 오버라이딩된 메소드 (method2( )) 는 타입 변환 이후에도 자식 메소드가 호출된다.

Parent.java

public class Parent {

//메소드
    public void method1() {
        System.out.println("Parent - method1()");
    }

    public void method2() {
        System.out.println("Parent - method2()");
    }
}

Child.java

public class Child extends Parent {
    @Override
    public void method2() {// 부모의 method2 재정의됨
        System.out.println("Child - method2()");
    }

    public void method3() {
        System.out.println("Child - method3()");
    }
}

ChildExample.java

public class ChildExample {
    public static void main(String[] args) {
        Child child = new Child();

        Parent parent = child;// 자동 타입 변환

        parent.method1();
        parent.method2();// 재정의된 메소드 호출 (자식 메소드)//parent.method3();  // 호출 불가능
    }
}

 


전문 용어


 

에러 메세지


학습 시간

 


 

캠 스터디


공부 모임

1) 카카오톡 오픈 채팅방

  - 모르는것을 질문하거나

  - 이해가 가지 않는 부분을 다른 분들의 블로그에서 참고하기 용도

2) 구루미 온라인 독서실

  - 학습 시간을 관리 하거나 경쟁 하는 용도 

 

온라인 강의 주소

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

 


1~4 . 정리하기


이론 정리챕터3

형변환 : casting

  • 영어 단어 : casting (주조) : 제료를 융해되는 온도보다 높게 가열하여 액체화 하여 형태를 바꾸는 것
  • 간단 정의 :
    • UpCasting : 서브 클레스를 슈퍼 클레스로 변환
    • DownCasting : 서브 클레스에서 슈퍼 클레스로 업케스팅 된 클레스에 한해서. 다시 서브 클레스로 변환이 가능하다.
  • 용도 : 다형성 (Polymophism)
    • 다형성이란?
      • 객체 지향의 특징
      • 서브 클레스의 메소드를 중복되게 슈퍼 클레스에서 생성해야 할때. 서브클레스의 메소드를 사용할수 있다.
  • 사용방법 : Perents perent = new childen();
    • perents는 perent의 메소드를 사용할수 있지만 children 의 메소드를 우선적으로 사용한다.

형변환 TEST

package upcasting;

import org.w3c.dom.TypeInfo;

class caffee { // super Class
	String cafeebean ;
	String sugar = "설탕 : 미포함";
	void eat () {
		System.out.println("카페인 섭취가 완료 되었습니다.");
	}
	void buyCaffee() {
		System.out.println("커피 콩을 구입하였습니다");
	}
	void changebean() {
		this.cafeebean = "원산지 : 정체불명";
	}
}
class goldMoca extends caffee {//sub Class
	String sugar = "설탕 : 포함";
	String instance = "인스턴트 커피 입니다";
	void eat() {
		System.out.println("설탕으로 인해 집중력과 행복도가 증가 하였으나. 당료병 가능성, 채중이 증가 하였습니다.!");
	}
	
	public goldMoca() {
		this.cafeebean = "원산지 : 페루산";
	}
	
	void changebean() {
		this.cafeebean = "원산지 : 한국산";
	}
}

public class MyUpCasstingEx_1 {
	public static void main(String[] args) {
		//----다운 케스팅 ----
		System.out.println("----다운 케스팅----");
		caffee goldMocaA = new goldMoca();
		// goldmocaA를 caffee로 생성하고 goldMoca로 형변환(다운케스팅)을 시킨 코드를 축약 한것이다.
		// ㄴ 이 코드가 갖고 있는 의미는 변수는 슈퍼 클레스 것을 사용하지만 메소드는 형변환 시킨 클레스(서브 클레스)것을 사용 한다는 것이다.
		// ㄴ 슈퍼 클레스의 변수 + 서브 클레스(형 변환된 타입)의 메소드 조합으로 사용 한다는 것이다. 
		goldMocaA.changebean();
		System.out.println(goldMocaA.cafeebean);
		// 다운 케스팅 했기 때문에 서브클레스의 메소드가 실행 되었다.
//		System.out.println(goldMocaA.instance);
		//	 ㄴ 생성을 수퍼 클레스로 생성 했기 때문에. 서브 클레스로 형변환 해도 서브 클레스의 변수는 갖고 있지 않다.  
		System.out.println(goldMocaA.sugar);
		//	 ㄴ 서브클레스와 슈퍼 클레스에 동일한 이름의 변수가 있어도 . 메서드와 다르게 변수는 슈퍼 클레스의 변수이다.  
		//----업 케스팅----
		System.out.println("----업 케스팅----");
		goldMocaA.changebean(); // 다운 케스팅 상태에서 메소드가 오버라이드 된 서브 클레스의 메소드가 실행 되었다.
		System.out.println(goldMocaA.cafeebean);
		
		System.out.println("----새로운 인스턴스에 다운케스팅 했을때 참조 주소값----");
		// 새로운 서브 클레스의 인스턴스에 다운케스팅 했을때 참조 주소 실험 
		goldMoca goldmocaB = new goldMoca();
		goldmocaB =(goldMoca)goldMocaA;
		System.out.println(goldmocaB.cafeebean);
		goldmocaB.eat();
		// 결론 : 메서드는 형변환된 타입의 메서드가 실행 되지만. 변수는 처음에 생성된 클레스의 변수를 유지한다. 
		

	}
	
}

Super Test Code

MySuperEx_1

package superEx;

public class MySuperEx_1 {
	public static void main(String[] args) {
		SubA A = new SubA(10);
		System.out.println(A.intA);
	}
}

SubA

package superEx;

public class SubA extends SuperA {
	SubA(int number){
		super(number);
		super.print();// super클레스 내부의 메소드 사용가능.
		super.intA =3;
	}
}

SuperA

package superEx;

public class SuperA {
int intA ;
SuperA(int number){
	this.intA = number;
}
void print() {
	System.out.println("Super print");
}
}

constructer : 생성자 ( 매번 기억하기 힘든 단어 ^^;)

챕터 4

오버라이드

  • 서브 클레스에서 메서드 이름을 슈퍼 클레스와 똑같이 하면 서브클레스의 메서드가 가동 된다.
    • 메서드의 정의 부분을 데피니션 혹은 펑션 시그니쳐 라고도 한다.
  • annotation 애노테이션 : @overriding같은 컴파일러에 보내는것
  • c++은 형변환 후에 가상메서드로 선언을 해야 메서드의 사용이 가능하지만 .자바는 모든 메서드가 가상메서드이고 메모리 영역에 저장되는 공간이 변수와 독립되어 있기 때문에. 그냥 사용이 가능함.

복습 & 실무적인 사용방법

 


전문 용어


 

에러 메세지


학습 시간


캠 스터디

 


공부 모임

1) 카카오톡 오픈 채팅방

  - 모르는것을 질문하거나

  - 이해가 가지 않는 부분을 다른 분들의 블로그에서 참고하기 용도

2) 구루미 온라인 독서실

  - 학습 시간을 관리 하거나 경쟁 하는 용도 

 

온라인 강의 주소

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

 

 


15. 여러 인터페이스 구현하기, 인터페이스의 상속


이론 정리

인터페이스가 구현되는 여러가지 상황들

  • 클레스와 인터페이스를 같이 상속받는 클레스도 많이 사용한다.
    • 어떻게 사용하는걸까?
    • 일단 프레임워크에서 인터페이스를 상속받기 때문에 클레스 까지 상속하는 상황은 흔하게 발생된다고 한다.
  • 여려개의 인터페이스를 같이 상속받는 경우.
  • 인터페이스 간의 상속도 발생한다.
  • 이렇게 인터페이스가 자유롭게 상속의 유연성을 갖게 되는 원인은 인터페이스 내부의 메서드에는 구현(body)부가 없기 때문에. 호환성이 높아지는 것에 있다.
    • 인터페이스 내부에서 사용하는 default method,static method 는 구현부가 있기 때문에. 호환성이 낮아 진다.

그렇다면 클레스는 복수 상속이 왜 불가능 할까?

  • 하나의 클레스를 두개의 클레스가 상속받았을경우에 발생하게 되는 대표적인 문제점으로는 다이아몬드 프라블롬이 뽑힌다.

다이아몬드 프라블롬 이란?

  • 클레스가 다중 상속을 지원하지 않는 대표적인 원인 이다.
  • 위의 다이어그렘 에서 결과적으로 A메서드는 제정의된 B와 C중에서 어떤쪽이 실행되는지 모호성을 갖게 된다. 이런 상황을 다이아몬드 프라블롬이라고 한다.
  • 유저가 구매자 이 기도 하고 판매자 이기도 한 상황처럼 다양한 상속을 받는 경우가 있다.
  • C++에서는 사용하려는 메소드의 재정의 지점을 지정하여 가능하다.
    • 안전하고 모호하지 않는 방향으로 자바가 개발되었다.
    • 점차 자바에 여러가지 기능이 많이 생겨나고 있다.

코드 예제

  • 상위 클레스로 생성 될수 있고. 상위클레스로 생성되면 상위 클레스의 메소드를 사용할수 있다.

코드예제

Buy

package ch15.A;

public interface Buy {
	void buy();
	default void order() {
		System.out.println("buy order");
	}
}

Sell

package ch15.A;

public interface Sell {
	void sell();
	default void order() {
		System.out.println("sell order");
	}
}

Customer

package ch15.A;

public class Customer implements Buy,Sell {

	@Override
	public void sell() {
	System.out.println("Customer Sell");		
	}

	@Override
	public void buy() {
	System.out.println("Customer Buy");
		
	}

	@Override
	public void order() {
		System.out.println("customer order");
	}
	
	public void hello() {
		System.out.println("HELLO");
	}

}

CustomerTest

package ch15.A;

public class CustomerTest {
	public static void main(String[] args) {
		Customer customer = new Customer();
		customer.buy();
		customer.sell();
		customer.order();
		customer.hello();
		System.out.println();
		Buy buyer = customer;
		buyer.buy();
		buyer.order();
		System.out.println();
		Sell seller = customer;
		seller.sell();
		seller.order();
	}
}

인터페이스 끼리의 상속

  • 인터페이스 끼리도 extends 로 상속 할수 있다.
  • X(interface), Y(interface) : interface Z extends X,Y{}
    • X와 Y를 상속받은 Z를 상속받는 클레스는 XYZ의 메소드를 전부 구현해야만 합니다.
    • 어떤 인스턴스를 X와 Y의 메소드 둘다 사용하고 싶은 경우 . 업 스케일링없이 사용할수 있다.
  • 복수 상속받을수 있는 클레스는 인터페이스 밖에 없기 때문에. Z처럼 다수를 상속받으면 다수의 인터페이스 클레스라는것을 알수 있다.
  • implements와 extends를 둘다 사용할 경우에는 implements extends의 순서로 사용한다.

예제 코드

목표 : 책장에서 책을 넣고 꺼낸다.

BookShelf : 책장

Shelf : 물건이 담겨 있다.

Queue : 먼저 입력한 책만 먼저 꺼낼수 있는 큐(Queue)방식을 구현

BookShelf.java

package ch15.B;

public class BookShelf extends Shelf implements Queue {

	@Override
	public void enQueue(String title) {
		shelf.add(title);
		
	}

	@Override
	public String deQueue() {
		// TODO Auto-generated method stub
		return shelf.remove(0);
	}

	@Override
	public int getSize() {
		// TODO Auto-generated method stub
		return getCount();
	}

}

BookShelfTest.java

package ch15.B;

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());
	}
}

Queue.java

package ch15.B;

public interface Queue {
	void enQueue(String title);
	String deQueue();
	int getSize();
	
}

Shelf.java

package ch15.B;

import java.util.ArrayList;

public class Shelf {
	protected ArrayList<String> shelf;
	public Shelf() {
		shelf = new ArrayList<String>();
	}
	public ArrayList<String> getshelf(){
		return shelf;
	}
	public int getCount() {
		return shelf.size();
	}
}

복습 & 실무적인 사용방법

 

 


전문 용어


 

에러 메세지


학습 타이머


 

캠 스터디

 


스터디 그룹


1) 카카오톡 오픈 채팅방

  - 모르는것 질문하기

  - 이해가 가지 않는 부분을 다른 분들이 블로그에서 정리한 글을 살펴보고 참고 하기

2) 구루미 온라인 독서실

  - 학습 시간 관리하기

  - 남들과 경쟁하기 

 

온라인 강의 주소

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

 


14. 인터페이스의 여러가지 요소

인터페이스에 대한 뚜렷한 사용방법. 계론

의 공동 학습진행을 위해 1강씩 진도를 나가면서. 복습. 이론 정리를 진행하기로 함.

이해가 가지 않는 선생님의 어휘가 등장하면 조사하면서 한 강의를 세세한 부분으로 나누어 정리.


이론 정리

인터페이스의 요소

1. 상수

인터페이스 내에서는 에서는 변수의 값 이 변할 경우 하위클레스들 (복수 구현(Implementation)가능)에 큰 영향을 미치기 때문에 변수를 상수로 사용한다.

  • 잘못된 사용예 ) final int A = 10;
  • 올바른 사용예 ) public static final 클레스명{ int A = 10 ;}

2. 추상 메서드

  • 인터페이스 내 에서는 모든 메서드를 구현부(중활호부분,body)없이 사용한다.
    • 잘못된 사용예 ) public int 메서드(){ }
    • 올바른 사용예 ) public abstract int 메서드명()
  • 자바 8이후의 변화
    • default method 등장
      • 인터페에스를 구현한(Implementation 한)대부분의 클레스에서 중복 구현 해야만 하는 메소드가 있을경우 오버해드가 발생됨으로, 인터페이스 내부에서 구현할수 있는 default method가 탄생
        • 사용예 ) default void description(){}
        • 구현된 클레스 ) description(){실행문} 로 메소드를 재정의 하거나 디폴트 메소드로 사용한다.
        • 구현하려는 메소드가 있는 인터페이스를 상속해야 한다.
  • 정적 메서드 : static method
    • NEW 해서 만들거나 상속받지 않아도 사용할수 있는 메서드로 default method처럼 인터페이스를 구현한 클레스 중에서 중복적으로 사용되는 메서드로 인해 오버해드 되는것을 해결하기 위해 탄생했다. (탄생 배경은 디폴트 메서드와 같다)
      • 사용예 ) static int(){}
  • 자바 9 이후로 바뀐점
    • private method
      • 인터페이스 내부에서 사용 하기위해서 구현하는 메소드
      • 인터페이스를 구현한 하위 클레스에서 사용하거나 재정의도 할수 없다.
      • interface 내부의 default, static 메소드에서 사용하기 위해서 탄생하였다.

한글

정적 메서드 : static 으로 되어있어서 호출 업이 사용가능한 메서드

인플리멘테이션 하는 클레스 : 인터페이스를 구현하는 클레스

영어

Implementation : implement 하는 클래스. (인터페이스 클레스를 상속받는 하위,자식 클레스)

decollation : 선언하다


복습 & 실무적인 사용방법

 

 


전문 용어


 

에러 메세지


학습 타이머


 

캠 스터디


스터디 그룹

1) 카카오톡 오픈 채팅방

  - 모르는것 질문하기

  - 이해가 가지 않는 부분을 다른 분들이 블로그에서 정리한 글을 살펴보고 참고 하기

2) 구루미 온라인 독서실

  - 학습 시간 관리하기

  - 남들과 경쟁하기 

 

온라인 강의 주소

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

 


13. 프로그램에서 인터페이스의 역할과 다형성

 


이론 정리

인터페이스를 활용한 다형성을 구현하기_DAO 구현하기

인터페이스와 다형성

#전문적인 영역에서 사용하는 용어 & 어휘의 익숙함. 이해가 필요하다고 느껴진다.

#선생님께서 사용하시는 어휘를 학습자도 사용해서 설명하고. 사고할수 있을정도로 이해가 필요하다고 생각한다.

#어휘 & 용어에 대한 정리를 위해 수집 과정이 따로 필요하다고 느껴진다.

인터페이스에 기반한 여러 클레스는 경우에 따라서 리플레이스 해서 사용할수 있다.

예를 들어서 . 정렬 이라는 인터페이스를 구현하는 여러가지 정렬의 정책들을 인터페이스를 구현한 클레스하고 했을때 경우에 따라서 여러 클레스를 변경하면서 사용하는 방법을 스트레티지 페턴 이라고 한다.

인터페이스를 활용한 DAO 구현하기

  • DB에 회원 정보를 넣는 DAO(data access object)를 여러 DB 제품이 지원 될수 있게 구현하기
    • 상황제시 : 오라클 에 사용자 데이터를 유용하게 가공하여 입력하는 솔루션을 만들어서 여러 회사에 납품 하러 갔더니 “ 저희 회사는 mySQL 입니다만!... “이라는 상황
      • 코드를 mySQL로 변경한 버전을 만들거나. 객체를 더 생성하게 되면 관리 해야하는 코드가 2배로 늘어나게 된다. 프로세스가 오버헤드 되는 흔한 상황이다. 기능을 늘리거나 버그를 픽스할때 지옥의 버전관리 개발환경이 된다.
    • 이럴때를 위해서 DAO 인터페이스를 정의해서 오파클, MYsql버전으로 구현하여 경우에 따라서 리플레이스(변경)될수 있도록 한다.

구현

  • 환경파일(db.properties)에서 database의 종류에 대한 정보를 읽고 그 정보에 밎게 DAO인스턴스를 생성하여 실행될수 있도록 구현

source hierarchy

  • 페키지 이름
    • domain.userinfo : 서버 측 _ 백엔드 ,
      • dao
        • mysql
          • userInfoMySqlDao.java
        • oracle
          • userInfoOracleDao.java
        • UserInfoDAO.java : 인터페이스
      • UserInfo.java :
    • userinfo.web : 웹_클라이언트 측_JAVA 매인으로 대체
      • UserInfoClient.java

이클립스의 페키지 익스플로어를 소스 하이러키 계층 구조로 변경하기 : 이클립스의 package explorer에서 햄버거버튼을 누르고 페키지 프레젠테이션에서 소스 하이러키를 선택할수 있다.

source hierarchy계층 구현

  1. 하위 페키지를 구현하려는 페키지를 선택한다
  2. .ctrl+N → “pa(package자동완성)”
  3. “선택되어있는 페키지명.하위 페키지명”을 입력한다.
  4. ( . 점)뒤의 이름은 패키지 내에서 하위 계층으로 자동으로 인식한다.

나이브한 구현방법.

다른 프레임워크를 사용할수도 있으며.

선생님 (曰): “JDBC를 나이브하게 사용한다고 한다면 커넥팅 연결헤서 스테이먼트 에다가 SQL 실어서 쿼리를 때릴수도 있다.”

번역 : 자바에서 기본적으로 제공하는 DB접속 방법을 사용해서. Connection객체를 생성하고 SQL 명령문을 입력하는것?

UserInfoDAO

package ch13.domain.userinfo.dao;

import ch13.domain.userinfo.UserInfo;

public interface UserInfoDAO {
	void insertUserInfo(UserInfo userInfo);
	void updateUserInfo(UserInfo userInfo);
	void deleteUserInfo(UserInfo userInfo);
	
}

UserInfoMySqlDao

package ch13.domain.userinfo.dao.mysql;

import ch13.domain.userinfo.UserInfo;
import ch13.domain.userinfo.dao.UserInfoDAO;

public class UserInfoMySqlDao implements UserInfoDAO {

	@Override
	public void insertUserInfo(UserInfo userInfo) {
		System.out.println("insert into MySQl DB userID = "+ userInfo.getUserId());
	}

	@Override
	public void updateUserInfo(UserInfo userInfo) {
		System.out.println("update into MySQl DB userID = "+ userInfo.getUserId());
	}

	@Override
	public void deleteUserInfo(UserInfo userInfo) {
		System.out.println("delete into MySQL DB userId = "+ userInfo.getUserId());
		
	}

}

UserInfoOracleDao

package ch13.domain.userinfo.dao.oracle;

import ch13.domain.userinfo.UserInfo;
import ch13.domain.userinfo.dao.UserInfoDAO;

public class UserInfoOracleDao implements UserInfoDAO {
	@Override
	public void insertUserInfo(UserInfo userInfo) {
		System.out.println("insert into Oracle DB userID = "+ userInfo.getUserId());
	}

	@Override
	public void updateUserInfo(UserInfo userInfo) {
		System.out.println("update into Oracle DB userID = "+ userInfo.getUserId());
	}

	@Override
	public void deleteUserInfo(UserInfo userInfo) {
		System.out.println("delete into Oracle DB userId = "+ userInfo.getUserId());
		
	}
}

UserInfo

package ch13.domain.userinfo;

public class UserInfo {
	private String userId;
	private String password;
	private String userName;
	public String getUserId() {
		return userId;
	}
	public void setUserId(String userId) {
		this.userId = userId;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	
}

UserInfoClient

package ch13.web.userInfo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

import ch13.domain.userinfo.UserInfo;
import ch13.domain.userinfo.dao.UserInfoDAO;
import ch13.domain.userinfo.dao.mysql.UserInfoMySqlDao;
import ch13.domain.userinfo.dao.oracle.UserInfoOracleDao;

public class UserInfoClient {
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("db_properies");
		Properties prop = new Properties();
		prop.load(fis);
		String dbType = prop.getProperty("DBTYPE");
		System.out.println(dbType);
		UserInfo userinfo = new UserInfo();
		userinfo.setUserId("12345");
		userinfo.setPassword("!@#$%");
		userinfo.setUserName("lee");
		UserInfoDAO userinfoDao = null;
		if(dbType.equals("ORACLE")) {
			userinfoDao = new UserInfoOracleDao();
		}
		else if(dbType.equals("MYSQL")) {
			userinfoDao = new UserInfoMySqlDao();
		}
		else {
			System.out.println("db error");
			return;
		}
		userinfoDao.insertUserInfo(userinfo);
		userinfoDao.updateUserInfo(userinfo);
		userinfoDao.deleteUserInfo(userinfo);
	}
}

db_properies

DBTYPE=ORACLE

어휘

한글

인터페이스를 상속한 클레스들을 인터페이스를 구현한 클레스 라고한다.

콘솔아웃 : 실제로 output을 하지 않고 콘솔창에서 출력되는 수준으로 끝내는 출력

오버헤드 : 프로그램의 처리과정에 들어가는 처리 시간, 메모리 등의 자원 소모 증가

다형성 : 똑같은 인터페이스를 통해서 구현된 다양한 클레스를 경우에 따라서 변경

페키치 이름짓는 법 : 도메인측과 웹측은 앞의 이름을 좌우로 반대가 되도록 짖느다.

  • web측 : “기능.web
  • domain측 : “domain.기능”

코드에 오퍼레이션 하다 :

  • 프로젝트 : 목표를 당설하기 위한 관리
  • 오퍼레이션 : 유지 하는것.
  • 나이브하게 코딩하다 : 세심한 고려없이 작성 되어있다.
  • 쿼리를 때린다 : 쿼리를 입력한다. =ω=(ㅋㅋ)

영어

strategy pattern : 전략패턴

  • 인터페이스를 구현한 여러 클레스를 경우에 따라서 바꿔서 사용할수 있다.
  • 예를 들자면 정렬에 대한 인터페이스를 기반으로 구현한 정책 클레스들을 필요에 따라서 변경해서 호출한다.

DAO : data access object

  • 데이터 베이스의 데이터에 접근하는 기능을 하는 객체 를 말한다.

implements : 도구 ( 인터페이스를 구현할때 사용한다 )

source hierarchy : 코드의 계층 구조

Expression : 평가(evaluate)가 가능해서 하나의 값으로 출력될수 있는 수식(코드 조각)

  • 1+2+3 →6
  • a → a의 값
  • a → [1,2,3]
  • a+b - > 값
  • get(i) - > i값
  • 10 - > 10

Statement : 실행(컴파일러가 해석할수 있는) 가능한(executable) 최소 서술 (코드)

  • Expression이 포함 되어 있다.

 


복습 & 실무적인 사용방법


전문 용어


에러 메세지


학습 타이머


 

캠 스터디


스터디 그룹

1) 카카오톡 오픈 채팅방

  - 모르는것 질문하기

  - 이해가 가지 않는 부분을 다른 분들이 블로그에서 정리한 글을 살펴보고 참고 하기

2) 구루미 온라인 독서실

  - 학습 시간 관리하기

  - 남들과 경쟁하기 

 

온라인 강의 주소

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

 


11. 구현 코드가 없는 인터페이스


이론 정리

구현 방법

  • 모든 메서드가 추상 메서드로 되어 있다. (public abstract)
  • 모든 변수는 상수로 선언된다 . (public static final)
  • class 대신 interface로 생성한다.
  • 다이어 그렘에서 점선(인플리멘츠)과 화살표로 상속관계 처럼 표현한다.
    • 인터페이스에서는 상속한다를 구현한다 라고 말한다.
  • 전혀 이해가 가지 않기 때문에. 이전 학습과정을 복습해야 할것 같다.

Calc.java

package interface_1;

public interface Calc {
	double Pi = 3.14;
	int ERROR = -9999999;
	int add(int num1,int num2);
	int substract(int num1,int num2);
	int times(int num1,int num2);
	int divide(int num1,int num2);
	
}

Calculater.java

package interface_1;

public abstract class Calculater implements Calc {

	@Override
	public int add(int num1, int num2) {
		return num1+num2;
	} 

	@Override
	public int substract(int num1, int num2) {
		return num1-num2;
	}

}

CalculatorTest.java

package interface_1;

public class CalculatorTest {
	public static void main(String[] args) {
		// 타입상송을 했다. 구현 상속을 했다.
		
	}
}

CompleteCalc.java

package interface_1;

public class CompleteCalc extends Calculater {

	@Override
	public int times(int num1, int num2) {
		// TODO Auto-generated method stub
		return num1 * num2;
	}

	@Override
	public int divide(int num1, int num2) {
		// TODO Auto-generated method stub
		if(num2 ==0) {
			return ERROR;
		}
		return num1/num2;
	}
public void showInfo() {
	System.out.println("모두 구현 했습니다.");
}
}

복습 & 실무적인 사용방법


12. 인터페이스를 사용하는 이유


이론 정리

인터페이스

  • 연결점
  • 클래스나 프로그램이 제공하는 기능을 명시적으로 선언

클라이언트와 서버

서비스를 사용하는 쪽 : 클라이언트 , 서드파티 jar(라이브러리) 개발사

서비스를 재공하는 쪽 : 서버측

클라이언트는 서비스를 사용할때. 서버에 대한 세세한 정보를 습득 할수 있지 않고. 서버측 에서 사용할수 있는 기능이 명시 되어있는 사양을 보고 맟추어 사용하게 된다.

사양이라는 연결점에서 정보를 주고받는 규격을 만드는것? 이라고 볼수 있을까.

이전 챕터에서 사용했던 인터페이스의 코드를 보고 어떤 감각인지 느껴보도록 하자.

인터페이스를 사용하는 이유

이 모듈이 무슨 기능이 있고. 무슨 값을 넣어 주세요 라는 명세 대로. 입력하도록 하는것이 프레임워크와 비슷한것 같다.


복습 & 실무적인 사용방법


전문 용어


에러 메세지


학습 타이머


캠 스터디


스터디 그룹

1) 카카오톡 오픈 채팅방

  - 모르는것 질문하기

  - 이해가 가지 않는 부분을 다른 분들이 블로그에서 정리한 글을 살펴보고 참고 하기

2) 구루미 온라인 독서실

  - 학습 시간 관리하기

  - 남들과 경쟁하기 

 

온라인 강의 주소

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

 


09. 추상 클래스의 의미와 구현하는 방법


이론 정리

추상 클레스란?

추상 메서드를 선언(definition) 한 것을 포함한 클레스를 추상 클레스라고 한다.

  • int add(int x, int y); ← 이렇게 구현부(중괄호 : body )가 없이 선언하는 메서드(초상 메서드)을 포함하고 있는 클레스.
  • 인터페이스는 메서드 선언만으로 이루어져 있다고 한다.
  • 다이어 그램에서 이텔릭체(기울어져 있는 글씨)로 구현된 클레스는 추상 클레스 이다.
  • 인스턴스를 생성할수 없다.

추상 클레스를 만드는 이유

  • 하위 클레스(상속받은 클레스)에서 공통적으로 사용하는 메서드
    • 상속 만을 위해서 사용하는 클레스.

추상 클레스를 만드는 방법

상위 클레스

public abstract class 클레스명{

public abstract void 메서드명 ;

}

  • 상위 클레스 에서 body(구현부)를 작성하지 않고. 하위 클레스에서 메서드의 구현부를 작성 하도록한다. 하위 클레스로 메서드 바디부의 구현 책임을 넘긴다.
  • 하위 클레스에서 메서드의 구현부를 전부다 구현하지 않을 경우 에러가 발생하는데.하위 클레스 또한 추상 클레스로 만들면 . 하위 클레스의 하위 클레스를 만들때 메서드를 구현할수 있게 된다.
  • 추상클레스는 인스턴스화 할수 없다.
    • 추상 클레스의 하위 클레스는 추상 클레스가 아니기 때문에 인스턴스화 할수 없다.

하위 클레스

추상 클레스를 상속 받는다.

상위에서 구현하지 않은 메서드를 @Override로 구현한다.

추상 클레스를 만들고 상속받을 하위 클레스를 만들때 . super란에서 상위 클레스를 선택하면 상위 클레스가 추상 클레스일 경우 자동으로 @Override와 메서드들의 구현부(BODY)를 생성해 준다.

computer.java

package ch9;

public abstract class computer {
	public abstract void display();
	public abstract void typing();
	
	public void turnOn() {
		System.out.println("전원을 컵니다.");
	}
	public void turnOff() {
		System.out.println("전원을 끕니다");
	}
}

computerTEST.java

package ch9;

public class computerTEST {
	public static void main(String[] args) {
		Desktop desktop = new Desktop();
		desktop.display();
//		computer computer = new computer();
//===예러가 발생됩니다 ===

// 아래처럼 로 메서드를 오버라이드 하면 사용할수 있다	
//		computer computer = new computer() {
//			
//			@Override
//			public void typing() {
//				// TODO Auto-generated method stub
//				
//			}
//			
//			@Override
//			public void display() {
//				// TODO Auto-generated method stub
//				
//			}
//		};
	}
}

Desktop.java

package ch9;

public class Desktop extends computer {

	@Override
	public void display() {
		System.out.println("Desktop display");

	}

	@Override
	public void typing() {
		System.out.println("Desktop typing");

	}
	//재정의 해봅시다.
	@Override
	public void turnOff() {
		System.out.println("Desktop turnOff");
	}

}

MyNoteBook.java

package ch9;

public class MyNoteBook extends NoteBook {

	@Override
	public void typing() {
		System.out.println("MyNoteBook typing");

	}

}

NoteBook.java

package ch9;

public abstract class NoteBook extends computer {

	@Override
	public void display() {
		System.out.println("NoteBook display");
	}
}

복습 & 실무적인 사용방법


10. 추상 클래스를 활용한 템플릿 메서드 패턴


이론 정리

템플릿 메서드

정의

실질적으로는 프레임워크 제작을 위한 디자인 패턴

본 강좌에서는 실무 : 프레임 워크 재작에만 기준을 두고 진행

( 컴퓨터 공학에서 템플릿 메서드는 여려 클레스 에서 사용하기 위한 용도로 정의하는 변하지 않는 상위 클레스에 불과하다, )

프레임워크와 라이브러리

공통점 : 이미 만들어진 재료 혹은 단위를 가지고 원하는 것을 재작할수 있도록 돕는다.

라이브러리 : 종류) JDK

개발의 흐름을 개발자가 설계

프레임워크 : 종류) 안드로이드

  • 정해져 있는 개발의 흐름 대로 빈칸을 채우는 형식 으로 개발한다. 그로인해 생산성, 접근성 . 퀄리티, 안전성 향상

구조

메서드 혹은 추상 메서드를 활용해서 시나리오(흐름 : 알고리즘)을 정의 한다.

추상클레스를 상속받은 클레스에서 메서드를 정의 하여 사용한다.

  • 추상 클레스를 final로 선언하여 상속받지 못하게 함으로서 하위클레스 에서 흐름을 망가트릴수 있는 메서드의 재정의(변조)를 제한 한다. 오직 추상 메소드의 코드부(중괄호 : BODY)를 정의해서 사용하게 한다.

다이어 그램

이텔릭체 폰트(기울어진 글씨)로 추상 클레스의 이름을 적고 하단에 메소드명를 적는다.

영어 단어

추상 클레스 : AbstractClass

추상 클레스를 상속받는 클레스 : ConcreteClass

디자인 패턴의 종류 : Behavioral(행위) : 행위의 분배

추상 메소드 : primitive

<스스로 과제>

  1. 라면 템플릿 클레스로 너구리 ,열라면 만들기 과정 콘솔에 출력하기
  2. 자동차 템플릿 클레스로 수동기어, 자동기어 자동차 출발시키기

예제 코드 )

AICar.java

package ch3_10;

public class AICar extends Car {

	@Override
	public void drive() {
		System.out.println("자율 주행을 합니다");
		System.out.println("자동차가 스스로 방향을 바꿉니다");
	}

	@Override
	public void stop() {
		System.out.println("장애물 앞에서 스스로 정차 합니다");
		
	}

}

Car.java

package ch3_10;

public abstract class Car {
	public abstract void drive();
	public abstract void stop();
	
	public void turnOn() {
		System.out.println("시동을 켭니다");
	}
	public void turnOff() {
		System.out.println("시동을 끕니다");
	}
	public final void run() { // 
		turnOn();
		drive();
		stop();
		turnOff();
		// 순서가 중요합니다. 순서대로 진행 되도록 설계한것이 변하지 않도록. final을 붙여 줍니다.
	}
}

CarTest.java

package ch3_10;

public class CarTest {

	public static void main(String[] args) {
		Car aiCar = new AICar();
		aiCar.run();
		System.out.println( );
		Car mCar = new ManualCar();
		mCar.run();

	}

}

ManualCar.java

package ch3_10;

public class ManualCar extends Car {

	@Override
	public void drive() {
		System.out.println("사람이 운전합니다");
		System.out.println("사람이 핸들을 조작합니다");
	}

	@Override
	public void stop() {
		System.out.println("장애물 앞에서 브레이크를 밟아서 정지합니다.");
	}

}

복습 & 실무적인 사용방법


전문 용어


에러 메세지


학습 타이머


캠 스터디


스터디 그룹

1) 카카오톡 오픈 채팅방

  - 모르는것 질문하기

  - 이해가 가지 않는 부분을 다른 분들이 블로그에서 정리한 글을 살펴보고 참고 하기

2) 구루미 온라인 독서실

  - 학습 시간 관리하기

  - 남들과 경쟁하기 

 

온라인 강의 주소

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

 


 3:1:01 ~ 3:1:06 복습


앞 챕터 까지 복습

1. 상속

  • 잘못된 일반적인 계념 : 코드의 재사용
  • 올바른 계념 : 객체가 갖고 있는 계념의 확장
  • 다이어드램 작성법 : 하위 클래스(상속받는 클레스)에서 상위클래스(상속하는 클레스)쪽으로 화살표 표시
  • 사용하는 방법 : 하위 클레스 extends 상위 클레스 / extends(영문뜻 : 연장하다, 확장하다 )
  • 자바의 안전성 향상을 위해 단일상속만 지원 , 이전의 언어들에서 다중 상속으로 상속 관계의 모호성이 나타남
  • 표현법
    • 상속 하는 클레스 : 상위 클레스, parent class , base class , super class
    • 상속 받는 클레스 : 하위 클레스, child class , derived(더라이브 : 파생 ) class, subclass

2. 멤버십 구현하기.

  • ratio : 비율

3. 상속의 과정

  • default constructer = 매게변수가 없는 생성자( 묵시적으로 자동 생성되는 생성자.)

3.5 형변환

상위 클래스로 생성하고 .하위클레스 인스턴스로 생성하는것.

  • 자신의 클레스보다 하위 계층으로 생성자를 사용해서 생성하면 자신의 명령어,변수와 하위 계층의 명령어에 접근 할수 있다.

Customer

package ver3;

public class Customer {
// 아이디, 이름 , 등급 , 포인트 , 적립비율(일반고객:1%,VIP:10%)
	private int customerID; // 고객 아이디 : 개인 정보
	protected String customerName; // 고객이름 : 개인 정보
	protected String customerGrade; //등급  : 개인 정보
	int bonusPoint; // 포인트
	double bonusRatio; // 적립비율
	
//	String agentID;
//	double saleRatio;
//	만약 VIP일 경우에도 Customer를 사용한다면 등급을 입력받고 . 등급에 따라서 할인율을 변경해주도록 할수 있다.
//  IF else If else 가 많아지면 !!(상속을 고민해볼 타이밍 이다)
	
	/*
	public Customer() {
		// 모든 고객이 똑같다면 생성자에 넣을 필요 있나요?
		customerGrade ="SILVER";
		bonusRatio = 0.01;
		
		System.out.println("Customer() call");
	}
	*/
	
	public Customer(int customerID,String customerName) {
		this.customerID=customerID;
		this.customerName=customerName;
		customerGrade ="SILVER";
		bonusRatio = 0.01;
		System.out.println("customer call(int,String)");
	}
	
	public int calcPrice(int price) {
		bonusPoint += price * bonusRatio;
		return price;
	}
	
	public String showCustomerInfo() {
		return customerName +"님의 등급은"+customerGrade+"이며 , 보너스 포인트는"+bonusPoint+"입니다";
	}
	
	public int getCustomerID() {
		return customerID;
	}
	
	public void setCustomerID(int customerID) {
		this.customerID = customerID;
	}
	
	public String getCustomerName() {
		return customerName;
	}
	
	public void setCustomerName(String customerName) {
		this.customerName = customerName;
	}
	
	public String getCustomerGrade() {
		return customerGrade;
	}
	public void setCustomerGrade(String customerGrade) {
		this.customerGrade = customerGrade;
	}
	public int getBonusPoint() {
		return bonusPoint;
	}
	public void setBonusPoint(int bonusPoint) {
		this.bonusPoint = bonusPoint;
	}
	public double getBonusRatio() {
		return bonusRatio;
	}
	public void setBonusRatio(double bonusRatio) {
		this.bonusRatio = bonusRatio;
	}
	
}

CustomerTEST

package ver3;

public class CustomerTEST {
public static void main(String[] args) {
	Customer customerLee = new Customer(10010,"이순신");
	/*
	customerLee.setCustomerName("이순신");
	customerLee.setCustomerID(10010);
	*/
	customerLee.bonusPoint = 1000;
	System.out.println(customerLee.showCustomerInfo());
	
	VIPCustomer customerkim = new VIPCustomer(10020,"김유신");
	/*
	customerkim.setCustomerName("김유신");
	customerkim.setCustomerID(10020);
	*/
	customerkim.bonusPoint = 10000;
	System.out.println(customerkim.showCustomerInfo());
}
}

VIPCustomer

package ver3;

public class VIPCustomer extends Customer {
	// Customer의 속성 아이디, 이름 , 등급 , 포인트 , 적립비율(일반고객:1%,VIP:10%)
//		private int customerID; // 고객 아이디 : 개인 정보
//		private String customerName; // 고객이름 : 개인 정보
//		private String customerGrade; //등급  : 개인 정보
//		int bonusPoint; // 포인트
//		double bonusRatio; // 적립비율
//ㄴ 상속으로 사용하지 않을수 있게 되었습니다.
		
		double salesRatio;
		private String agentID;
		
	/*	public VIPCustomer() {
			// 모든 고객이 똑같다면 생성자에 넣을 필요 있나요?
			bonusRatio = 0.05;
			salesRatio = 0.1; // 할인율을 소수점으로 적어요.
			customerGrade ="VIP";
			
			System.out.println("VIPCustomer() call");
//			super() 상위 계층 생성자.
		} 
		*/
		public VIPCustomer(int customerID,String customerName) {
			super(customerID, customerName);
			bonusRatio = 0.05;
			salesRatio = 0.1; // 할인율을 소수점으로 적어요.
			customerGrade ="VIP";
			
			System.out.println("VIPCustomer(int,String) call");
		}

		public double getSalesRatio() {
			return salesRatio;
		}

		public void setSalesRatio(double salesRatio) {
			this.salesRatio = salesRatio;
		}

		public String getAgentID() {
			return agentID;
		}

		public void setAgentID(String agentID) {
			this.agentID = agentID;
		}
	
}

4. 메서드 재정의 하기 ( 오버 라이딩 하기 )

  • 상위 클레스에서 구현된 메서드를 하위 클레스에서 다시 정리하여 다르게 사용하기
    • 메스드의 이름과 매게변수가 같으면 제정의 할수 있다. @override를 하면 잘 구현 되었는지 확인할수 있기 때문에 꼭 사용 하기로 한다. ( 에너케이션:주석 하기 )
    • 알트 + 시프트 + S 후 sorce 에서 overriding을 하면 상위 클레스의 메소드를 선택해서 제정의 할후있는 편의 기능이 있다.
  • 클레스,객체 형변환
    • 가상 메서드로 메서드가 사용된다.
      • 변수는 기존의 인스턴스에 저장 되어있는 변수를 쓰지만 .메서드는 생성자를 따라간다 : 생성자로 인스턴스의 타입을 변화 시킬수 있다.
        • 상위 객체로 변환시키면 업스케일링
          • 기존의 맴벼번수 그대로. 하위 객체의 메서드를 사용한다.
        • 하위 객체로 변환시키면 다운 스케일링이다.

5. 가상 메서드

  • 인스턴스 생성시 변수와 메서드는 따로 공간이 있기 때문에 가상 메서드가 가능하다.
  • 메서드는 코드영역(static)에서 메서드 테이블로 메서드명과 주소값이 일치하는지 호출되면 검색한다.
  • 메서드는 다중 인스턴스 생성시 인스턴스 별로 생성되지 않는다.
  • 메서드가 호출되면 지역변수들은 스택 영역에 생성 된다.
    • 스택 영역에는 인스턴스의 주소값도 저장 된다.
    • 인스턴스의 변수는 힙메모리에 생성된다.

6. 다형성

  • 가상메소드 테이블은 클레스 마다 따로 있어서 같은 이름의 메소드도 클레스마다 다르게 호출 됩니다.
  • main안에 있는 메소드는 자신을 인스턴스로 만들어야 사용할수 있다.
    • 혹은 main의 외부에서 sctatic 생성자로 만들면 된다

Animal.java

package Animal;

public class Animal {
	void doing() {
		System.out.println("동물이 움직입니다");
	}
}

ant.java

package Animal;

public class ant extends Animal {
	void doing() {
		System.out.println("개미가 집을 짓습니다");
	}
}

bard.java

package Animal;

public class bard extends Animal {
	void doing() {
		System.out.println("새가 날라갑니다.");
	}
}

cat.java

package Animal;

public class cat extends Animal {
	void doing() {
		System.out.println("고양이가 잡을 잡니다.");
	}
}

Doing.java

package Animal;

public class Doing {
	public static void main(String[] args) {
	
	Animal antAnimal = new ant();
	Animal bardAnimal = new bard();
	Animal catAnimal = new cat();
	Animal humanAnimal = new human();
	doing(antAnimal);
	doing(bardAnimal);
	doing(catAnimal);
	doing(humanAnimal);
}//?
	public static void doing(Animal animal) {
		animal.doing();
	}
}

human.java

package Animal;

public class human extends Animal{
	void doing() {
		System.out.println("동물이 움직입니다");
	}
}

다형성을 사용하는 이유

  • 상속을 사용하지 않고 if문으로만 사용한다면.
  • if{ 동물
    • if{ 조류
      • if{ 사이즈
        • }}}
  • 처럼 복잡해질수 있습니다
  • goldClass를 만들때 super탭을 선택해서 superClass를 선택해주면 상속관계상태에서 생성됩니다.
  • 기존의 코드가 객체 지향적으로 구성된 상태라면. 코스의 수정이나 기능추가시에도 편의성을 갖을수 있다.

<다형성의 사용예>

Customer.java

package ver5;

public class Customer {
// 아이디, 이름 , 등급 , 포인트 , 적립비율(일반고객:1%,VIP:10%)
	private int customerID; // 고객 아이디 : 개인 정보
	protected String customerName; // 고객이름 : 개인 정보
	protected String customerGrade; //등급  : 개인 정보
	int bonusPoint; // 포인트
	double bonusRatio; // 적립비율
	
//	String agentID;
//	double saleRatio;
//	만약 VIP일 경우에도 Customer를 사용한다면 등급을 입력받고 . 등급에 따라서 할인율을 변경해주도록 할수 있다.
//  IF else If else 가 많아지면 !!(상속을 고민해볼 타이밍 이다)
	
	/*
	public Customer() {
		// 모든 고객이 똑같다면 생성자에 넣을 필요 있나요?
		customerGrade ="SILVER";
		bonusRatio = 0.01;
		
		System.out.println("Customer() call");
	}
	*/
	
	public Customer(int customerID,String customerName) {
		this.customerID=customerID;
		this.customerName=customerName;
		customerGrade ="SILVER";
		bonusRatio = 0.01;
	}
	
	public int calcPrice(int price) {
		bonusPoint += price * bonusRatio;
		return price;
	}
	
	public String showCustomerInfo() {
		return customerName +"님의 등급은"+customerGrade+"이며 , 보너스 포인트는"+bonusPoint+"입니다";
	}
	
	public int getCustomerID() {
		return customerID;
	}
	
	public void setCustomerID(int customerID) {
		this.customerID = customerID;
	}
	
	public String getCustomerName() {
		return customerName;
	}
	
	public void setCustomerName(String customerName) {
		this.customerName = customerName;
	}
	
	public String getCustomerGrade() {
		return customerGrade;
	}
	public void setCustomerGrade(String customerGrade) {
		this.customerGrade = customerGrade;
	}
	public int getBonusPoint() {
		return bonusPoint;
	}
	public void setBonusPoint(int bonusPoint) {
		this.bonusPoint = bonusPoint;
	}
	public double getBonusRatio() {
		return bonusRatio;
	}
	public void setBonusRatio(double bonusRatio) {
		this.bonusRatio = bonusRatio;
	}
	
}

CustomerTEST.java

package ver5;

import java.util.ArrayList;

public class CustomerTEST {
public static void main(String[] args) {
	ArrayList<Customer> customerList = new ArrayList<>();
	
	Customer customerT = new Customer(10010, "tomas");
	Customer customerJ = new Customer(10020, "James");
	Customer customerE = new GoldCustomer(10030, "Edward");
	Customer customerP = new GoldCustomer(10040, "Percy");
	Customer customerK = new VIPCustomer(10050, "Kim");

		customerList.add(customerT);
		customerList.add(customerJ);
		customerList.add(customerE);
		customerList.add(customerP);
		customerList.add(customerK);
		int price = 10000;
		for (Customer customer : customerList) {
			int cost = customer.calcPrice(price);
			System.out.println(customer.getCustomerName()+"님이"+cost+"원 지불 하셨습니다.");
			System.out.println(customer.getCustomerName()+"님의 현재 보너스 포인트는"+customer.bonusPoint+"입니다");
		}

}
}

GoldCustomer.java

package ver5;

public class GoldCustomer extends Customer {
	
	double salesRatio;
	
	public GoldCustomer(int customerID,String customerName) {
		super(customerID,customerName);
		
		salesRatio = 0.1;
		bonusRatio = 0.02;
		customerGrade ="GOLD";
		
	}
	public int calcPrice(int price) {
		bonusPoint += price * bonusRatio;
		return price-(int)(price*salesRatio);
	}
}

VIPCustomer.java

package ver5;

public class VIPCustomer extends Customer {
	// Customer의 속성 아이디, 이름 , 등급 , 포인트 , 적립비율(일반고객:1%,VIP:10%)
//		private int customerID; // 고객 아이디 : 개인 정보
//		private String customerName; // 고객이름 : 개인 정보
//		private String customerGrade; //등급  : 개인 정보
//		int bonusPoint; // 포인트
//		double bonusRatio; // 적립비율
//ㄴ 상속으로 사용하지 않을수 있게 되었습니다.
		
		double salesRatio;
		private String agentID;
		
	/*	public VIPCustomer() {
			// 모든 고객이 똑같다면 생성자에 넣을 필요 있나요?
			bonusRatio = 0.05;
			salesRatio = 0.1; // 할인율을 소수점으로 적어요.
			customerGrade ="VIP";
			
			System.out.println("VIPCustomer() call");
//			super() 상위 계층 생성자.
		} 
		*/
		public VIPCustomer(int customerID,String customerName) {
			super(customerID, customerName);
			bonusRatio = 0.05;
			salesRatio = 0.1; // 할인율을 소수점으로 적어요.
			customerGrade ="VIP";
			
		}
				
		@Override
		public int calcPrice(int price) {
			bonusPoint += price * bonusRatio;
			price -= (int)price * salesRatio;
			return price;
		}

		public double getSalesRatio() {
			return salesRatio;
		}

		public void setSalesRatio(double salesRatio) {
			this.salesRatio = salesRatio;
		}

		public String getAgentID() {
			return agentID;
		}

		public void setAgentID(String agentID) {
			this.agentID = agentID;
		}
	
}

07. 상속은 언제 사용 할까


이론 정리

IS-A 관계(is a relationship : inhertance)

  • 일반적인(general) 개념과 구체적인(spectific)개념과의 관계
    • 기존에 명확한 의미를 갖고 있는 객체에
      • 조금더 세분화된 객체의 의미를 확장 : 연장 하는것.
      • 예제 )
        • 인간(general) > 손님(spectific)
        • 직원(employee) > 인턴(Intern)
        • 스마트폰 > 안드로이드
        • 노트북 > 씽크패드
    • 다형성이 좋은 코드 짜기
      • 상위에서 사용한 변수는 사용할수 있도록한다.
      • 복잡하지 않게 구조를 짠다.
      • 계층이 길어지지 않게 짠다.
  • 사용하기 좋은 클레스가 있을때
  • 코드 제사용 계념으로 사용하면 나중에 상위 계층의 코드를 수정해야 할때 하위 계층은 전부 버그가 발생 될수 있을만큼 상속관계로 인해 결합되는 결합도가 매우 높다.

HAS-A 관계(composition : 구성 : 포함 )

  • 상속을 사용하지 않습니다.
  • Computer클래스(CPU클래스 , RAM클래스)
  • 이전 코드 중에서 student 클레스가 Subject의 클레스들을 갖고 있었던 구조
    • 클레스를 내부에서 생성해서 내부 클레스의 메소드까지 사용하는 경우
  • 코드 재사용의 가장 일반적인 방법

복습 & 실무적인 사용방법


08. 다운 캐스팅과 instanceof


이론 정리

  • 업케스팅 됬던 객체를 다운케스팅 했을 경우에만 클레스 간의 형변환을 사용할수 있다. 
  • 오브젝트 클레스로 반환 되는 경우( 오브젝트 클레스는 최상위 클레스 이기 때문에, 모든 클레스가 업케스팅이 가능합니다.)
  • 업 케스팅은 묵시적으로 작동. 다운 케스팅은 묵시적으로 일어나지 않기 떄문에 직접 구연할 필요가 있다.
  • 업케스트는 인플리스트 (묵시적으로) 다운 케스트는 명시적으로 진행 되야 합니다.

하위 클레스로 변경하는 방법

customer customerA = new VIPCustomer();

VIPCustomer customerA = (VIPCustomer)customerA;

(자료형 형변환과 똑같음)

하위 클레스로 변경하는 상황

  1. 하나의 상위 클레스를 상속받는 객체가 두개(A,B) 인데.

상속바받는 객체 A에서 B로 자료형을 이동하고 싶을 경우에 사용하게 된다.

  • A → 상위 클래스 형변환(업케스팅) → 하위 클래스 형변환(다운 케스팅)
  • 만약 A →B 로 바로 형변환을 하면 이클립스에서는 에러를 발견하지 못하지만 컴파일에러가 출력되거나. 작동시 프로그램이 죽는다.
  • 프로그램이 죽는것을 방지하기 위해서 객채의 타입을 변경할때는 A instanceof B를 사용해서 자료형을 IF문으로 채크한뒤 변경해야 한다.
  1. 업케스팅을 했지만 하위 클레스의 메소드를 사용하기 위해서 다시 다운 케스팅을 해야할때 사용한다. 메소드 오버 라이딩으로 작성하는편이 코드가 깔끔해 진다.

A instanceof B

  • A 인스턴스가 B클레스를 기반으로 만든 자료형(타입)이 맞는지 확인.true false 출력됨

복습 & 실무적인 사용방법


전문 용어


에러 메세지


학습 시간


캠 스터디

 


스터디 그룹

1) 카카오톡 오픈 채팅방

  - 모르는것 질문하기

  - 이해가 가지 않는 부분을 다른 분들이 블로그에서 정리한 글을 살펴보고 참고 하기

2) 구루미 온라인 독서실

  - 학습 시간 관리하기

  - 남들과 경쟁하기 

 

온라인 강의 주소

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

 

+ Recent posts