java (4)

ysh·2023년 7월 4일
0

Spring Boot

목록 보기
19/53

오버로딩

하나의 클래스에 같은 이름의 메서드를 여러개 정의하는 것

package ch06;

class CalcUtil{

    public static int add(int a, int b){
        return a + b;
    }
    // 오버로딩
    // 이름은 같지만 다른 메서드
    public static int add(int a, int b, int c){
        return a + b + c;
    }
    // 리턴 타입이 달라지더라도 오버로딩이 가능하다
    public static long add(long a, long b){
        return a + b;
    }

    public static void print(String str, int num){
        System.out.println(str + num);
    }
    // 사용되는 매개변수 타입이 같더라도 위치가 달라지면 오버로딩 된다
    // 이런 방식으로 사용하는 것은 추천하지 않는다
    public static void print(int num, String str){
        System.out.println(str + num);
    }
}

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

    }
}

상속 (유전, 이어받다)

기존의 클래스를 재사용하여 새로운 클래스 작성

  • 자바에선 단일 상속만 허용

상속 기본 코드

package ch07;

// 부모 클래스
class 초보자{

    String skill_1 = "달팽이 세마리";
}

// 자식 클래스
class 마법사 extends 초보자{
    String skill_2 = "매직 클로";
}
// 썬콜 전직 / skill_3 / 썬더볼트
class 썬콜 extends 마법사{
    String skill_3 = "썬더 볼트";
}

// 자식 클래스
// 초보자 -> 로그 -> 시프
// 로그 skill_2 더블 스탭
// 시프 skill_3 세비지 블로우
class 로그 extends 초보자{
    String skill_2 = "더블 스탭";
}
class 시프 extends 로그{
    String skill_3 = "세비지 블로우";
}

public class S01 {
    public static void main(String[] args) {
        
        마법사 magic1 = new 마법사();
        System.out.println(magic1.skill_1);
        System.out.println(magic1.skill_2);
    }
}

상속 실습 코드

package ch07;


// 모든 스킬들의 공통적인 부분 세팅
// MAX_POINT는 모든 스킬들의 공통 고정 값 (static final)
class Skill{
    static final int MAX_POINT = 5;
    String name;
    int point;
    Champ champ;

    public Skill(String name, Champ champ) {
        this.name = name;
        this.champ = champ;
        this.point = 0;
    }

    public int getDamage(){
        return 0;
    }

    public void plusPoint(){
        if(this.point >= MAX_POINT){
            this.point = MAX_POINT;
            System.out.println("포인트를 더이상 올릴 수 없습니다");
            return;
        }
        this.point++;
    }
}

// 챔피언의 공통적인 부분들 만들기
class Champ {
    // 물리 공격력
    int ad;
    Skill skill;
    public Champ(int ad, Skill skill) {
        this.ad = ad;
        this.skill = skill;
    }

}

// 챔피언의 공통적인 부분을 이어 받되
// 캐릭터의 개별 특징을 세팅
class ash extends Champ{
    public ash() {
        // 1. 상속받는 객체가 생성됨
        // 2. super를 통해 객체 안의 필드에 값을 초기화 해줌
        super(100, null);
        // 3. 현재 class의 객체가 생성됨
        // 4. 현재 객체 안의 필드에 값을 넣어줌
        this.skill = new Volley(this);
    }
}

// 부모가 필요로하는 정보는 넘겨주고
// 내가 부모와 다르게 커스텀 할 부분 세팅
class Volley extends Skill{

    public Volley(Champ champ) {
        super("일제사격", champ);
    }

    // 부모가 가진 메소드 형태를 그대로 가져와
    // 내용만 바꿔 세팅
    @Override
    public int getDamage() {
        // return super.getDamage();
        // 고정 데미지 20 35 50 65 80
        // + 캐릭터 공격력 * 1
        
        // 스킬을 찍지 않았을 때
        if(point < 1){
            System.out.println("스킬을 사용할 수 없습니다");
            return super.getDamage();
        }

        int damage = (int)(20 + (15 * (point-1)) + (this.champ.ad * 1.0));

        return damage;
    }

    

}

// 스킬 이름 : 필트오버 피스메이커
// 고정 공격력 : 50 90 130 170 210
// 캐릭터 공격력 * 1.25 / 1.45 / 1.65 / 1.85 / 2.05
class Peace extends Skill {
    public Peace(Champ champ){
        super("필트오버 피스메이커", champ);
    }

    @Override
    public int getDamage(){
        int damage = 0;

        if(point < 1){
            System.out.println("스킬을 사용할 수 없습니다");
            return super.getDamage();
        }
        damage = (50 + (point-1) * 40) + (int)(champ.ad * (1.25 + 0.2 * (point-1)));
        return damage;
    }
}

class 케이틀린 extends Champ{
    public 케이틀린(){
        super(100, null);
        this.skill = new Peace(this);
    }
}

