본문 바로가기
한화시스템 Beyond SW Camp/백엔드

[Java] 생성자, 상속, 예외처리

by taeh00n 2025. 1. 6.

 ※ 이 글에서 다룬 기반기술, 프론트엔드, 백엔드, 데브옵스 등 풀스택 개발 지식은 모두 한화시스템 Beyond SW Camp 12기에서 배운 내용을 복습한 것입니다.

 

생성자

생성자 : 메소드 이름이 클래스 이름과 똑같은 메소드

생성자는 1개 이상 만들 수 있다. 클래스를 이용해서 new로 객체를 생성할 때 무조건 실행되는 메소드이다.일반저긍로 생성자는 객체안에 있는 변수의 초기화 작업을 하는데 사용된다.

 

class Champion {
    String name;

    int x;
    int y;
	
    // 생성자
    Champion(String name, String team) {
        this.name = name;
        if(team.equals("red")) {
            this.x = 99;
            this.y = 99;
        } else if (team.equals("blue")) {
            this.x = 1;
            this.y = 1;
        }
    }
}
public class Main {
    public static void main(String[] args) {
        Champion 가렌;
        // new로 생성자(메소드를 실행)
        // 생성자(메소드)에 매개변수가 있으면 new로 호출할 때 맞춰서 매개변수를 전달해야함
        가렌 = new Champion("가렌", "blue");

        System.out.println(가렌.name);	// 가렌 출력
        System.out.println(가렌.x);		// 1 출력


        Champion 다리우스;
        다리우스 = new Champion("다리우스", "red");
        System.out.println(다리우스.name);	// 다리우스 출력
        
        System.out.println(다리우스.x);		// 99 출력

    }
}

상속

public class Main {
    public static void main(String[] args) {
        Champion 가렌 = new Champion();
        Champion 다리 = new Champion();

        가렌.attack(다리);

        Minion minion01 = new Minion();
        Minion minion02 = new Minion("근거리");
        Minion minion03 = new Minion("근거리",30,30);

        minion01.attack(가렌);
        minion02.attack(minion03);

        CanonMinion canon01 = new CanonMinion();
        canon01.attack(minion01);
    }
}

 

public class Minion {
    private String type;
    private int hp;
    private int exp;

    // 메소드 오버로딩 : 메소드 이름이 똑같은 메소드가 여러 개
    // 완전히 똑같으면 안되고 매개변수의 타입, 매개변수의 수가 조금씩 달라야 함.
    // 메소드를 사용하는 곳에서 이렇게도 저렇게도 할 수 있게 편의 기능 제공
    public Minion() {
        this.type = "근거리";
        this.hp = 30;
        this.exp = 30;
    }

    public Minion(String type) {
        this.type = type;
        if(type.equals("근거리")){
            this.hp = 30;
            this.exp = 30;
        }
    }

    public Minion(String type, int hp, int exp) {
        this.type = type;
        this.hp = hp;
        this.exp = exp;
    }

    //공격
    public void attack(Champion target) {
        System.out.println("근거리 미니언이 챔피언을 공격했다.");
    }

    public void attack(Minion target) {
        System.out.println("근거리 미니언이 미니언을 공격했다.");
    }

    public int getHp() {
        return hp;
    }

    public void setHp(int hp) {
        this.hp = hp;
    }
}
public class CanonMinion extends Minion {
    public CanonMinion() {
        super("대포", 50, 50);
    }

    @Override
    public void attack(Minion target) {
        System.out.println("대포미니언이 미니언을 공격했다.");
    }
}

 

오버로딩(Overloading) : 같은 이름의 메서드를 여러 번 정의 한 것이다. 메서드 이름은 같지만 매개변수의 타입이나 수가 조금씩 다르다. 같은 작업을 여러 방식으로 처리할 수 있게 해준다.

예시 -> Minion 클래스에 있는 Minion(), Minion(String type), Minion(String type, int hp, int exp)와 같은 메서드들

 

오버라이딩(Overriding) : 부모 클래스에서 정의된 메서드를 자식 클래스에서 재정의하는 것이다.

예시 -> Minion 클래스에 attack이 정의되어있지만 CanonMinion클래스에서 attack을 재정의했다. 이렇게 되면 CanonMinion 객체가 attack을 쓰면 Minion의 attack이 아닌 재정의한 CanonMinion의 attack 메서드가 실행된다.


