본문 바로가기
자바/개인 정리

자바 암기 노트1

by limdae94 2024. 12. 26.

1. 객체 지향 프로그래밍에 대해 설명하시오.

객체 지향 프로그래밍(OOP)은 데이터와 그 데이터를 조작하는 메서드를 하나의 객체로 묶어, 코드의 재사용성과 확장성을 높이는 프로그래밍 패러다임이다. OOP의 주요 특징은 다음과 같다.

  1. 캡슐화: 데이터와 메서드를 객체 내부에 숨기고, 필요한 부분만 외부에 공개한다.
  2. 상속: 기존 클래스의 특성을 재사용하고 확장할 수 있다.
  3. 다형성: 동일한 메서드 이름으로 다양한 방식으로 동작하게 할 수 있다.
  4. 추상화: 복잡한 시스템을 단순화하여 핵심 개념만 표현한다.

이로 인해 유지 보수와 코드 관리가 쉬워지고, 프로그램의 유연성과 확장성이 향상된다.

 

2. 클래스와 인스턴스에 대해 설명하시오.

클래스(Class)는 객체를 정의하는 설계도나 청사진으로, 객체의 속성과 동작(메서드)을 정의한다.

인스턴스(Instance)는 클래스에서 생성된 구체적인 객체를 말한다. 즉, 클래스는 틀이고, 인스턴스는 그 틀로 만들어진 실제 데이터이다.

예를 들어, 사람이라는 클래스가 있다면, 홍길동김철수는 클래스에서 생성된 각각의 인스턴스이다.

 

3. 객체에 대해 설명하시오.

객체(Object)는 데이터(속성)와 이를 처리하는 메서드(동작)를 하나로 묶은 프로그래밍 단위이다. 클래스의 인스턴스이며, 프로그램에서 실제로 사용되는 구체적인 실체를 의미이다.

 

4. this, this()의 차이에 대해 설명하시오.

this 참조 변수는 인스턴스가 바로 자기 자신을 참조하는 데 사용하는 변수이다.

this() 메서드는 생성자 내부에서만 사용할 수 있다. 같은 클래스의 다른 생성자를 호출할 때 사용한다.

class Car {

    private String modelName;
    private int modelYear;
    private String color;
    private int maxSpeed;
    private int currentSpeed;

    Car(String modelName, int modelYear, String color, int maxSpeed) {
        this.modelName = modelName;
        this.modelYear = modelYear;
        this.color = color;
        this.maxSpeed = maxSpeed;
        this.currentSpeed = 0;
    }

    Car() {
        this("소나타", 2012, "검정색", 160); // 다른 생성자를 호출함.
    }

    public String getModel() {
        return this.modelYear + "년식 " + this.modelName + " " + this.color;
    }
}

public class prac {
    public static void main(String[] args) {
        Car tcpCar = new Car();
        System.out.println(tcpCar.getModel());
    }
}

 

5. super, super()의 차이에 대해 설명하시오.

super는 부모 클래스의 멤버(필드나 메서드)에 접근할 때 사용한다. 예를 들어 super.필드명 또는 super.메서드명()이다.

super()는 부모 클래스의 생성자를 호출할 때 사용한다. 자식 클래스의 생성자에서 부모 클래스의 초기화 작업을 수행할 때 주로 사용된다.

차이점으로 super는 부모 클래스의 멤버 접근용, super()는 부모 생성자 호출용이다.

 

6. 오버라이딩, 오버로딩에 대해 설명하시오.

오버라이딩(Overriding)

  • 부모 클래스의 메서드를 자식 클래스에서 재정의한다.
  • 메서드 이름, 매개변수, 반환형이 부모 메서드와 완전히 동일해야 한다.
  • 다형성을 구현하며, 부모의 기능을 자식 클래스에서 맞게 변경할 때 사용한다.

오버로딩(Overloading)

  • 같은 이름의 메서드를 매개변수의 타입, 개수, 순서를 다르게 정의한다.
  • 반환형만 다르게 정의할 수는 없다.
  • 코드의 가독성과 재사용성을 높이는 데 사용된다.

주요 차이

  • 오버라이딩: 부모 메서드 재정의 (상속 관계 필요).
  • 오버로딩: 같은 이름의 메서드 여러 개 정의 (상속 관계 불필요).

 

7. 오버라이딩을 사용하는 이유에 대해 설명하시오.

