소프트웨어 형상 관리
SCM
SW Config Mgt

버전관리시스템
VCS
Ver Ctr Sys

VCS에는 Git과 SVN 등이 있다. 

⭐Git 분산형 저장 시스템
⭐ SVN 중앙 집중형 저장 시스템

💀SVN은 안정성 문제.. 싹 날아갈 위험이 존재

 

👍그래서 원격지에 저장해 안정성을 높인 Git이 등장하게 됐다.

 

git은 데이터를 논리적인 3가지 상태로 분류한다.

working directory => staging area => repository ===> remote

저장소 안에 또 저장소를 쓸 수 없다.

 

git clone 주소
(git에 있는 코드들을 오프라인 폴더로 가져온다.)

⭐빈 공간에만 쓸 수 있다.

 

git init
(git 폴더 만들어짐)

git status

(폴더 상태 확인)

git -M main

(현 버전을 메인 브렌치로 설정)

 

branch
○ - ○ - ○
  └ ○ - ○


git add .
(요소들이 staging area에 옮겨짐)

git commit -m'버전명'

(요소들이 repository에 옮겨짐)

git push origin main

(요소들이 remote에 옮겨짐)

q

리셋


IDE인 인텔리제이는 Git 터미널을 제공하고 있다.

터미널 기능을 통해 코드를 작성하면서 바로바로 Git과 상호작용할 수 있다.

 

 

5번째 버전까지 누적된 모습

1.first commit 2.object class 3.string and stringbuffer 4.exception handling 5.thread...

 

4번째 버전으로 돌아가려면: 깃 체크아웃 헤드 캐럿

git checkout HEAD^

 

1번째 버전으로 돌아가려면:깃 체크아운 헤드 캐럿캐럿캐럿캐럿

git checkout HEAd^^^^

 

최신버전으로 돌아오려면

git checkout main

⭐인터페이스

Interface

객체의 동작을 정의하는 추상타입으로
클래스가 구현할 메서드의 설계도를 제공한다.

👍다형성
👍 유연성
👍 코드재사용성을 높일 수 있다.

 

예제 1)

인터페이스(동물 )

클래스(새,개)

설계를 통해 인터페이스 사용법을 알아봤다.

 

public interface Animal { //인터페이스

}

public class Bird implements Animal { //구현클래스

}

public class Dog implements Animal {  //구현클래스

}

package com.interface_.animal;
/**
 * 4.23 인터페이스
 *
 * How
 * Interface를 선언하면 된다.
 * 여기 안에 선언된 메서드는
 * 모두 추상메서드가 돼야 한다.
 *
 * Why?
 */
public interface Animal {

    //추상메서드 선언
    public abstract void eat(); // 메서드 선언부만 있고 바디가 없다.

    public void move(); // abstract 생략 가능

}//end of Animal
package com.interface_.animal;
/**
 * 4.23 인터페이스
 */
public class Bird implements Animal{

    @Override
    public void eat() {
        System.out.println("새가 모이를 먹는다");
    }

    @Override
    public void move() {
        System.out.println("새가 하늘을 난다");
    }
    
}//end of Bird
package com.interface_.animal;
/**
 * 4.23 인터페이스
 * <p>
 * 인터페이스는 상속이 아니라 구현받다, 구현하다 라고 말한다.
 * <p>
 * Animal 인터페이스를 구현받았다.
 */
public class Dog implements Animal {

    //추상메서드를 구현메서드로 재정의 해야 한다.
    @Override
    public void eat() {
        System.out.println("강아지가 먹이를 먹는다");
    }

    @Override
    public void move() {
        System.out.println("강아지가 달린다");
    }

    //main
    public static void main(String[] args) {

        //다형성 적용
        Animal dog = new Dog(); //업캐스팅 됐다
        Animal bird = new Bird();

        dog.eat();
        dog.move();
        System.out.println();
        bird.eat();
        bird.move();

    }//end of main

}//end of dog

 

예제 2)

인터페이스(리모콘,음향)

추상클래스(가전)

구현클래스(티비,냉장고,로봇,)

설계를 통해 인터페이스 사용법을 알아봤다.

 

⭐바텀업!

먼저 티비, 냉장고, 로봇 클래스를 만든 뒤

공통된 부분을 추상클래스로

동작 부분은 인터페이스로 선언해간다.

 

public interface RemoteController { //인터페이스

}

public interface SoundEffect { //인터페이스

}

 

public abstract class HomeAppliances { //추상클래스

}

 

public class TV extends HomeAppliances //추상클래스 상속

implements RemoteController, SoundEffect { //인터페이스 구현

}

public class Refrigerator extends HomeAppliances //추상클래스 상속

implements RemoteController , SoundEffect { //인터페이스 구현

}

public class Refrigerator implements Animal, SoundEffect { //인터페이스 구현

 

2-1.TV 클래스

package com.interface_.appliance;
/**
 * 4.23 인터페이스 2강
 */
public class Television extends HomeAppliances implements RemoteController {

//    //member
//    int width;
//    int height;
//    String color;
//
//    //method
//    public void turnOn() {
//        System.out.println("TV전원을 켠다");
//    }
//    public void turnOff() {
//        System.out.println("TV전원을 끈다");
//    }

    @Override
    public void turnOn() {
        System.out.println("티비 전원을 켠다");
    }

    @Override
    public void turnOff() {
        System.out.println("티비 전원을 끈다");
    }
    
}//end of TV

 

2-2.냉장고

package com.interface_.appliance;
/**
 * 4.23 인터페이스 2강
 */
public class Refrigerator extends HomeAppliances
        implements RemoteController, SoundEffect { // 인터페이스는 다중 구현이 가능하다.

    @Override
    public void turnOn() {
        System.out.println("냉장고 전원을 켠다");
    }

    @Override
    public void turnOff() {
        System.out.println("냉장고 전원을 끈다");
    }

    @Override
    public void soundOn() {
        System.out.println("냉장고 문이 열렸다고 경고한다");
    }
}//end of Refrige

 

2-3.장난감로봇

package com.interface_.appliance;
/**
 * 4.23 인터페이스 2강
 *
 * 지금처럼 장난감 로봇이 가전을 상속받는다면 혼동이 올 수 있다.
 *
 * 추상클래스보다
 * 더 유연한 설계기법이 필요하다.
 *
 * 그것이 인터페이스 Interface 다.
 */
public class ToyRobot implements RemoteController, SoundEffect {

