여러분, 안녕하세요! 오늘은 Java 개발자 인터뷰 질문에 대한 검토를 계속하겠습니다.
29. 생성자에서 return을 사용할 수 있나요?
예, 하지만 return 키워드 오른쪽에 값이 없는 경우에만 가능합니다 . 반환을 사용할 수 있습니다 . 추가 코드 실행을 긴급하게 종료(중단)하고 객체 초기화를 완료하기 위한 생성자의 도우미 문으로 사용됩니다. 예를 들어 Cat 클래스가 있고 Cat이 노숙자 인 경우 ( isHomeless = true ) 초기화를 종료하고 다른 필드를 채우지 않기를 원합니다(결국 고양이가 노숙자이므로 해당 필드는 우리에게 알려지지 않습니다). :public Cat(int age, String name, boolean isHomeless) {
if (isHomeless){
this.isHomeless = isHomeless;
return;
}
this.isHomeless = isHomeless;
this.age = age;
this.name = name;
}
그러나 구체적인 값에 대해 이야기하는 경우 return 키워드는 다음과 같은 이유로 특정 값을 반환할 수 없습니다.
- 생성자를 선언하면 반환 유형과 같은 것이 없습니다.
- 일반적으로 생성자는 인스턴스화 중에 암시적으로 호출됩니다.
- 생성자는 메소드가 아닙니다. 이는 인스턴스 변수를 초기화하는 것이 유일한 목적인 별도의 메커니즘입니다. 즉, 객체를 생성하기 위해 new 연산자 를 사용하고 있습니다 .
30. 생성자에서 예외가 발생할 수 있나요?
생성자는 메서드와 동일한 방식으로 예외를 처리합니다. 메소드를 사용하면 메소드 헤더에 <ExceptionType> 발생을 작성하여 예외를 발생시킬 수 있습니다 . 그리고 생성자를 사용하면 우리도 같은 일을 할 수 있습니다. 하위 클래스의 생성자를 상속하고 정의할 때 예외 유형을 확장할 수 있습니다(예: IOException -> Exception(그러나 그 반대는 아님)). 예외를 발생시키는 생성자의 예로 Cat 클래스 의 생성자를 사용해 보겠습니다 . 객체를 생성할 때 콘솔에서 이름과 나이를 입력한다고 가정해 보겠습니다.public Cat() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
this.name = reader.readLine();
this.age = Integer.parseInt(reader.readLine());
}
reader.readLine()은 IOException을 발생 시키므로 이를 발생 가능한 예외로 헤더에 기록합니다.
31. 클래스 헤더의 요소는 무엇입니까? 예시 작성
클래스 헤더를 구성하는 요소를 설명하기 위해 작은 스키마를 살펴보겠습니다.- 필수 요소는 괄호 <> 안에 표시됩니다.
- 선택적 요소는 {}에 있습니다.
public final class Lion extends Cat implements WildAnimal
32. 메소드 헤더의 요소는 무엇입니까? 예시 작성
메소드 헤더를 구성하는 요소를 고려할 때 작은 스키마를 다시 고려해 보겠습니다.- 필수 요소는 괄호 <> 안에 표시됩니다.
- 선택적 요소는 {}에 있습니다.
public static void main(String[] args) throws IOException
33. 기본 클래스에 기본 생성자가 정의되어 있지 않은 경우(그러나 다른 생성자가 정의된 경우) 하위 클래스에 기본 생성자를 생성합니다.
질문을 완전히 이해했는지는 모르겠지만 아마도 상위 클래스에 다음과 같은 생성자가 있다는 의미일 수 있습니다.public Cat(int age, String name) {
this.age = age;
this.name = name;
}
이 경우 부모 클래스에서 부모를 초기화할 생성자를 정의해야 합니다(즉, 부모 생성자를 호출).
public class Lion extends Cat {
public Lion(int age, String name) {
super(age, name);
}
}
34. this 키워드는 언제 사용되나요?
Java에서 이는 두 가지 다른 의미를 갖습니다. 1. 현재 객체에 대한 참조입니다(예: this.age = 9 ). 즉, this는 이것이 사용되는 개체와 this 가 포함된 코드가 참조하는 개체를 나타냅니다. 주요 목적은 코드 가독성을 높이고 모호성을 방지하는 것입니다. 예를 들어 인스턴스 필드와 메서드 인수의 이름이 같은 경우:public void setName(String name) {
this.name = name;
}
즉, this.name 은 객체의 필드이고 name 은 메서드 매개변수입니다. this 참조 는 정적 메서드에서 사용할 수 없습니다. 2. 생성자에서 this (value) 와 같이 메서드처럼 호출할 수 있습니다 . 이 경우에는 동일한 클래스의 다른 생성자를 호출하게 됩니다. 기본적으로 객체를 생성하는 과정에서 두 개의 생성자를 호출할 수 있습니다.
public Cat(int age, String name) {
this(name);
this.age = age;
}
public Cat(String name) {
this.name = name;
}
Cat 객체를 생성하기 위해 첫 번째 생성자를 호출하면 두 인스턴스 필드가 모두 성공적으로 초기화됩니다. 여기에는 몇 가지 뉘앙스가 있습니다.
- this()는 생성자에서만 작동합니다.
- 다른 생성자에 대한 참조는 생성자 블록(본문)의 첫 번째 줄에 있어야 합니다. 이는 생성자가 해당 클래스의 생성자를 두 개 이상 호출할 수 없음을 의미합니다.
35. 이니셜라이저란 무엇입니까?
내가 아는 한, 이 질문은 일반 및 정적 초기화 블록에 관한 것입니다. 먼저 초기화가 무엇인지 기억해 봅시다. 초기화는 필드의 생성, 활성화, 준비 및 정의입니다. 사용할 수 있도록 프로그램이나 구성 요소를 준비합니다. 객체를 생성할 때 클래스 변수가 선언되는 즉시 초기화될 수 있다는 것을 기억하실 것입니다.class Cat {
private int age = 9;
private String name = "Tom";
또는 생성자를 통해 사실 뒤에 설정합니다.
class Cat {
private int age;
private String name;
public Cat(int age, String name) {
this.age = age;
this.name = name;
}
하지만 또 다른 방법이 있습니다. 초기화 블록을 사용하여 인스턴스 변수를 설정할 수 있습니다. 초기화 블록은 이름 없이(예: 이름 없는 메서드나 생성자) 클래스 내에서 중괄호 {} 형식을 취합니다.
class Cat {
private int age;
private String name;
{
age = 10;
name = "Tom";
}
초기화 블록은 객체가 생성될 때 로드되는 코드 조각입니다. 이러한 블록은 일반적으로 클래스가 로드될 때 필요한 특정 복잡한 계산을 수행하는 데 사용됩니다. 이러한 계산 결과는 변수 값으로 설정될 수 있습니다. 일반적인 초기화 블록 외에도 정적 초기화 블록이 있습니다. 동일해 보이지만 여는 중괄호 앞에 static 키워드가 있습니다.
class Cat {
private static int age;
private static String name;
static{
age = 10;
name = "Tom";
}
이 블록은 이전 블록과 동일합니다. 그러나 일반 객체가 각 객체가 초기화될 때 실행된다면 정적 객체는 클래스가 로드될 때 한 번만 실행됩니다. 일반적으로 특정 복잡한 계산은 정적 클래스 변수를 초기화하는 데 사용되는 정적 블록에서 수행됩니다. 정적 메서드에 적용되는 정적 블록에도 동일한 제한 사항이 적용됩니다. 즉, 정적 블록의 현재 개체( this )에 대한 참조와 같은 비정적 데이터를 사용할 수 없습니다 . 이제 초기화 블록이 호출되는 시기를 더 잘 이해하기 위해 클래스의 초기화 순서(상위 클래스와 함께)를 살펴볼 수 있습니다.
36. Parent를 확장하는 공개 Child 클래스가 주어지면 객체의 초기화 순서를 작성합니다.
Child 클래스를 로드할 때 초기화 순서는 다음과 같습니다.- 상위 클래스 의 정적 클래스 필드입니다 .
- Parent 클래스 의 정적 초기화 블록입니다 .
- Сhild 클래스 의 정적 필드입니다 .
- Child 클래스 의 정적 초기화 블록입니다 .
- Parent 클래스 의 비정적 필드입니다 .
- Parent 클래스 의 비정적 초기화 블록입니다 .
- 상위 클래스 생성자.
- Сhild 클래스 의 비정적 필드입니다 .
- Сhild 클래스 의 비정적 초기화 블록입니다 .
- Сhild 클래스 의 생성자입니다 .
37. 클래스(객체) 간의 어떤 관계를 알고 있나요?
Java에는 기본 유형과 본격적인 객체에 대한 참조라는 두 가지 종류의 변수가 있습니다.- IS-A 관계
Lion IS-A Cat
(그러나 모든 고양이 가 사자 는 아닙니다 ) 인터페이스에도 동일한 상황이 존재합니다. Lion 클래스가 WildAnimal 인터페이스를 구현하는 경우 해당 인터페이스도 관계에 존재합니다.
Lion IS-A WildAnimal
- HAS-A 관계
Car HAS-A Passenger
반대의 경우도 마찬가지입니다. Passenger가 Car 에 대한 참조를 갖고 있는 경우 다음과 같은 관계가 됩니다.
Passenger HAS-A Car
38. 당신은 어떤 연관 객체 관계를 알고 있습니까?
집합과 구성은 연합의 특별한 경우에 지나지 않습니다. 집계는 한 개체가 다른 개체의 일부인 관계입니다. 예를 들어, 승객이 자동차 안에 있을 수 있습니다. 게다가 승객이 여러 명일 수도 있고 전혀 없을 수도 있습니다(그리고 Tesla에 관해 이야기하고 있다면 운전자가 없을 수도 있습니다). 예를 들어:public class Car {
private List passengers = new ArrayList<>();
void setPassenger(Passenger passenger) {
passengers.add(passenger);
}
void move() {
for (Passenger passenger : passengers) {
System.out.println("Transporting passenger - " + passenger.toString());
}
passengers.clear();
}
}
즉, 승객 수는 우리에게 중요하지 않습니다. Car 클래스의 기능은 이에 의존하지 않습니다. 또한 집계는 다른 개체가 하나의 개체를 사용할 때 첫 번째 개체를 다른 개체에서 사용할 수 있음을 의미합니다. 예를 들어, 같은 학생이 뜨개질 클럽과 록 밴드에 동시에 속해 있고 동시에 스페인어 수업에 참석할 수도 있습니다. 상상할 수 있듯이 집계는 클래스 간의 보다 느슨한 연관 관계입니다. 구성은 개체가 다른 개체의 일부일 뿐만 아니라 한 개체의 작업이 다른 개체에 크게 의존하는 훨씬 더 긴밀한 관계입니다. 예를 들어, 자동차에는 엔진이 있습니다. 자동차 없이도 엔진은 존재할 수 있지만 자동차 밖에서는 쓸모가 없습니다. 그리고 자동차는 엔진 없이는 작동할 수 없습니다.
public class Car {
private Engine engine;
public Car(Engine engine) {
this.engine = engine;
}
void startMoving() {
engine.start();
...
}
또한 합성은 다른 개체가 개체를 사용할 때 첫 번째 개체가 다른 개체에 속할 수 없음을 의미합니다. 우리의 예로 돌아가면, 엔진은 동시에 두 대 이상의 자동차에 속할 수 없고 한 대의 자동차에만 속할 수 있습니다. 오늘은 이 정도면 충분할 것 같으니 여기서 그만 두겠습니다.
GO TO FULL VERSION