클래스 만들때 생성자가 선언되지 않으면 컴파일러에 의해 자동적으로 생성자가 만들어진다. 자식 생성자에서 자동으로 super(); 을 생성해 부모 생성자를 호출한다.
상속 받은 자식 클래스에서 생성자 자체는 생략 가능하지만 명시적으로 호출을 만들때 부모 생성자 super() 를 꼭 넣어줘야한다. -> 없으면 오류 발생
상위 클래스(부모 클래스)의 메소드를 하위 클래스(자식 클래스)에서 재정의하는 것
@Override 어노테이션을 생략 가능하나 붙여주면 메소드가 정확히 오버라이딩 된 것인지 컴파일러가 체크해줘서 개발자의 실수를 줄여준다.
-> 개발자가 metho1() 이라고 d를 빼먹게 되면 컴파일 에러 발생
자식 클래스 내부에서 오버라이딩된 부모 클래스의 메소드를 호출하려면 super를 붙여 호출한다. super는 부모 객체를 참조하고 있기 때문에 부모 메소드에 직접 접귾할 수 있다.
class Parent {
void method1() {
System.out.println("부모의 메소드1");
}
void method2() {
System.out.println("부모의 메소드2");
}
}
class Child extends Parent {
void method2() {
System.out.println("부모의 메소드를 오버라이딩");
}
void method3(){
method2();
super.method2(); // 부모 메소드 method2 호출
}
}
클래스 앞에 final 이 붙으면 final 클래스로서 부모 클래스가 될 수 없다. 자식 클래스도 만들 수 없다.
final 메소드는 오버라이딩이 불가능하다.
같은 타입이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질
타입 변환은 상속 관계에 있는 클래스 사이에서 발생한다. 자식 타입은 부모 타입으로 자동 타입 변환이 가능하다.
public class Car {
// Tire 타이어 타입 필드
// new HankookTire(); 자식 타입 객체 대입
// new KumhoTire(); 자식 타입 객체 대입
Tire t1 = new HankookTire();
Tire t2 = new KumhoTire();
}
매개값의 타입을 조사할 때 사용
boolean result = 좌향(객체) instanceof 우향(타입)
boolean result = paraent istanceof Child // paraent가 참조하는 객체가 Child인지 조사
클래스들의 공통적인 특성을 추출해서 선언한 클래스를 추상 클래스라고 한다. new 연산자를 사용해서 인스턴스(객체)를 생성할 수 없다.
추상 클래스와 실체 클래스는 상속의 관계를 가지고 있다. 실체 클래스가 자식으로 구현되어 추상 클래스의 모든 특성을 물려받고, 추가적인 특성을 가질 수 있다.
메소드의 선언만 통일화하고, 실행 내용은 실체 클래스마다 달라야 하는 경우 추상 메소드를 선언한다. 추상 메소드는 추상 클래스에서만 선언할 수 있다.
자식 클래스는 반드시 추상 메소드를 재정의(오버라이딩)해서 실행 내용을 작성해야 한다.
public abstract class Animal{
public abstract void sound();
}
public class Dog extends Animal {
@Override
public void sound(){
System.out.println("멍멍");
}
}