    String name;

    @Override
    public void turnOn() {
        System.out.println("장난감 로봇을 켠다");
    }

    @Override
    public void turnOff() {
        System.out.println("장난감 로봇을 끈다");
    }

    @Override
    public void soundOn() {
        System.out.println("장난감 로봇이 소리를 낸다");
    }
    
}//end of TR

 

2-4.가전 (추상클래스)

package com.interface_.appliance;
/**
 * 4.23 인터페이스 2강
 */
public abstract class HomeAppliances implements RemoteController {

    //member
    int width;
    int height;
    String color;

//    //method
//    public void turnOn() {
//        System.out.println("전원을 켠다");
//    }
//    public void turnOff() {
//        System.out.println("전원을 끈다");
//    }

}//end of HA

 

2-5. 리모콘 (인터페이스)

package com.interface_.appliance;
/**
 * 4.23 인터페이스 2강
 *
 * 인터페이스 개념정리
 */
public interface RemoteController {

    /*
    ⭐인터페이스란

    구현된 것이 아무것도 없는
    밑 그림만 있는 기본 설계도다.

    모든 변수는 상수가 된다.
    public static final int N;

    모든 메서드는 추상메서드가 된다.
    심지어 abstract 키워드도 필요 없다.

    추상클래스보다 추상화 수준이 더 높다.

    ⭐Why
    인터페이스는
    동작 중심의 클래스를 선언해야 할 때 사용한다.

    인터페이스는 동작 중심이다.

    인터페이스는 표준이다.

    또는 강제성 있는 규약이다.
     */

    //오직 static final 상수만을 가질 수 있다.
    public static final int SERIAL_NUMBER = 100;

    //오직 abstract 추상 메서드만을 가질 수 있다.
    public abstract void turnOn();
    public void turnOff();

}//end of RemoteController

 

2-6. 음향(인터페이스)

package com.interface_.appliance;
/**
 * 4.23 인터페이스 2강
 */
public interface SoundEffect {

    //추상메서드
    public abstract void soundOn();

}//end of SE

 

2-7. 코드 실행부

package com.interface_.appliance;
/**
 * 4.23 인터페이스 2강
 */
public class MainTest1 {
    //main
    public static void main(String[] args) {
        /*
        인터페이스를 사용하면
        유연한 코드를 설계할 수 있다.
         */
        RemoteController[] remoteControllers = new RemoteController[3];

        remoteControllers[0] = new Television(); //다형성
        remoteControllers[1] = new Refrigerator();
        remoteControllers[2] = new ToyRobot();

        /*
        인터페이스는 표준이다.
        또는 강제성 있는 규약이다.
         */
        for (int i = 0; i < remoteControllers.length; i++) {
            remoteControllers[i].turnOn(); //한번에 모든 전원을 켰다.
        }

    }//end of main
}

 

예제 3)

다음 코드다이어그램(uml) 구현

 

 

Calc, 인터페이스로 작성

 

 

 

 

Claclator, 추상클래스로 작성

 

 

 

 

CompleteCalc, 구현클래스로 작성

 

 

 

⭐코드설계가 이미 완성돼 있다면

탑다운으로 작성하더라도 문제가 없다.

 

3-1.Calc(인터페이스) 작성

package com.interface_;
/**
 * 4.23 인터페이스 3강
 */
public interface Calc { //인터페이스 선언

    //인터페이스는 public abstract 생략 가능
    void add(int n1, int n2);
    void sub(int n1, int n2);
    void multi(int n1, int n2);
    void divide(int n1, int n2);

}//end of Calc

 

3-2. Calculator(추상클래스) 작성

package com.interface_;
/**
 * 4.23 인터페이스 3강
 */
public abstract class Calculator implements Calc {

}//end of Calculator

 

3-3. CompleteCalc(구현클래스) 작성

F2를 누르면 구현메서드를 딸깍하고 만들 수 있다.

package com.interface_;
/**
 * 4.23 인터페이스 3강
 */
public class CompleteCalc extends Calculator{

    @Override
    public void add(int n1, int n2) {

    }

    @Override
    public void sub(int n1, int n2) {

    }

    @Override
    public void multi(int n1, int n2) {

    }

    @Override
    public void divide(int n1, int n2) {

    }

}//end of CompleteCalc

 

 

 

⭐추상 클래스

abstract class

추상 메서드를 포함한 클래스

상속에서 사용되는 개념으로

객체로 만들기는 좀 애매할때 사용한다.

class 앞에 abstract가 붙으면 된다.


⭐추상 메서드

선언부만 있고 바디가 없는 형태

예 int add(int x, int y);

void 앞에 abstract가 붙으면 된다.

 

추상클래스를 (동물 - 인간, 호랑이) 관계를 통해 이해해봤다.

package com.abstract_.animal;
/**
 * 4.22 5교시 추상클래스
 * <p>
 * 추상클래스
 * abstract class
 * <p>
 * 하나 이상의 추상 메서드를 포함한 클래스
 * class 앞에 abstract가 뭍으면 추상클래스다.
 *
 * 강제적으로 타입으로만 설계하는 기법이다.
 *
 * abstract - 강제성
 */
public abstract class Animal { //추상클래스로 선언됐다.

    String name;

    public void move() {
        System.out.println("동물이 이동한다");
    }

    //추상메서드를 만들어보자
    public abstract void hunt();
    /*
    클래스 안에
    단 하나라도 추상 메서드를 가지고 있다면
    그 클래스는 반드시 추상 클래스가 돼야 한다.
     */

}//end of Animal

 

2. 자식클래스 호랑이

추상클래스를 상속받으면, 이렇게 오류가 발생한다. 해결방법은 1.자식클래스도 추상클래스로 변경 2.추상메서드를 구현메서드로 오버라이드 하는 방법이다.

package com.abstract_.animal;
/**
 * 4.22 5교시 추상클래스
 *
 * 추상클래스를 사용하는 이유
 *
 * 단 하나라도 추상메서드가 있으면 추상클래스다.
 */
