1. Super와 부모생성자
class가 인스턴스화 될 떄 생성자가 실행되면서 객체를 초가화한다.
그때 자신의 생성자만 실행되는 것이 아니 아니고 부모의 생성자부터 실행됨.
public class Car{
public Car(){
System.out.println("Car의 기본생성자입니다.");
}
}
public class Bus extends Car{
public Bus(){
System.out.println("Bus의 기본생성자입니다.");
}
}
public class BusExam{
public static void main(String args[]){
Bus b = new Bus();
}
}
// 이러면 실행했을 떄
// Car의 기본생성자입니다.
// Bus의 기본생성자입니다.
// 이렇게 부모생성자 먼저 실행이 되고, 그 다음 생성자가 실행이 됨.
new 연산자로 Bus객체를 생성하면,
Bus객체가 메모리에 올라갈때 부모인 Car도 함께 메모리에 올라간다.
생성자는 객체를 초기화 하는 일을한다.
생성자가 호출될 때 자동으로 부모의 생성자가 호출되면서 부모객체를 초기화 하게된다.
super
자신을 가리키는 키워드가 this 라면, 부모들 가리키는 키워드는 super
super() 는 부모의 생성자 == 부모객체를 나타내는 키워드
부모의 생성자를 임의로 호출하지 않으면, 부모 class의 기본 생성자가 자동으로 호출된다.
아래 예제처럼 호출해보면 위에서 super()를 호출하지 않을때와 결과가 같다.
public Bus(){
super();
System.out.println("Bus의 기본생성자입니다.");
}
부모의 기본생성자가 아닌 다른 생성자를 호출하는 방법
클래스는 기본 생성자가 없는 경우도 존재한다.
public class Car{
public Car(String name){
System.out.println(name + " 을 받아들이는 생성자입니다.");
}
}
Car class(부모클래스)가 위 처럼 수정되면, Bus생성자에서 컴파일 오류가 발생한다.
부모가 기본생성자가 없기 때문에 컴파일 오류가 발생하게 되는 것이다.
이런 문제를 해결하려면 자식 클래스의 생성자에서 직접 부모의 생성자를 호출해야 합니다.
public Bus(){
super("소방차"); // 문자열을 매개변수로 받는 부모 생성자를 호출하였다.
System.out.println("Bus의 기본생성자입니다.");
}
super 키워드는 자식에서 부모의 메소드나 필드를 사용할 때도 사용함.
2. 오버라이딩 (Overriding)
부모가 가지고 있는 메소드와 똑같은 모양의 메소드를 자식이 가지고 있는 것
== 즉, 메소드를 재정의 하는 것이다.
부모의 기능이 나도 필요는 한테 그대로 쓰고싶지는 않을 때,
부모클래스의 메소드를 자식 클래스에서 재정의하여 사용하는 것.
Car 클래스를 상속받은 Bus 클래스는 부모클래스가 가진고 있는 run() 메소드를 잘 사용한다.
//run 메소드를 가지고 있는 Car클래스
public class Car{
public void run(){
System.out.println("Car의 run메소드");
}
}
//Car 를 상속받는 Bus 클래스
public class Bus extends Car{
}
public class BusExam{
public static void main(String args[]){
Bus bus = new Bus();
bus.run(); //Car의 run메소드가 실행된다.
}
}
Bus클래스에 부모가 가지고 있는 메소드와 모양이 같은 메소드를 선언
public class Bus extends Car{
public void run(){
System.out.println("Bus의 run메소드");
}
}
public class BusExam{
public static void main(String args[]){
Bus bus = new Bus();
bus.run(); //Bus run메소드가 실행된다.
}
}
BusExam을 실행하면, "Bus의 run메소드"가 출력된다.
메소드를 오버라이드 하면, 항상 자식클래스에서 정의된 메소드가 호출된다.
오버라이딩 한다고 해서 부모의 메소드가 사라지는 것은 아니다.
super 키워드를 이용하면, 부모의 메소드를 호출 할 수 있다.
public class Bus extends Car{
public void run(){
super.run(); // 부모의 run()메소드를 호출
System.out.println("Bus의 run메소드");
}
}
3. 클래스 형변환
부모타입으로 자식객체를 참조하게 되면 부모가 가지고 있는 메소드만 사용할 수 있다.
자식객체가 가지고 있는 메소드나 속성을 사용하고 싶다면 형변환 해야 한다.
public class Car{
public void run(){
System.out.println("Car의 run메소드");
}
}
public class Bus extends Car{
public void sound(){
System.out.println("빵빵.");
}
}
상속관계 == is a 관계
== "Bus는 Car다." 라는 관계가 성립되는 것이죠.
==> 부모타입으로 자식객체를 참조할 수 있다.
부모타입으로 자식객체를 참조하게 되면 부모가 가지고 있는 메소드만 사용할 수 있다.
== 부모타입으로 자식을 가리킬 수 있으나 이때 부모가 가지고 있는 내용만 사용 가능함.
public class BusExam{
public static void main(String args[]){
Car car = new Bus();
car.run();
car.sound(); // 컴파일 오류 발생
}
}
*** ppangppang()메소드를 호출하고 싶다면 Bus타입의 참조변수로 참조해야 한다.
public class BusExam{
public static void main(String args[]){
Car car = new Bus();
car.run();
//car.sound(); // 컴파일 오류 발생
Bus bus = (Bus)car; //부모타입을 자식타입으로 형변환
bus.run();
bus.sound(); // 작동
}
}
객체들 끼리도 형변환이 가능. 단, 상속관계에 있었을 때만
부모타입으로 자식타입의 객체를 참조할 때는 묵시적으로 형변환이 일어난다.
== 부모 -> 자식으로 형변환은 묵시적
부모타입의 객체를 자식타입으로 참조하게 할때는 명시적으로 형변환 해주어 한다.
== 자식 -> 부모로 형변환은 명시적
단 이렇게 형변환 할때에는 부모가 참조하는 인스턴스가 형변환 하려는 자식타입일 때만 가능하다.
public class BusExam{
public static void main(String args[]){
Car car = new Bus();
Bus bus = (Bus)car; //부모타입을 자식타입으로 형변환
//이 경우는 car이 자식인 Bus를 참조하고 있었기 때문에 가능한 것.
Car car2 = new Car();
Bus bus2 = (Bus)car2; //불가능
//이 경우는 car2가 자식인 Bus를 참조하던 것이 아니라 형변환 불가능함.
}
}'Java > 기초 공부' 카테고리의 다른 글
| int와 Integer (0) | 2025.11.26 |
|---|---|
| 인터페이스(interface) (0) | 2025.11.21 |
| 상속(1) - 상속, 접근제한자, 추상클래스 (0) | 2025.11.20 |
| 클래스 다듬기 - 생성자, this, 오버로딩, 패키지 (0) | 2025.11.20 |
| 클래스와 객체(2) (0) | 2025.11.20 |