1. 다형성 구현
    - 부모 클래스의 참조 변수로 자식 클래스의 메서드를 호출하여, 객체의 타입에 따라 다른 동작을 수행할 수 있다.

2.기능 변경
    - 부모 클래스에서 제공하는 기본 기능을 자식 클래스의 요구에 맞게 변경할 수 있다.

3. 코드 재사용성
    - 부모 클래스의 기본 구조를 활용하면서 일부 동작만 수정하여 개발 시간을 절약하고 중복 코드를 줄일 수 있다.

4. 유지 보수성 향상
    - 공통된 인터페이스나 상위 클래스의 메서드를 재정의해, 코드 구조를 일관되게 유지하고 유지 보수를 쉽게 만든다.

 

8. 오버로딩을 사용하는 이유에 대해 설명하시오.

같은 이름의 메서드로 다양한 매개변수를 처리해 가독성재사용성을 높이기 위해 사용한다.
메서드 이름을 일관되게 유지해 편리한 API 설계를 가능하게 한다.

 

9. 캡슐화에 대해 설명하시오.

캡슐화(Encapsulation)는 객체의 데이터(필드)와 이를 처리하는 메서드를 하나로 묶고, 외부에서 직접 접근하지 못하도록 보호하는 개념이다.

  1. 정보 은닉: private 접근 제한자를 사용해 데이터에 직접 접근을 막고, gettersetter를 통해 간접적으로 접근한다.
  2. 데이터 보호: 잘못된 데이터 수정이나 외부 간섭을 방지한다.
  3. 유지 보수 용이: 내부 구현 변경 없이 외부 코드에 영향을 최소화한다.
class Person {
    private String name; // 데이터 은닉

    public String getName() { // 간접 접근
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
  • 코드 안정성 및 보안성이 높아지고, 유지 보수가 쉬워진다.

10. 상속에 대해 설명하시오.

상속(Inheritance)은 기존 클래스(부모 클래스)의 속성과 메서드를 새로운 클래스(자식 클래스)에 물려주는 객체지향 프로그래밍의 핵심 개념이다.

  1. 코드 재사용: 부모 클래스의 코드를 자식 클래스에서 재사용한다.
  2. 확장성: 자식 클래스에서 부모의 기능을 확장하거나 변경(오버라이딩)할 수 있다.
  3. "is-a" 관계: 자식 클래스는 부모 클래스의 일종으로 간주된다.
class Parent {
    public void show() {
        System.out.println("나는 부모 클래스입니다.");
    }
}

class Child extends Parent {
    public void greet() {
        System.out.println("나는 자식 클래스입니다.");
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        child.show();  // 부모 클래스 메서드 호출
        child.greet(); // 자식 클래스 메서드 호출
    }
}
// 실행 결과
나는 부모 클래스입니다.
나는 자식 클래스입니다.
  • 코드 중복을 줄이고 유지 보수를 쉽게 만들고, 클래스 간 관계를 명확하게 표현할 수 있다.


11. 다형성에 대해 설명하시오.

다형성(Polymorphism)은 객체가 여러 형태를 가질 수 있는 성질로, 같은 메서드나 부모 클래스 참조 변수가 자식 클래스의 객체를 참조하여 다른 동작을 수행하는 것을 의미한다.

  1. 오버라이딩: 부모 클래스의 메서드를 자식 클래스에서 재정의하여 다르게 동작시킴.
  2. 다형성 구현: 부모 타입 참조 변수로 여러 자식 객체를 다룰 수 있음.
class Animal {
    public void sound() {
        System.out.println("동물이 소리를 냅니다.");
    }
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("멍멍!");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog(); // 부모 타입 참조 변수
        animal.sound(); // 출력: 멍멍!
    }
}
  • 코드의 유연성과 확장성이 증가하고, 동일한 인터페이스로 다양한 객체를 다룰 수 있다.

 

12. 추상화에 대해 설명하시오.

추상화(Abstraction)는 복잡한 시스템에서 중요한 핵심만 표현하고, 불필요한 세부 사항은 숨기는 객체지향 프로그래밍의 개념이다.

  1. 필수적인 정보만 제공: 복잡성을 줄이고 사용자에게 필요한 부분만 노출.
  2. 구현 세부사항 은닉: 사용자는 내부 구현을 몰라도 동작을 이해하고 사용할 수 있음.
abstract class Animal {
    public abstract void sound(); // 추상 메서드 (구현 없음)
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("멍멍!");
    }
}