public class Tiger extends Animal {

    @Override //오버라이드 하자 오류가 없어졌다
    public void hunt() {
        System.out.println("호랑이가 사냥을 한다");
    }

    @Override
    public void move() {
        System.out.println("호랑이가 살금살금 이동한다");
    }

}//end of Tiger

 

3.자식클래스이자 추상클래스인 인간을 설계해봤다.

package com.abstract_.animal;
/**
 * 4.22 5교시 추상클래스
 */
public abstract class Human extends Animal{


    @Override
    public void move() {
        System.out.println("사람이 두 발로 걷는다");
    }
}//end of Human

 

4. 인간 클래스의 자식클래스인 사람 클래스를 설계했다.

package com.abstract_.animal;
/**
 * 4.22 5교시 추상클래스
 */
public class Person extends Human{

    //구현 메서드로 만들어주면 된다.
    @Override
    public void hunt() {
        System.out.println("총으로 동물을 사냥한다");
    }
}//end of Person

 

5. 코드 실행부

추상클래스인 Animal, Human을 인스턴스화 하려고 하자 오류가 발생했다.

추상클래스를 객체 선언할 수 없다.

package com.abstract_.animal;
/**
 * 4.22 5교시 추상클래스
 */
public class MainTest1 {
    //main
    public static void main(String[] args) {
        /*
        객체지향 개념으로
        Animal이라는 클래스를 인스턴스화하면 좀 이상하다
         */
//        animal = new Animal(); // 오류발생

        /*
        Animal 클래스는
        abstract 키워드를 사용해
        추상 클래스로 설계됐다.

        추상 클래스는
        new 키워드 생성자를 활용해서
        독립적으로 메모리에 올릴 수 없다.

        개발자가 객체를 생성시킬 때
        다른 사용자가 마음대로 객체를 생성시키지 못하도록
        강제성을 줄 수 있다.
         */
//        Human human = new Human(); //오류 발생

    }//end of main
}//end of class

 

 

예제)

컴퓨터 - 데스크탑, 노트북 - 내노트북

상속관계와 추상클래스 처리 방법을 연습했다. 

 

1. 컴퓨터 클래스

package com.abstract_.computer;
/**
 * 4.22 5_1교시 추상클래스
 *
 * 추상클래스 상속
 * 메서드 오버라이드
 *
 * Computer
 * 부모클래스
 * 추상클래스
 */
public abstract class Computer {

    abstract void display();
    abstract void typing();

    void turnOn() { System.out.println("컴퓨터를 켭니다"); }
    void turnOff() { System.out.println("컴퓨터를 끕니다"); }

}//end of Computer

 

2-1. 데스크탑 클래스

구현클래스로 설계했다(완)

package com.abstract_.computer;
/**
 * 4.22 5_1교시 추상클래스
 * 구현클래스
 * Computer의 자식클래스
 */
public class DeskTop extends Computer {

    void display() { System.out.println("데스크탑 화면을 띄웁니다"); }
    void typing() { System.out.println("데스크탑에 문자를 입력합니다"); }

}//end of DeskTop

 

2-2. 노트북 클래스

추상클래스로 설계했다.

package com.abstract_.computer;
/**
 * 4.22 5_1교시 추상클래스
 * 추상클래스
 * Computer의 자식클래스
 */
public abstract class NoteBook extends Computer {

    void typing() { System.out.println("노트북에 글자를 입력합니다"); }

}//end of NoteBook

 

3. 내노트북 클래스

구현클래스로 설계했다(완)

package com.abstract_.computer;
/**
 * 4.22 5_1교시 추상클래스
 * 구현클래스
 * NoteBook의 자식클래스
 */
public class MyNoteBook extends NoteBook {

    void display() { System.out.println("내 노트북 화면을 띄웁니다"); }

}//end of MyNoteBook

 

4. 코드 실행부

데스크탑과 내노트북 클래스로 객체선언이 정상적으로 되는 것을 확인했다.

package com.abstract_.computer;
/**
 * 4.22 5_1교시 추상클래스
 * 코드 실행부
 */
public class ComperMainTest1 {
    //main
    public static void main(String[] args) {

        Computer computer1 = new DeskTop(); //다형성
        Computer computer2 = new MyNoteBook();

    }//end of main
}//end of class

 

⭐다형성
Polymorphism

하나의 데이터 타입을 다양한 형태로 바라볼 수 있다는 개념

한 요소가 여러 형태를 가질 수 있다는 가능성을 가리킨다.

⭐ 다형성의 장점은

부모 타입으로 자식 클래스를 인스턴스화 할 수 있다는 점이다.
이는 자바의 굉장한 기능이다.

다형성을 이해한다면
유연한 코드를 작성할 수 있다.

 

 

예제) 동물 클래스를 인간, 호랑이 클래스가 상속하게 하자

package com.polymorphism;
/**
 * 4.22 3교시 다형성
 */
public class Animal {

    public void move() {
        System.out.println("동물이 움직인다");
    }
    public void eat() {
        System.out.println("동물이 먹는다");
    }

}//end of Animal class

class Human extends Animal { // 상속 관계로 설정... 다형성

    @Override
    public void move() {
        System.out.println("사람이 걷는다");
    }
    @Override
    public void eat() {
        System.out.println("사람이 식사한다");
    }
    public void read() {
        System.out.println("사람이 읽는다");
    }

}//end of Human class

class Tiger extends Animal {

    @Override
    public void move() {
        System.out.println("호랑이가 활보한다");
    }
    public void hunt() {
        System.out.println("호랑이가 사냥한다");
    }

}//end of Tiger class

 

코드 테스트

package com.polymorphism;
/**
 * 4.22 3교시 다형성
 *
 * 다형성
 * 하나의 데이터 타입을 다양한 형태로 바라보는 것
 *
 * 한 메서드(클래스)가 여러 형태를 가질 수 있다.
 * 상속관계를 통해 다형성을 살펴본다.
 */
