package coffeeshop.test;
class Data1 {
// 오브젝트 자료형은 받기는 쉬우나 받은뒤 사용하려면 캐스팅 해야하기 때문에 불편
Object data;
}
// 제네릭
class Data <T> {
T value;
}
// 콤마를 통해서 두개를 넣을 수 있다
class Str<K, V>{
K k;
V v;
}
public class GenericEx01 {
public static void main(String[] args) {
Data1 data1 = new Data1();
data1.data = "오브젝트자료형";
System.out.println((String)data1.data);
Data<String> data = new Data<>();
data.value = "제네릭문자열";
System.out.println(data.value);
// 제네릭에는 기본자료형이 들어갈 수 없다 (Wrapper 클래스로 감싸야한다)
// Wrapper 클래스 = 기본자료형에 첫글자에 대문자(클래스자료형처럼) (기본자료형의 수만큼 있음)
// int -> Integer / char -> Character
Data<Integer> data2 = new Data<>();
data2.value = 10;
System.out.println(data2.value);
Str<String, String> s = new Str<>();
s.k = "비밀번호";
s.v = "bitc5500";
System.out.println(s.k);
System.out.println(s.v);
}
}
package composite;
import lombok.Data;
@Data // getter, setter 생성
public class Burger {
private int price;
private String desc;
public Burger() {
this(1500, "기본버거");
}
public Burger(int price, String desc) {
this.price = price;
this.desc = desc;
System.out.println(desc + "가 만들어졌습니다.");
}
}
package composite;
import lombok.Data;
@Data
public class Coke {
private int price;
private String desc;
public Coke() {
this(1500, "코카콜라");
}
public Coke(int price, String desc) {
this.price = price;
this.desc = desc;
System.out.println(desc + "가 만들어졌습니다.");
}
}
package composite;
import lombok.Data;
@Data
public class FrenchFried {
private int price;
private String desc;
public FrenchFried() {
this(2000, "감자칩");
}
public FrenchFried(int price, String desc) {
this.price = price;
this.desc = desc;
System.out.println(desc + "이 만들어졌습니다.");
}
}
버거를 상속 받아 빅버거와 쉬림프버거를 만든다
package composite;
public class BigBurger extends Burger {
public BigBurger() {
super(4000, "빅버거");
}
public BigBurger(int price, String desc) {
super(price, desc);
}
}
package composite;
public class ShrimpBurger extends Burger {
public ShrimpBurger() {
super(3500, "쉬림프버거");
}
public ShrimpBurger(int price, String desc) {
super(price, desc);
}
}
콤포지션
- 상속이 아닌 만들어 놓은 클래스를 가져오는 것
빅버거, 쉬림프버거, 감자튀김, 콜라 를 이용해서 세트를 만들기
package composite;
import lombok.Data;
// 자바는 다중 상속이 안됨 (부모가 여럿이 될 수 없음)
@Data
public class BigBurgerSet {
// 콤포지션(중요) - 상속이 아닌 만들어 놓은 클래스를 가져오는 것
private BigBurger bigBurger;
private Coke coke;
private FrenchFried frenchFried;
public BigBurgerSet() {
this(new BigBurger(), new Coke(), new FrenchFried());
}
public BigBurgerSet(BigBurger bigBurger, Coke coke, FrenchFried frenchFried) {
this.bigBurger = bigBurger;
this.coke = coke;
this.frenchFried = frenchFried;
}
}
package composite;
import lombok.Data;
@Data
public class ShrimpBurgerSet {
// 콤포지션(중요) - 상속이 아닌 만들어 놓은 클래스를 가져오는 것
private ShrimpBurger shrimpBurger;
private Coke coke;
private FrenchFried frenchFried;
public ShrimpBurgerSet() {
this(new ShrimpBurger(), new Coke(), new FrenchFried());
}
public ShrimpBurgerSet(ShrimpBurger shrimpBurger, Coke coke, FrenchFried frenchFried) {
this.shrimpBurger = shrimpBurger;
this.coke = coke;
this.frenchFried = frenchFried;
}
}
실행 파일을 만들어서 실행해보기
package composite;
public class LotteriaApp {
public static void main(String[] args) {
// 빅버거 세트
BigBurgerSet set1 = new BigBurgerSet();
System.out.println();
// 기본버거
Burger burger1 = new Burger();
System.out.println();
// 콜라
Coke coke1 = new Coke();
System.out.println();
// BigBurgerSet
BigBurgerSet set2 = new BigBurgerSet(
new BigBurger(3000, "빅버거할인"),
new Coke(),
new FrenchFried()
);
System.out.println();
BigBurgerSet set3 = new BigBurgerSet(
new BigBurger(2000, "빅버거할인"),
new Coke(),
new FrenchFried()
);
System.out.println();
// 새우버거 세트 추가요
ShrimpBurgerSet set4 = new ShrimpBurgerSet();
System.out.println();
}
}
생성자 오버로딩
package composite;
import lombok.Data;
@Data
public class ShrimpBurgerSet {
// 콤포지션(중요) - 상속이 아닌 만들어 놓은 클래스를 가져오는 것
private ShrimpBurger shrimpBurger;
private Coke coke;
private FrenchFried frenchFried;
public ShrimpBurgerSet() {
this(new ShrimpBurger(), new Coke(), new FrenchFried());
}
public ShrimpBurgerSet(ShrimpBurger shrimpBurger) {
this(shrimpBurger, new Coke(), new FrenchFried());
}
public ShrimpBurgerSet(Coke coke) {
this(new ShrimpBurger(), coke, new FrenchFried());
}
public ShrimpBurgerSet(FrenchFried frenchFried) {
this(new ShrimpBurger(), new Coke(), frenchFried);
}
public ShrimpBurgerSet(ShrimpBurger shrimpBurger, Coke coke) {
this(shrimpBurger, coke, new FrenchFried());
}
public ShrimpBurgerSet(ShrimpBurger shrimpBurger, FrenchFried frenchFried) {
this(shrimpBurger, new Coke(), frenchFried);
}
public ShrimpBurgerSet(Coke coke, FrenchFried frenchFried) {
this(new ShrimpBurger(), coke, frenchFried);
}
// 생성자가 제일 많은 것이 기준
public ShrimpBurgerSet(ShrimpBurger shrimpBurger, Coke coke, FrenchFried frenchFried) {
this.shrimpBurger = shrimpBurger;
this.coke = coke;
this.frenchFried = frenchFried;
}
public static void main(String[] args) {
ShrimpBurgerSet s1 = new ShrimpBurgerSet(new Coke(), new FrenchFried());
}
}
package animal;
// 인터페이스의 변수와 함수
// 1. 변수 : public static final 생략
// 2. 함수 : public abstract 생략
// 3. 통로의 역할 - 동적 바인딩
// 4. 무조건 추상메서드만 존재가능 -> 강제성부여
// 5. new 할 수 없다
// 고정된 범위의 값을 주는 것을 [도메인]을 준다고 한다
interface 부서 {
int 총무과 = 10; // 공통코드
int 생산팀 = 20; // 공통코드
int 인사과 = 30; // 공통코드
int 행정과 = 40; // 공통코드
}
interface Cal {
int num = 10; // 인터페이스의 변수는 무조건 public static final 이다.
}
public class InterfaceEx01 {
public static void main(String[] args) {
System.out.println(Cal.num);
}
}
package stars1;
// 인터페이스는 추상 클래스와 유사
// 다른점 : 추상 메서드만 존재가능
// 동적 바인딩의 통로로만 사용
// 메서드에 public abstract를 생략가능
// 제작자와 이용자의 약속 - 키보드에서 a를 누르면 작동원리를 몰라도 컴퓨터에 a가 입력된다
// 프로토콜 : 동등한 관계의 상호 협의하에 이루어진 약속
// 인터페이스 : 제작자가 사용법만 알려주고 이용자가 사용하는 식의 약속
public interface Behavior {
public abstract void move();
public void repair();
void attack(Behavior unit);
public String getName();
public int getHp();
public void setHp(int hp);
}
추상클래스
package stars1.protoss;
import stars1.Behavior;
public abstract class Protoss implements Behavior {
// 움직임과 쉴드 치료는 프로토스 유닛 공통이기 때문에 추상 클래스에 바로 만들어준다
// 이렇게 만든 공통 메서드들은 구체클래스들에 구현하지 않아도 되서 어댑터 역할도 한다
@Override
public void move() {
System.out.println("이동");
}
@Override
public void repair() {
System.out.println("쉴드 치료");
}
public static void upgrade() {
Zealot.attack++;
Dragoon.attack++;
System.out.println("프로토스 업그레이드 완료");
}
}
일반 클래스
package stars1.protoss;
import stars1.Behavior;
public class Zealot extends Protoss {
private String name;
private int hp;
private int sh; // 보호막
public static int attack = 10;
public Zealot(String name) {
this.name = name;
this.hp = 100;
this.sh = 100;
}
@Override
public void attack(Behavior unit) {
unit.setHp(unit.getHp() - attack);
System.out.println(unit.getHp());
}
@Override
public int getHp() {
return hp;
}
@Override
public void setHp(int hp) {
this.hp = hp;
}
@Override
public String getName() {
return name;
}
}
메인
package stars1;
import stars1.protoss.Dragoon;
import stars1.protoss.Protoss;
import stars1.protoss.Zealot;
public class StartGame {
public static void move(Behavior b) {
b.move();
}
public static void repair(Behavior b) {
b.repair();
}
public static void attack(Behavior b1, Behavior b2) {
System.out.println(b1.getName() + "이 " + b2.getName() + "을 공격했습니다.");
System.out.println(b2.getName() + "의 현재 체력");
b1.attack(b2);
}
public static void main(String[] args) {
Protoss.upgrade();
Zealot z1 = new Zealot("질럿1");
Zealot z2 = new Zealot("질럿2");
Dragoon d1 = new Dragoon("드라군1");
attack(z1, d1);
repair(z1);
}
}
주의 : 이클립스 또는 STS를 한글디렉토리 또는 띄어쓰기가 있는 디렉토리에 설치하신 분은 프로그램이 실행 안될 가능성이 있습니다. 띄어쓰기 없는 영문명 디렉토리에 IDE를 설치해주세요
롬복을 사용하면 게터와 세터를 자동으로 만들어준다
package stars1.protoss;
import lombok.Data;
@Data
public class Zealot{
private String name;
private int hp;
private static int attack;
public static void main(String[] args) {
Zealot z1 = new Zealot();
z1.getName();
z1.setHp(10);
}
}
게터만 만들려면
package stars1.protoss;
import lombok.Getter;
@Getter
public class Zealot{
private String name;
private int hp;
private static int attack;
public static void main(String[] args) {
Zealot z1 = new Zealot();
z1.getName();
z1.setHp(10);
}
}
롬복 디폴트생성자, 모든 변수 생성자, 게터 세터
package stars1.protoss;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
// 어노테이션 - 컴파일러가 읽고 해당 내용을 코드를 띄우기전에 먼저 동작
@AllArgsConstructor // 모든 힙 변수를 받는 생성자 자동생성
@NoArgsConstructor // 디폴트 생성자 자동생성
@Data // 게터와 세터 자동생성 @Getter @Setter 를 이용할 수도 있다.
public class Zealot{
private String name;
private int hp;
private static int attack;
}