public class S04 {
    public static void main(String[] args) {
    
        // // 참조형 변수에 주소값을 아직 모르는 상태에서
        // // 초기화 하는 경우 null 사용
        // String str = null;
        // System.out.println(str);
        // str = new String("홍길동");
        // System.out.println(str);
        // // 더 쓰지 않는 객체에 null
        // str = null;

        // ash champ1 = new ash();
        // System.out.println(champ1.skill.getDamage(champ1));
        // champ1.skill.plusPoint();
        // System.out.println(champ1.skill.getDamage());
        // champ1.skill.plusPoint();
        // System.out.println(champ1.skill.getDamage());

        // // 케이틀린 생성
        // 케이틀린 champ2 = new 케이틀린();
        // // 케이틀린
        // champ2.skill.plusPoint();
        // System.out.println(champ2.skill.getDamage());
        // champ2.skill.plusPoint();
        // System.out.println(champ2.skill.getDamage());


        // 상속을 받으면 부모 타입으로 공통화 사용 가능
        Champ[] champArr = new Champ[2];

        champArr[0] = new ash();
        champArr[1] = new 케이틀린();

        for (Champ cham : champArr){
            cham.skill.plusPoint();
            // 항상 같은 메소드를 사용하기 때문에
            // 메소드 이름 고민을 할 필요가 없어서
            // 신뢰성이 높아진다.
            System.out.println(cham.skill.getDamage());
        }
    }
}

포함

한 클래스의 멤버 변수로 다른 클래스를 선언

포함 기본 코드

package ch07;

// 작은 구성요소, 포함될 클래스 생성
class Skill{
    String name;
    int damage;

    public Skill(String name, int damage) {
        this.name = name;
        this.damage = damage;
    }
}

class 초보자{
    // 스킬 클래스 포함
    Skill skill_1;

    public 초보자() {
        this.skill_1 = new Skill("달팽이 세마리", 1);
    }
    
}

class 마법사 extends 초보자{
    // 스킬 클래스 포함
    Skill skill_2;

    public 마법사() {
        this.skill_2 = new Skill("매직 클로", 10);
    }
}

public class S02 {
    public static void main(String[] args) {
        
    }
}

오버라이딩 (부모 자식 간)

조상클래스로부터 상속 받은 메서드의 내용을 상속받는 클래스에 맞게 변경하는 것

  • 선언부 똑같이
class Skill{
	public int getDamage(){
        return 0;
    }
}

class Volley extends Skill {
    // 부모가 가진 메소드 형태를 그대로 가져와
    // 내용만 바꿔 세팅
    @Override
    public int getDamage() {
        // return super.getDamage();
        // 고정 데미지 20 35 50 65 80
        // + 캐릭터 공격력 * 1

        // 스킬을 찍지 않았을 때
        if (point < 1) {
            System.out.println("스킬을 사용할 수 없습니다");
            return super.getDamage();
        }

        int damage = (int) (20 + (15 * (point - 1)) + (this.champ.ad * 1.0));

        return damage;
    }
}

class Peace extends Skill {
    @Override
    public int getDamage(){
        int damage = 0;

        if(point < 1){ 
            System.out.println("스킬을 사용할 수 없습니다");
            return super.getDamage();
        }  
        damage = (50 + (point-1) * 40) + (int)(champ.ad * (1.25 + 0.2 * (point-1)));
        return damage;
    }
}     

제어자

클래스, 변수, 메서드의 선언부에 사용되어 부가적인 의미 부여
Ex )
접근제어자 - public, protected, default, private
그 외 - static, final, abstract

static (클래스, 공통적)

final (변경 불가)

abstract (추상, 미완성)


접근 제어자

public (접근 제한 X)

  • 같은 패키지 내

private

  • 같은 클래스 내

제어자 코드

package ch07;

// import
// 다른 패키지의 클래스 호출
import ch07.sub.Sub01;

public class S06 {
    public static int first = 1;
    public int second = 2;
    public static final int third = 3;

    public void printSecond(){
        System.out.println(second);
    }
    public static void main(String[] args) {
        // Sub01 코드는 아래쪽에
        Sub01 sub01 = new Sub01();
        System.out.println(sub01.getData());

        // S06 클래스의 public static int first = 1;
        // 같은 스태틱 객체이므로 가져올 수 있다
        System.out.println(first);
        System.out.println(S06.first);

        // S06 클래스의 public int second = 2;
        // main은 스태틱, second는 스태틱 변수가 아니므로 가져올 수 없다
        // System.out.println(second);
        // 실행할 수 없다
        // System.out.println(printSecond());

        // static이 아닌 필드는 인스턴스 생성 후 가져오기
        S06 s06 = new S06();
        System.out.println(s06.second);
        s06.printSecond();

        S06.first = 11;
        // final 값은 변경 불가능
        // S06.third = 33;

        final String str = "홍길동";
        // 변경 불가능
        // str = "임꺽정";
    }
}

객체 지향에서의 데이터 관리(?)

package ch07.sub;
public class Sub01 {
    // 객체 지향에서 데이터는 객체만 볼 수 있는게 기본적
    private String data = "데이터";
    // 객체의 데이터를 외부에 노출 시킬 때
    // 보통 메소드로
    // 원본 데이터를 넘길 수도 있고
    // 숨겨야 하는 부분은 숨길 수도 있다
    public String getData(){
        return "숨긴 " + data;
    }
}
profile
유승한

0개의 댓글