public class AnimalTest1 {
    //main
    public static void main(String[] args) {

        Animal animal1 = new Animal();
        animal1.move();
        animal1.eat();
        System.out.println();
        /*
        다형성의 장점

        부모 타입으로 자식 클래스를 인스턴스화 할 수 있다.

        이는 자바의 굉장한 기능
         */
        Animal animal2 = new Tiger(); //? 다형성.. 업캐스팅
        animal2.move();
        animal2.eat();
        System.out.println();
        /*
        코드를 작성하는 컴파일 시점
        프로그램을 실행하는 런타임 시점
         */
        Animal animal3 = new Human();
        animal3.move();
        animal3.eat();

    }//end of main
}//end of class

 

코드테스트2

package com.polymorphism;
/**
 * 4.22 3교시 다형성
 */
public class AnimalTest2 {

    //main
    public static void main(String[] args) {

        /*
        다형성
        하나의 메서드가
        여러 형태를 가질 수 있는 능력

        move()

        배열
        하나의 변수에 통으로 데이터를 관리하고 싶다면
         */
        Animal[] animals = new Animal[3];

        animals[0] = new Animal();
        animals[1] = new Tiger();
        animals[2] = new Human();

        for (int i = 0; i < animals.length; i++) {
            animals[i].move();
        }

    }//end of main
}//end of class



⭐업캐스팅 / 다운캐스팅

업캐스팅

부모클래스의 데이터타입으로
자식클래스의 객체를 대입하는 것을 말한다.

이는 자동으로 이뤄진다.

다운캐스팅

부모클래스의 참조변수를
자식클래스의 객체로 

((Banana) fruits[i]).saleBanana();

이 객체가 특정 클래스에 종속됐는지 확인하는 구문

if (fruits[i] instanceof Banana) {}

 

예제)

복숭아, 바나나 클래스를 만들고

부모클래스인 과일 클래스를 만들어보자

 

1. 복숭아 클래스

package com.polymorphism.fruits;
/**
 * 4.22 3_1교시 다형성
 *
 * 과일을 통해
 * 상속
 * 바텀업
 * 업캐스팅
 * 다운캐스팅 이해
 */
public class Peach extends Fruit {

//    String name;
//    int price;

    public Peach() {
        name = "춘식이복숭아";
        price = 5000;

    }

}//end of Peach

 

2. 바나나 클래스

바나나 클래스에는 고유의 멤버변수와 메서드를 넣었다.

package com.polymorphism.fruits;
/**
 * 4.22 3_1교시 다형성
 */
public class Banana extends Fruit {

    String ogrin; // Banana만의 멤버변수

        public Banana() {
            name = "델몬트바나나";
            price = 3000;
            ogrin = "필리핀";
        }

    public void saleBanana() {
        System.out.println("지금은 할인 기간입니다");
        System.out.println("이 방송이 나간 뒤(메서드호출) 바나나 가격을 천원 할인");
        price -= 1000;
    }

}//end of Banana

 

3. 부모클래스인 과일 클래스 설계

package com.polymorphism.fruits;
/**
 * 4.22 3_1교시 다형성
 */
public class Fruit {

    String name;
    int price;

    public Fruit() {
        name = "춘식이복숭아";
        price = 5000;

    }
    public void showInfo() {
        System.out.print("상품명: ");
        System.out.print(name + " ");
        System.out.print("가격: ");
        System.out.println(price + "원");
    }
}//end of Fruits

 

4. 코드 실행부

package com.polymorphism.fruits;
/**
 * 4.22 3_1교시 다형성
 *
 * 업캐스팅
 * 다운캐스팅
 */
public class FruitTest1 {
    //main
    public static void main(String[] args) {

        Fruit fruit1 = new Peach(); //업캐스팅된 상태
        Fruit fruit2 = new Banana();

        fruit1.showInfo();
        fruit2.showInfo();

        System.out.println();
        /*
        바나나의 원산지 정보를 출력하시오

        이 문제는
        컴파일 시점과 런타임 시점을 이해해야 한다.

        업캐스팅된 상태에서는
        컴파일 시점에 부모에 있는 변수나 메서드만 이해 가능
         */
        //fruit2.orign

        String reultOrigin = ((Banana)fruit2).ogrin; // 다운캐스팅
        System.out.println("바나나 원산지: " + reultOrigin);

        System.out.println();
        /*
        인스턴스오브 연산자
        instanceof
        ↳예약어

        다운캐스팅 관련 활용가능한 기능
         */

        if (fruit2 instanceof Banana) { // true
            System.out.println("바나나인가? true");
        }
        if (fruit2 instanceof Peach) { // false
            System.out.println("복숭아인가? true");
        }

        System.out.println();
        /*
        fruit2에 saleBanana() 메서드를 호출하시오
         */

        ((Banana)fruit2).saleBanana(); //다운캐스팅
        fruit2.showInfo();

    }//end of main
}//end of class

 

5. 다운캐스팅 연습을 위한 심화문제

package com.polymorphism.fruits;
/**
 * 4.22 3_1교시 다형성
 *
 * 업캐스팅
 * 다운캐스팅
 */
public class EMart {
    //main
    public static void main(String[] args) {

        Banana banana1 = new Banana();
        Banana banana2 = new Banana();
        /*
        배열
        배열을 사용할 때는
        반드시 크기를 먼저 지정한다.

        배열의 길이와
        요소의 길이는 항상 동일한 것은 아니다.
         */
        Banana[] bananas = new Banana[10];
        bananas[0] = banana1;
        bananas[1] = banana2;

        Peach[] peaches = new Peach[3];
        peaches[0] = new Peach();
        peaches[1] = new Peach();

        System.out.println();
        /*
        다형성
        다형성을 이해한다면
        유연한 코드를 작성할 수 있다.
         */
        Fruit[] fruits = new Fruit[5];
        fruits[0] = new Banana();
        fruits[1] = new Peach();
        fruits[2] = new Banana();
        fruits[3] = new Peach();
        /*
        문제
        배열 안에 들어있는 각각의 객체 showInfo 호출

        데이터타입이 바나나면
        원산지 정보와 세일 메서드를 호출하라
         */
        for (int i = 0; i < fruits.length; i++) {

            if (fruits[i] != null) {

                if (fruits[i] instanceof Banana) {
                    System.out.print((i + 1) + "번 ");
                    fruits[i].showInfo();
                    System.out.println("원산지: " + ((Banana) fruits[i]).ogrin);
                    ((Banana) fruits[i]).saleBanana();
                    System.out.println("===== ===== =====");
                } else {
                    System.out.print((i + 1) + "번 ");
                    fruits[i].showInfo();
                    System.out.println("===== ===== =====");
                }//end of if

            }//defensive

        }//end of for

    }//end of main

}//end of class