Animal 클래스는 추상화된 개념(동물)을 제공하며, 실제 동작은 Dog 클래스에서 구현된다.

  • 코드의 설계와 유지보수성을 높이고, 복잡성을 줄이고, 공통 기능을 쉽게 정의할 수 있다.
  • 자바 8 이후, 인터페이스에서 디폴트 메서드와 정적 메서드를 지원하면서 거의 사용하지 않는다.
  • 추상 클래스는 상속을 통한 공통 구현 제공 혹은 is-a 관계 표현에서 사용한다.

인터페이스는 클래스 간 느슨한 결합과 다중 구현을 제공하여 더 유연한 설계가 가능하다. 하지만, 공통 상태(필드)나 일부 구현이 필요하다면 추상 클래스를 사용한다. 상황에 따라 두 개념을 혼합해서 사용할 수도 있다.

 

13. 인터페이스에 대해 설명하시오.

인터페이스(Interface)는 클래스가 구현해야 할 메서드의 청사진만 제공하는 추상 타입이다. 객체지향 프로그래밍에서 계약 또는 규칙을 정의하는 데 사용된다.

  1. 추상 메서드: 인터페이스의 모든 메서드는 기본적으로 public abstract이다. (구현은 클래스가 담당)
  2. 다중 구현 가능: 클래스는 여러 인터페이스를 동시에 구현할 수 있어 유연한 설계가 가능하다.
  3. 필드: 인터페이스의 필드는 기본적으로 public static final(상수)이다.
  4. 디폴트 및 정적 메서드 지원(Java 8 이상): 디폴트 메서드(default)와 정적 메서드(static)를 정의할 수 있다.
interface Animal {
    void sound(); // 추상 메서드
    default void eat() { // 디폴트 메서드
        System.out.println("먹는다.");
    }
}

class Dog implements Animal {
    @Override
    public void sound() {
        System.out.println("멍멍!");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        dog.sound(); // 출력: 멍멍!
        dog.eat();   // 출력: 먹는다.
    }
}
  1. 다중 구현: 클래스가 여러 인터페이스를 구현할 수 있어 코드 재사용과 유연성이 높아진다.
  2. 결합도 낮춤: 클래스 간 의존성을 줄이고, 유연한 설계를 지원한다.
  3. 표준화된 규칙 제공: 특정 동작을 강제하여 일관성 있는 설계를 유도한다.
  • 다양한 클래스에서 공통된 동작을 정의하고 강제할 때
  • 다중 상속이 필요한 상황에서
  • 서비스나 API 설계 시 규격화를 위해

14. 접근제한자의 종류와 특징에 대해 설명하시오.

자바의 접근 제한자(Access Modifier)는 클래스, 필드, 메서드 등의 접근 범위를 제어하는 데 사용된다.

접근 제한자 종류와 특징

  1. public
    • 특징: 어디서나 접근 가능 (같은 패키지, 다른 패키지 모두 접근 가능)
    • 용도: 클래스 외부에서도 사용해야 하는 필드, 메서드, 클래스에 사용
    • 예: 라이브러리 API의 메서드나 클래스
  2. protected
    • 특징: 같은 패키지 내에서 접근 가능하고, 다른 패키지라도 상속받은 클래스에서 접근 가능
    • 용도: 상속받은 클래스에서만 사용할 메서드나 필드
  3. default (명시적 키워드 없음)
    • 특징: 같은 패키지 내에서만 접근 가능
    • 용도: 패키지 내부에서만 사용하는 클래스나 메서드
  4. private
    • 특징: 해당 클래스 내에서만 접근 가능
    • 용도: 외부에 노출하지 않아야 하는 필드나 메서드

접근 제한자 비교표

제한자 같은 클래스 같은 패키지 다른 패키지(상속받음) 다른 패키지
public O O O O
protected O O O X
default O O X X
private O X X X
public class Example {
    public String publicField = "Public";      // 어디서나 접근 가능
    protected String protectedField = "Protected"; // 상속 관계 또는 같은 패키지
    String defaultField = "Default";          // 같은 패키지에서만 접근 가능
    private String privateField = "Private";  // 클래스 내부에서만 접근 가능

    public void show() {
        System.out.println(privateField); // 클래스 내부 접근 가능
    }
}

결론: 접근 제한자는 정보 은닉코드 설계의 유연성을 높이는 데 사용된다.
         필요한 접근 수준에 따라 적절히 설정하는 것이 중요하다.