final과 static

final : 한 번 할당되면 이후에는 변경할 수 없다. (타입 앞에 final을 붙이면 된다.)

final double PI = 3.14159;

 

static : 클래스 자체에 속하는 변수. 모든 객체가 같은 값을 공유한다. 객체별로 값을 독립적으로 저장할 필요없을 때 사용한다.

 


예외 처리

public class Main {
    // 컴파일 에러 : 지키지 않으면 실행조차 안되는 것. 일반적으로 문법이 틀린 것
    // 런타임 에러 : 예외, 실행이 되기는 하는데 프로그램이 동작하다가 특정 상황에 발생
    public static void main(String[] args) {
        int num01;
        int num02;;

        num01 = 10;
        num02 = 0;
        A a = new A();
        a.ex01();

        try{
            System.out.println(num01/num02);
        } catch (Exception e) {
            System.out.println("예외 발생");
        }
        System.out.println("코드");
    }
}

 

try-catch를 통해서 예외 처리를 할 수 있는데 try는 예외가 발생할 수 있는 코드를 작성하고 catch에는 예외 발생 시 어떻게 동작하게 해야할지를 적는 부분이다,


추상화

추상화 = 공통점

구체적인 객체나 클래스들이 가질 수 있는 공통적인 특성이나 동작을 뽑아내 하나의 추상적인 수준에서 정의하고 다루기 위해서이다.

추상 클래스 : 클래스는 클래스인데 추상 메서드를 포함한 클래스

추상 메서드 : 메서드는 메서드인데 구현이 없고 선언만 있는 메서드

인터 페이스 : 추상 메서드만 있는 클래스

 

public class Main {
    // 의존성 주입 : 특정 클래스의 변수에 다른 클래스의 객체를 저장하는 것
    //      의존성 주입을 어디서 하는가?
    public static void main(String[] args) {
        FileUpload uploader;    // 다형성 : 다양한 현태를 가질 수 있는 성질
        uploader = new LocalFileUpload();   //Main에서 FileUpload의 의존성을 주입
        uploader.save("파일01");
    }
}

public interface FileUpload {
    public void save (String file);
}

public class CloudFileUpload implements FileUpload {
    public void save(String file){
        System.out.println(file + "을 클라우드에 저장");
    }
}

public class LocalFileUpload implements FileUpload {
    public void save(String file){
        System.out.println(file + "을 내 컴퓨터에 저장");
    }
}

 


의존성 역전의 법칙 (DIP)

상위 클래스는 하위 클래스에 의존해서는 안되며 둘 다 추상화에 의존해야한다는 말이다.

public class Main {
    public static void main(String[] args) {
        TestController testController = new TestController();
        testController.ex01();
    }
}

//-----------------------------------------------------------------------------//
// 사용자의 요청을 받고 요청에 대한 응답을 처리
public class TestController {
    public void ex01() {
        System.out.println("컨트롤러 실행");
        TestRepository testRepository =
                new TestRepositoryImpl02();

        TestServiceImpl testService =
                new TestServiceImpl(testRepository);
        testService.ex01();
        System.out.println("컨트롤러 종료");
    }
}

//-----------------------------------------------------------------------------//
// 비즈니스 로직을 수행하는 계층
public interface TestService {
    public void ex01();
}

//-----------------------------------------------------------------------------//
// Service 인터페이스의 실제 구현체
public class TestServiceImpl implements TestService {
    TestRepository testRepository;
                            // 변수 타입은 인터페이스
    public TestServiceImpl(TestRepository testRepository){
                                // 실제 변수에 저장되는 건 인터페이스의 구현 객체
        this.testRepository = testRepository;
    }
    public void ex01() {
        System.out.println("서비스 실행");
        testRepository.ex01();
        System.out.println("서비스 종료");
    }
}

//-----------------------------------------------------------------------------//
// 데이터베이스나 외부 시스템과 상호작용하는 역할
public class TestRepositoryImpl02 implements TestRepository {
    public void ex01() {
        System.out.println("레포지토리02 실행");
        System.out.println("Redis에 CRUD하는 코드");
        System.out.println("레포지토리02 종류");
    }
}

//----------------------------------실행 결과-----------------------------------//
컨트롤러 실행
서비스 실행
레포지토리02 실행
Redis에 CRUD하는 코드
레포지토리02 종류
서비스 종료
컨트롤러 종료