⭐연관관계
Association

두 클래스가 독립적으로 존재하면서 서로를 참조하거나 협력하는 관계

클래스 간의 느슨한 결합
두 객체의 생명주기는 종속되지 않는다. (생명주기 = 선언~GC)

 

ex)

학생과 과목

선수와 팀

이는 폭넓은 개념인데
포함관계도 연관관계의 일부다.
⭐ 내부에서 객체가 생성될 때 따로 포함관계라고 한다

1. 학생 클래스 설계

package com.association;
/**
 * 4.22 2교시 연관관계
 * 
 * 학생과 과목 클래스의 연관관계를 만들어본다
 */
public class Student {
    //member
    private String name;

    private Course course; //연관관계

    //constructor
    public Student(String name) {
        this.name = name;
        course = null; //수강 없음
    }

    //method
    /*
    1.강의를 듣는 메서드를 만든다.
    과목에 대한 정보는 Course에 있다.

    2.학생의 현재 수강상태를 보여주는 기능

    3.수강 종료 기능을 만들어보시오
     */

//    public void takeCourse(Course course) {
//        System.out.println(this.name + "의 수강 과목");
//        course.display();
//    }

    public void enroll(Course course) {
        this.course = course;
        System.out.println(name + ", " + course.getName() + " 과목 등록" );
    }

    public void showCourse() {
        if (this.course != null) {
            System.out.println(this.course.getName() + " 과목을 수강중입니다.");
        } else {
            System.out.println("수강중인 과목 없음");
        }
    }

    public void end(Course course) {
        if (course == null) {
            System.out.println("수강중이 아닙니다");
        } else {
            System.out.println(course.getName() + " 수강 취소");
            this.course = null;
        }
    }

}//end of Student

 

2. 과목 클래스 설계

package com.association;
/**
 * 4.22 2교시 연관관계
 *
 * 학생과 과목 클래스의 연관관계를 만들어본다
 */
public class Course {
    //member
    private String name;

    //constructor
    public Course(String name) {
        this.name = name;
    }

    //getter
    public String getName() {
        return name;
    }

    public void display() {
        System.out.println(name + "강의");
    }

}//end of Course

 

3. 코드 실행부

package com.association;
/**
 * 4.22 2교시 연관관계
 */
public class MainTest1 {
    //main
    public static void main(String[] args) {

        Student student = new Student("홍길동");

        Course java = new Course("자바");
        Course db = new Course("데이터베이스");

        student.showCourse(); //상태
        System.out.println();

        student.enroll(java); //강의등록
        student.showCourse(); //상태
        System.out.println();

        student.end(java); //수강취소
        student.showCourse(); //상태

    }//end of main
}//end of class

 

다음으로 선수와 팀을 만들어 연관관계를 만들어봤다.

 

1.선수 클래스 설계

package com.association;
/**
 * 4.22 2_2교시 연관관계
 */
public class Player {
    
    //member
    private String name;

    private Team team;

    //constructor
    public Player(String name) {
        this.name = name;
    }

    //getter
    public String getName() {
        return name;
    }

    //method - 입단
    public void join(Team team) {
        this.team = team;
        System.out.println(name + " " + team.getName() + " 입단");
    }

    //method - 탈단
    public void leave(Team team) {
        System.out.println(name + " " + team.getName() + " 탈단");
        this.team = null;
    }

    //method - 현황
    public void showRoster() {
        System.out.print(name + " 팀 현황: ");
        if (this.team != null) {
            System.out.println(this.team.getName());
        } else {
            System.out.println("소속 팀 없음");
        }
    }

}//end of Player

 

2.팀 클래스 설계

package com.association;
/**
 * 4.22 2_2교시 연관관계
 */
public class Team {

    //member
    private String name;

    private Player player; //연관관계

    //constructor
    public Team(String name) {
        this.name = name;
    }

    //getter
    public String getName() {
        return name;
    }

    //method - 영입
    public void recruit(Player player) {
        this.player = player;
        System.out.println(name + " " + player.getName() + " 선수 영입");
    }

    //method - 방출
    public void release(Player player) {
        System.out.println(name + " " + player.getName() + " 선수 방출");
        this.player = null;
    }

    //method - 현황
    public void showRoster() {
        System.out.print(name + " 선수 현황: ");
        if (this.player != null) {
            System.out.println(this.player.getName());
        } else {
            System.out.println("등록 선수 없음");
        }
    }

}//end of Team

 

3. 코드 실행부

package com.association;
/**
 * 4.22 2_2교시 연관관계
 */
public class MainTest2 {
    //main
    public static void main(String[] args) {
        Team team1 = new Team("롯데");
        Player player1 = new Player("장원준");

        team1.showRoster();
        System.out.println();

        team1.recruit(player1);
        team1.showRoster();
        System.out.println();

        team1.release(player1);
        team1.showRoster();
        System.out.println();

        player1.showRoster();
        System.out.println();

        player1.join(team1);
        player1.showRoster();
        System.out.println();
        
        player1.leave(team1);
        player1.showRoster();

    }//end of main
}//end of class

⭐접근제어지시자

 

+ public
  default
- private
# protected

 

# protected
접근제어지시자의 한 종류
자식클래스에서만 접근 가능하게 해준다.

package com.inheritance.animal;
/**
 * 4.22 1교시 상속 심화
 * xxx.java 파일에는 public을 가진 클래스는 오직 하나만 존재할 수 있다.
 */
//부모 클래스
class Animal {
    /*
    protected
    접근제어지시자의 한 종류
    자식클래스에서만 접근 가능하게 된다.
     */
    protected String name;

    void bark() {
        System.out.println(name + " 짖는 중");
    }

    void eat() {
        System.out.println(name + " 먹이 먹는 중");
    }
}//end of Animal

//자식 클래스1
class Dog extends Animal {

//    void bark() {
//        System.out.println(name + " 멍멍 짖는 중");
//    }

