안녕하세요! 이전 강의에서 우리는 이미 상속의 개념을 여러 번 간략하게 접했습니다. 오늘 우리는 이 주제에 대해서도 다룰 것이지만 너무 깊이 다루지는 않을 것입니다. 이에 대한 자세한 강의는 나중에 할 예정이지만, 오늘은 실용적인 예제를 살펴보고 Java의 흥미로운 연산자 하나에 대해 알아 보겠습니다.
자바 상속
그렇다면 상속이란 정확히 무엇입니까? 상속은 Java를 포함한 프로그래밍의 메커니즘으로, 기존 클래스를 기반으로 새 클래스를 설명할 수 있습니다. 그런 다음 하위 클래스는 상위 클래스의 필드와 메서드에 액세스할 수 있습니다. 왜 이것이 필요할 수 있습니까? 예를 들어, 프로그램에서 트럭, 레이싱, 세단, 픽업 등 여러 클래스의 자동차를 만들어야 한다고 상상해 보세요. 코드 작성을 시작하지 않아도 이러한 클래스에는 공통점이 많다는 것을 확실히 알 수 있습니다. 모든 자동차에는 모델 이름, 제조 연도, 엔진 크기, 최대 속도 등이 있습니다. (모두 바퀴와 기타 부품이 있다는 사실은 말할 것도 없습니다). 이러한 상황에서는 다음을 수행할 수 있습니다.- 각 클래스에 이러한 필드를 생성하고 생성 시 새 자동차 클래스에 추가하세요.
- 모든 기계에 공통된 필드를 상위 클래스로 이동하면
Car
특정 유형의 기계의 모든 클래스가 확장이라는Car
단어를 사용하여 상속됩니다 .
public class Car {
private String model;
private int maxSpeed;
private int yearOfManufacture;
public Car(String model, int maxSpeed, int yearOfManufacture) {
this.model = model;
this.maxSpeed = maxSpeed;
this.yearOfManufacture = yearOfManufacture;
}
}
public class Truck extends Car {
public Truck(String model, int maxSpeed, int yearOfManufacture) {
super(model, maxSpeed, yearOfManufacture);
}
}
public class Sedan extends Car {
public Sedan(String model, int maxSpeed, int yearOfManufacture) {
super(model, maxSpeed, yearOfManufacture);
}
}
최소한 불필요한 코드 중복은 피했고, 이는 프로그램을 작성할 때 항상 노력해야 할 사항입니다. 또한 간단하고 이해하기 쉬운 클래스 구조를 가지고 있습니다. 즉, 모든 기계에 공통된 필드가 하나의 클래스에 배치됩니다. 예를 들어 트럭에 다른 자동차에는 없는 특정 필드가 있는 경우 해당 필드를 클래스에 선언할 수 있습니다 Truck
. 방법도 마찬가지다. 모든 자동차에는 자동차 시동, 주유/브레이크 등 설명할 수 있는 몇 가지 공통적인 동작이 있습니다. 이러한 일반 메소드는 일반 클래스에 배치될 수 있으며 Car
, 각 특정 유형의 특정 동작은 하위 클래스에서 설명될 수 있습니다.
public class Car {
public void gas() {
//...gas
}
public void brake() {
//...brake
}
}
public class F1Car extends Car {
public void pitStop() {
//...only racing cars make pit stops
}
public static void main(String[] args) {
F1Car formula1Car = new F1Car();
formula1Car.gas();
formula1Car.pitStop();
formula1Car.brake();
}
}
우리는 모든 자동차의 공통 메소드를 클래스로 옮겼습니다 Car
. 그러나 Formula 1 경주용 자동차를 설명하는 후속 클래스에서는 F1Car
경주에서만 수행되고 특정 동작으로 구별되는 피트 스탑(자동차의 긴급 유지 관리를 위한 정지)이 있습니다.
Java 인스턴스 연산자
클래스를 기반으로 객체가 생성되었는지 확인하기 위해 Java에는 특수 연산자 - 가 있습니다instanceof
. true
테스트가 참인 경우 또는 false
결과가 거짓인 경우 값을 반환합니다 . 자동차 클래스를 예로 들어 어떻게 작동하는지 살펴보겠습니다.
public class Truck extends Car {
public static void main(String[] args) {
Truck truck = new Truck();
System.out.println(truck instanceof Car);
}
}
출력: true 클래스의 개체가 있고 모든 트럭은 자동차이므로 instanceof
반환된 연산자를 사용하여 테스트합니다 . 클래스 는 클래스의 자손 이므로 모든 트럭은 공통 상위인 자동차를 기반으로 생성됩니다. 연산자에 주의하십시오 . 점 없이 작성됩니다. 왜냐하면 메소드("클래스의 객체 인스턴스")가 아니라 연산자이기 때문입니다. 다르게 시도해 봅시다: true
Truck
Truck
Car
instanceof
public static void main(String[] args) {
Car car = new Car();
System.out.println(car instanceof Truck);
}
출력: false 클래스 Car
및 해당 객체는 클래스에서 파생되지 않습니다 Truck
. 모든 트럭은 자동차이지만 모든 자동차가 트럭은 아닙니다. Car
클래스를 기반으로 객체가 생성되지 않습니다 Truck
. 또 하나의 예:
public static void main(String[] args) {
Car car = new Car();
Truck truck = new Truck();
System.out.println(car instanceof Object && truck instanceof Object);
}
출력: True 여기의 논리도 간단합니다. 생성한 클래스를 포함하여 Java의 모든 클래스는 클래스에서 나옵니다 (그 안에 확장 Object를Object
작성하지 않더라도 이 메커니즘은 클래스에 암시되어 있습니다). 이것이 왜 유용하며 어떤 상황에서 유용할까요? 연산자의 가장 일반적인 용도는 메서드 재정의입니다 . 예를 들어, 클래스에서 메소드가 구현되는 방법은 다음과 같습니다 . instanceof
equals()
equals
String
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
문자열을 전달된 객체와 비교하기 전에 메서드는 전달된 객체가 실제로 문자열인지 확인합니다. 그리고 나서야 그는 두 물체의 속성을 비교하기 시작합니다. 이 검사를 수행하지 않으면 값 및 길이 필드가 있는 개체를 메서드에 전달 하고 이를 문자열과 비교할 수 있습니다. 물론 이는 잘못된 작업입니다.
GO TO FULL VERSION