    @Override // 어노테이션 = 주석+힌트 : 부모클래스의 메서드 eat 오버라이드
    void eat() {
        // super.eat(); 기존 필드.. 필요하다면 사용
        // 강아지 전용 코드 작성
        System.out.println(name + "사료 먹는 중");
    }
}//end of Dog

//자식 클래스2
class Cat extends Animal {

//    void bark() {
//        System.out.println(name + " 야옹 하는 중");
//    }

    @Override
    void eat() {
        // super.eat();
        //고양이 먹는 모습 구현
    }
}//end of Cat

public class Main1 {
    //main
    public static void main(String[] args) {

        Dog dog = new Dog();
        dog.name = "바둑이";

        dog.eat(); // 부모클래스 메서드 호출
        dog.bark(); // 자식클래스 메서드 호출

    }//end of main
}//end of class

/**
 * 보다 일반적인 개념이 부모클래스가 된다. 동물 <= 개
 */

package com.inheritance.animal;
/**
 * 4.22 1교시 상속 심화
 */
public class AnimalTest {
    //main
    public static void main(String[] args) {

        Dog dog = new Dog();
        dog.name = "멍멍이";
        dog.bark();

        Cat cat = new Cat();
        cat.name = "야옹이";
        cat.bark();

    }//end of main
}//end of class

 

⭐상속 실무팁

탑 다운(부모 => 자식)으로 접근하면 문제가 발생할 가능성이 높아진다.
바텀 업(자식 => 부모)으로 접근하는 것이 안전

또한 강한의존성은 문제를 키울 위험이 있다.
따라서 유연하게 묶는 것이 안전

⭐포함관계
Compositon

한 클래스가 다른 클래스를 포함하는 관계다.

"has a"

⭐ 강한 연관성(필수적)

단, 상속과는 다르다

 

 

포함관계를 이해하기 위해

 

차와 엔진을 코드로 간략히 구현해봤다.

 

차와 엔진은 강한 연관성(필수적)을 가지고 있다.

 

1. 엔진

package com.composition;
/**
 * 4.21 포함개념 8
 */
public class Engine {

    //멤버변수설계
    String name;
    int price;

    //메서드
    void start() {
        System.out.println("start() 엔진을 구동합니다.");
    }

    void stop() {
        System.out.println("stop() 엔진을 정지합니다.");
    }

}// end of Engine

/**
객체지향 패러다임 고민

Q 차와 엔진을 상속관계에 둬도 될까?

A 안된다 💀
 */

 

2. 차

차가 움직이려면 먼저 엔진이 가동해야 한다.

package com.composition;
/**
 * 4.21 포함개념 8
 */
public class Car {

    //멤버변수설계
    String name;
    int price;
    /*
    ⭐Car 클래스는 Engine 객체를 포함한다.
    포함관계(Compositoion)
     */
    Engine engine;

    //생성자
    public Car(String name, int price) {
        this.name = name;
        this.price = price;

        /*
        자동차 객체가 생성될 때 엔진 객체도 함께 생성된다.
        포함관계
        ⭐강한의존성
         */
        engine = new Engine();
    }

    //메서드
    void startCar() {

        //car 객체를 통해 engine의 start(); 메서드를 호출한다
        engine.start();
        System.out.println("startCar() 자동차가 움직입니다.");
    }

    void stopCar() {

        engine.stop();
        System.out.println("stopCar() 자동차가 멈춥니다.");
    }
//테스트코드작성
    public static void main(String[] args) {

        /*
        ⭐컴포지션 관계란

        자동차 클래스 내부에서
        엔진 객체를 생성시켜야 컴포지션 관계다
         */

        Car car = new Car("소나타", 1000);
        car.startCar(); // 시동걸기

        System.out.println();
        car.stopCar(); // 시동끄기

    }//main

} // end of Car

 

또 다른 포함관계 예제

 

PC와 CPU 역시 강한 연관성(필수적)을 가지고 있다.

 

1.CPU

package com.composition;
/**
 * 4.21 포함개념 8_1
 */
public class CPU {

    //멤버변수
    private String name;
    private int id;

    //메서드

    void startCPU() {
        System.out.println(this.name + "CPU 가동");
    }

    void stopCPU() {
        System.out.println(this.name + "CPU 정지");
    }

}//end of CPU

 

2. PC

package com.composition;
/**
 * 4.21 포함개념 8_1
 */
public class PC {

    //멤버변수
    private String name;
    private int id;

    //CPU 객체 선언
    CPU cpu;

    //생성자
    PC(String name, int id) {
        this.name = name;
        this.id = id;

        cpu = new CPU();
    }

    //메서드
    void startPC() {
        cpu.startCPU();
        System.out.println(this.name + " PC 가동");
    }
    void stopPC() {
        cpu.stopCPU();
        System.out.println(this.name + "PC 정지");
    }

    //main
    public static void main(String[] args) {

        PC pc1 = new PC("삼보", 1113);
        PC pc2 = new PC("현대", 4321);

        pc1.startPC();
        pc1.stopPC();

        System.out.println();

        pc2.startPC();
        pc2.stopPC();

    }//end of main

}//end of PC

 

다른 형태의 포함관계를 생각해보자.

 

집과 방도 강한 연관성(필수적)을 가지고 있다.

 

1. 방

package com.composition;
/**
 * 4.21 포함개념 8_2
 */
public class Room {

    private String type;

    public Room(String type) {
        this.type = type;
    }

    void descrive() {
        System.out.println(this.type + " 입니다.");
    }
}// end of Room

 

2. 집

 

집은 여러개의 방으로 구성돼 있다.

 

반복되는 부분이 있는 점을 고려해

 

배열과 반복문을 응용해서 넣어봤다.

package com.composition;
/**
 * 4.21 포함개념 8_2
 */
public class House {

    private String address;
    Room[] rooms;

    public House(String address) {
        this.address = address;

        this.rooms = new Room[3];

        rooms[0] = new Room("1.거실");
        rooms[1] = new Room("2.침실");
        rooms[2] = new Room("3.주방");

        //속성으로 선언되고
        //내붸서 객체생성
        //컴포지션이다.
        //room = new Room(type:"안방");
    }

    void showRoom() {
        System.out.println(address+ "에 있는 한 주택의 방 목록: " );
        for (int i = 0; i < rooms.length; i++) {
            if (rooms[i] != null) {
                rooms[i].descrive();
            }
        }
    }

    //테스트
    public static void main(String[] args) {
        House house = new House("부산시진구");
        house.showRoom();

        //house 객체가 소멸이 되면 rooms 도 Room 객체도 소멸
        //GC에 의해 소멸
        house = null;
    }//end of main

}//end of House

요청사항.

 

고객 클래스.

고객 ID

고객 이름

고객 등급

포인트

할인율

 

VIP고객 클래스.

전용 할인율

전용ID

 

GOLD고객 클래스.

전용 할인율

전용ID

 

코드 실행부.

 

 

1. 고객 클래스 설계

//멤버변수

//static

//constructor

//getter

//setter

//method

package com.inheritance;
/**
 * 4.21 상속개념 7
 * 클래스 다이어그램 준수해야 한다.
 */
public class Customer {

    //member
    private int customerID;
    private String customerName;
    private String customerGrade;
    private int bonuspoint;
    private double bonusRatio;

    static int idCount = 1;

    //constructor
    public Customer(String customerName) {
        this.customerID = idCount;
        idCount++;
        this.customerName = customerName;
        customerGrade = "일반";
        bonuspoint = 0;
        bonusRatio = 0.01;
    }

    //getter
    int getCustomerID() {
        return customerID;
    }

    String getCustomerName() {
        return customerName;
    }

    String getCustomerGrade() {
        return customerGrade;
    }

    int getBonuspoint() {
        return bonuspoint;
    }

    //setter
    void setCustomerGrade(String customerGrade) {
        this.customerGrade = customerGrade;
    }

    //method

    public int calcPrice(int int1) {
        return (int) (bonusRatio * int1);
    } //calcPrice

    public void showCustomerInfo() {
        System.out.print("고객 정보...");
        System.out.print(" 고객ID: " + customerID);
        System.out.print(" 고객이름: " + customerName);
        System.out.print(" 고객등급: " + customerGrade + "(" + bonusRatio + ")");
        System.out.println(" 포인트: " + bonuspoint);
    } //showCustomerInfo

}//end of class

 

2.VIP클래스 설계

package com.inheritance;
/**
 * 4.21 상속개념 7_1
 * 클래스 다이어그램 준수해야 한다.
 */
public class VIPCustomer extends Customer {

    //클래스속성
    private int agentID;
    private double salesRatio;

    //생성자
    public VIPCustomer(String customerName, int agentID) {
        super(customerName);
        this.agentID = agentID;
        salesRatio = 0.03;
        setCustomerGrade("VIP");
    }

    //getter
    public int getAgentID() {
        return agentID;
    }

    //메서드
    public int calcPrice(int int1) {
        return (int) (salesRatio * int1);
    }

    public void showCustomerInfo() {
        System.out.print("고객 정보...");
        System.out.print(" 고객ID: " + super.getCustomerID());
        System.out.print(" 고객이름: " + super.getCustomerName());
        System.out.print(" 고객등급: " + super.getCustomerGrade() + "(" + salesRatio + ")");
        System.out.println(" 포인트: " + super.getBonuspoint());
    }

}//end of class

 

3.GOLD 클래스 설계(VIP와 비슷)

package com.inheritance;
/**
 * 4.21 상속개념 7_2
 * 클래스 다이어그램 준수해야 한다.
 */
public class GoldCustomer extends Customer {

    //클래스속성
    private int agentID;
    private double salesRatio;

    //생성자
    public GoldCustomer(String customerName, int agentID) {
        super(customerName);
        this.agentID = agentID;
        salesRatio = 0.05;
        setCustomerGrade("GOLD");
    }

    //getter
    public int getAgentID() {
        return agentID;
    }

    //메서드
    public int calcPrice(int int1) {
        return (int) (salesRatio * int1);
    }

    public void showCustomerInfo() {
        System.out.print("고객 정보...");
        System.out.print(" 고객ID: " + super.getCustomerID());
        System.out.print(" 고객이름: " + super.getCustomerName());
        System.out.print(" 고객등급: " + super.getCustomerGrade() + "(" + salesRatio + ")");
        System.out.println(" 포인트: " + super.getBonuspoint());
    }

}//end of class

 

4.실행부

package com.inheritance;
/**
 * 4.21 상속개념 7_3
 * 클래스 다이어그램 준수해야 한다.
 */
public class CustomerMainTest {

    //main
    public static void main(String[] args) {

        Customer customer1 = new Customer("홍길동");
        VIPCustomer vipCustomer1 = new VIPCustomer("장길산", 1);
        GoldCustomer goldCustomer1 = new GoldCustomer("임꺽정", 1);

        customer1.showCustomerInfo();
        vipCustomer1.showCustomerInfo();
        goldCustomer1.showCustomerInfo();

        System.out.println(customer1.getCustomerName() + "이 받을 포인트: " + customer1.calcPrice(1000));
        System.out.println(vipCustomer1.getCustomerName() + "이 받을 포인트: " + vipCustomer1.calcPrice(1000));
        System.out.println(goldCustomer1.getCustomerName() + "이 받을 포인트: " + goldCustomer1.calcPrice(1000));

    }//end of main
}//end of class

 

메서드 오버라이드
Method Override

 

부모클래스의 메서드를 자식클래스에서 재정의 하는 것이다.

💀 문법 주의

부모클래스의 메서드 이름과 매개변수 개수 및 타입
즉, 모양이 동일해야 한다.

한편 xxx.java 파일 하나에
여러 클래스를 선언할 수 있다.
단 스코프는 분명히 구분된다.

또한 단 하나의 자바파일에
public 클래스는 오직 하나만 존재할 수 있다.

package com.inheritance;
/**
 * 4.21 2강 상속개념 5
 *
 *선임이 작성한 코드라고 가정한다
 */
public class Cal {
    //메서드를 만들어보자
    public int sum(int n1, int n2) {
        return n1 + n2;
    }
    public int multiply(int n1, int n2) {
        return n1 * n2;
    }

}//end of Cal

/**
 *  xxx.java 파일 하나에
 *  여러 클래스를 선언할 수 있다.
 *  단 스코프는 분명히 구분된다.
 *
 *  또한 단 하나의 자바파일에
 *  public 클래스는 오직 하나만 존재할 수 있다.
 *
 *  요청사항
 *  마이너스 기능을 추가하라
 *  곱하기 기능에서 n1과 n2에 0이 들어온다면
 *  0을 입력하지 말라는 문구를 추가하라
 */

class ChildCal extends Cal { //자식 클래스는 접근제어코드 public을 붙일 수 없다

    //마이너스 기능 추가
    public int minus(int n1, int n2) {
        return n1 - n2;
    }

    /*
    상속을 사용했을때

    메서드 오버라이드라는 개념이 있다.
    Method Override

    부모클래스의 메서드를 재정의 하는 것이다.

    문법
    부모클래스의 메서드 이름과 매개변수 개수 및 타입
    즉, 모양이 동일해야 한다.
     */

    //곱셈 기능 수정
    public int multiply(int n1, int n2) {
        if (n1 == 0 || n2 == 0) {
            System.out.println("0을 입력하지 마시오");
        }
        return n1 * n2;
    }
    /*
    부모 클래스의 메서드를 자식 클래스에서 수정했다면
    메서드 오버라이드라고 한다.
     */
}//end of ChildCal

 

예제

부모클래스 Hero 클래스를

자식클래스인 Warrior, Archer, Wizarad로 상속시켰다.

package com.inheritance;

/**
 * 4.21 상속개념 6
 * 클래스 다이어그램 준수해야 한다.
 */
public class Hero {

    // 클래스 속성
    String name;
    int hp;

    //생성자
    Hero(String name, int hp) {
        this.name = name;
        this.hp = hp;
    }

    //메서드
    void attack() {
        System.out.println("대상을 공격합니다");
    }
}//end of class

 

💀 문법 주의

 

부모 사용자정의생성자가 기존재한다면
super(); 키워드를 생성하여
부모 생성자를 호출하여야 한다.

 

package com.inheritance;
/**
 * 4.21 상속개념 6_1
 * 클래스 다이어그램 준수해야 한다.
 */
public class Warrior extends Hero{

    Warrior(String name, int hp) {
        /*
        this();
        부모 사용자정의생성자가 기존재한다면
        super(); 키워드를 생성하여
        부모 생성자를 호출하여야 한다.
         */
        super(name, hp);
    }
    //메서드
    void comboAttack() {
        System.out.println("대상에게 comboAttack을 시전합니다");
    }
    //메서드 오버라이드
    //어노테이션 주석 + 힌트
    @Override
    void attack() {
        System.out.println("전사가 공격을 합니다");
        super.attack();
    }
    //
}//end of class
package com.inheritance;
/**
 * 4.21 상속개념 6_2
 * 클래스 다이어그램 준수해야 한다.
 */
public class Archer extends Hero {

    Archer(String name, int hp) {
        super(name, hp);
    }
    //메서드
    void fireArrow() {
        System.out.println("대상에게 fireArrow를 시전합니다");
    }
}//end of class
package com.inheritance;
/**
 * 4.21 상속개념 6_3
 * 클래스 다이어그램 준수해야 한다.
 */
public class Wizard extends Hero {

    Wizard(String name, int hp) {
        super(name, hp);
    }
    //메서드
    void freezing() {
        System.out.println("대상에게 freezing을 시전합니다");
    }
}//end of class

상속
inheritance

기존의 클래스를 확장하여 새로운 클래스를 정의하는 메커니즘을 말한다.

부모가 자식에게 재산을 물려주듯
미리 작성해둔 클래스의
1.속성과 2.메서드를 물려줄 수 있다.

부모클래스(상위,수퍼)
자식클래스(하위,차일드)

기능이 더 큰 쪽은 자식클래스 쪽이다.
(부모기능 + 자식기능)

 

상속 개념은 기존의 코드를 변경하지 않고 활용하고 싶을 때 활용한다.

package com.inheritance;
/**
 * 4.21 2강 상속개념 1
 *
 * 선임이 작성한 코드라고 가정한다
 */
public class A {

    String name;
    int height;
    int weight;
    int age;
    
}//end of A
package com.inheritance;
/**
 * 4.21 2강 상속개념 2
 */
public class B {
        
        //선임이 작성한 코드 예
        String name;
        int height;
        int weight;
        int age;
        
        /*
        선임이 작성한 코드는 그대로 두고
        기존 코드를 복붙하여
        추가로 필드를 선언해서 만든다
         */
        int level;
        String nickName;
        
        /*
        하지만 우리가 상속이라는 기법을 활용한다면
        더 편하게 작업을 할 수 있다.
         */
}//end of B
package com.inheritance;
/**
 * 4.21 2강 상속개념 3
 *
 * 선임이 작성한 코드를 따라쓴다고 가정한다
 *
 * 만약 상속이란 개념을 이해한다면
 * 기존 클래스의 속성과 메서드를 상속받아 작업할 수 있다.
 */
public class C extends A {
    /*
    ⭐C extends A
    C가 A에 선언된 필드를 물려받겠다는 뜻이다.

    이때 A클래스는 부모클래스가 되고
    C클래스는 자식클래스가 된다.

    💀단, 자바에서는 단일상속만 인정된다.
    충돌을 방지하기 위해서다.
     */
    int level;
    String nickName;

}//end of C

⭐C extends A
C가 A에 선언된 필드를 물려받겠다는 뜻이다.

이때 A클래스는 부모클래스가 되고
C클래스는 자식클래스가 된다.

💀단, 자바에서는 단일상속만 인정된다.
충돌을 방지하기 위해서다.

package com.inheritance;
/**
 * 4.21 2강 상속개념 4
 */
public class CMainTest1 {
    //main = 코드의 진입점
    public static void main(String[] args) {

        //A와 C는 상속관계
        C c = new C();
        c.name = "C클래스입니다";
        c.height = 100;
        c.weight = 20;
        c.age = 10;

        c.level = 1;
        c.nickName = "자식 C클래스";

    }//end of main
}//end of class

 

 

+ Recent posts