상속 (Inheritance)
- 새로운 클래스를 정의할 때 이미 구현된 클래스를 상속(inheritance) 받아서 속성이나 기능을 확장하여 구현한다.
- 기존의 클래스보다 더 구체적인 기능을 가진 클래스를 구현해야 할 때 상속을 이용함.
기본 문법
(Parent 클래스를 상속받은 Child 클래스)
- extends 키워드 뒤에는 단 하나의 클래스만 올 수 있음 (단일 상속)
class Child extends Parent{
//필드
//메서드
}
- 상위 클래스 : 하위 클래스보다 더 일반적인 개념과 기능을 가짐
- 하위클래스 : 상위 클래스보다 더 구체적인 개념과 기능을 가짐
- 하위 클래스가 상위 클래스의 속성과 기능을 확장(extends)
자식클래스 Child에서는 부모클래스 Parent의 메서드와 멤버변수 등을 호출해서 사용할 수 있음.
그러나, private, default 변수는 자식클래스에서 접근할 수 없다.
this와 super 키워드
- this : 객체 자기 자신을 의미하는 키워드
- super : 상위 객체를 의미하는 키워드
super
부모 클래스와 자식 클래스의 멤버변수 이름이 같을 때 구분하는 키워드
super()
부모 클래스의 생성자를 호출한다.
해당 메서드는 자식 클래스의 생성자 안에 들어가며, 무조건 자식 클래스의 생성자의 첫줄에 들어가야 한다.
예제
public class Vehicle {
public String name = "vehicle";
public int maxSpeed;
public int capacity;
public Vehicle() {
System.out.println("Vehicle 생성자 호출");
}
public void print(){
System.out.println("name = " + name);
System.out.println("maxSpeed = " + maxSpeed);
System.out.println("capacity = " + capacity);
}
}
public class Car extends Vehicle {
public String name = "myCar";
public String displacement; //배기량
public Car() {
super(); //부모 클래스의 생성자 호출
System.out.println("Car 생성자 호출");
}
public void print(){
//super 키워드 : 부모 클래스의 name을 가리킨다.
System.out.println("(Vehicle) name = " + super.name);
System.out.println("maxSpeed = " + maxSpeed);
System.out.println("capacity = " + capacity);
System.out.println("displacement = " + displacement);
//this 키워드 : 지금 이 클래스의 name을 가리킨다.
System.out.println("(Car) name = " + this.name);
}
}
public class VehicleTest {
public static void main(String[] args) {
Car myCar = new Car();
myCar.maxSpeed = 200;
myCar.capacity = 4;
myCar.displacement = "2000cc";
myCar.print();
}
}
(출력)
Vehicle 생성자 호출
Car 생성자 호출
(Vehicle) name = vehicle
maxSpeed = 200
capacity = 4
displacement = 2000cc
(Car) name = myCar
부모 클래스의 생성자를 호출하는 super() 는 항상 자식 클래스 생성자의 첫줄에 써줘야 한다.
또한, 부모 클래스와 자식클래스가 같은 이름의 멤버변수를 가질 경우, super, this로 구분할 수 있다.
super()를 이용해서 부모 생성자에 파라미터를 넘길 수도 있다.
public Vehicle(int maxSpeed, int capacity) {
this.maxSpeed = maxSpeed;
this.capacity = capacity;
}
public Car(int maxSpeed, int capacity, String displacement) {
super(maxSpeed, capacity);
this.displacement = displacement;
}
이렇게 super()에 파라미터를 넘겨서 부모 클래스 생성자에 값을 전달할 수 있다.
Overriding
부모클래스의 메서드를 자식클래스에서 상속받아서 재정의 하는것.
메서드의 선언부는 부모 클래스의 메서드와 동일해야 한다. ( 매개변수(파라미터)나 메서드 이름 등이 동일해야 함. )
overriding 예제
간단하게 자동차의 종류를 출력하는 printType()이라는 메서드를 만들었다.
Car 클래스
class Car{
Car(){}
public void printType(){
System.out.println("자동차 입니다.");
}
}
Sedan클래스
Sedan클래스는 printType을 overriding 하여 "세단입니다."를 출력하도록 했다.
class Sedan extends Car{
@Override
public void printType() {
System.out.println("세단 입니다.");
}
}
SUV 클래스
SUV 클래스는 printType을 overriding 하여 "SUV입니다."를 출력하도록 하고, 추가로 super의 printType메서드도 실행하도록 했다.
class SUV extends Car{
@Override
public void printType() {
super.printType();
System.out.println("SUV 입니다.");
}
}
Truck
Truck 클래스는 상속만 받고 아무것도 overriding 하지 않았다.
class Truck extends Car{
}
테스트코드와 출력 결과
public static void main(String[] args) {
System.out.println("=== Sedan ===");
Sedan sedan = new Sedan();
sedan.printType();
System.out.println("=== SUV ===");
SUV suv = new SUV();
suv.printType();
System.out.println("=== Truck ===");
Truck truck = new Truck();
truck.printType();
}
=== Sedan ===
세단입니다.
=== SUV ===
자동차입니다.
SUV입니다.
=== Truck ===
자동차입니다.
overriding을 한 경우에는 overriding 한 메서드만 출력되고, overriding 하지 않은 경우에는 부모클래스의 메서드가 그대로 출력되는 것을 볼 수 있다.
추가로 super 키워드를 이용하여 부모클래스의 메서드도 사용할 수 있다.
형 변환 (업캐스팅과 다운캐스팅)
- 상위 클래스 : Customer(int customerID, String CustomerName)
- 하위 클래스 : VIPCustomer(int customerID, String CustomerName)
2-1. 업캐스팅
Customer vc = new VIPCustomer();
2-2. 다운캐스팅
VIPCustomer vCustomer = (VIPCustomer)vc;
2-3. instanceof를 사용하여 확인
원래 인스턴스의 형이 맞는지 체크하는 키워드
- 다운캐스팅 시 잘못된 형으로 변환되어 생기는 오류를 방지하기 위함
//업캐스팅
Customer vipMan = new VIPCustomer();
//다시 다운캐스팅
if(vipMan instanceof VIPCustomer){
VIPCustomer vc = (VIPCustomer)vipMan;
}else System.out.println("error");
예제
Car 클래스
- Car 클래스는 carName, carNum, type, price 속성을 갖고 있다.
- CarClass를 생성할 때는 이름과 번호를 입력받고, type은 none, 가격은 0으로 초기된다.
- printType 메서드는 자동차에 대한 정보를 출력해 준다.
class Car{
String carName;
int carNum;
String type;
int price;
Car(){}
public Car(String carName, int carNum) {
this.carName = carName;
this.carNum = carNum;
type = "none";
price = 0;
}
public void printType(){
System.out.println("자동차 종류는 ["+type+"]입니다.");
System.out.println("carName = " + carName);
System.out.println("carNum = " + carNum);
System.out.println("type = " + type);
System.out.println("price = " + price);
}
}
Sedan extends Car 클래스
- Car을 상속받은 Sedan 클래스이다.
- Sedan클래스는 생성할 때 이름, 번호, 가격을 입력받는다.
- 생성자에서 super()을 이용해 부모클래스의 생성자를 이용하고, 추가로 type과 price를 설정해 준다.
class Sedan extends Car{
public Sedan(String carName, int carNum, int price){
super(carName,carNum);
this.type="sedan";
this.price = price;
}
}
Truck extends Car 클래스
- Car을 상속받은 Truck 클래스이다.
- Truck 클래스는 생성할 때 이름, 번호, 가격을 입력받고 추가로 적재량 도 입력받는다.
- printType메서드에서는 super키워드를 이용해서 부모클래스의 메서드를 호출하고, 추가로 적재량을 출력한다.
class Truck extends Car{
int load;
public Truck(String carName, int carNum, int price,int load){
super(carName,carNum);
this.type = "truck";
this.price = price;
this.load = load;
}
@Override
public void printType() {
super.printType();
System.out.println("적재량 = " + load+"t");
}
}
테스트 코드, 출력 결과
Sedan클래스 객체를 생성할 때 Car클래스로 업캐스팅 하여 Car 타입으로 생성할 수 있다.
public static void main(String[] args) {
System.out.println("=== Sedan ===");
Sedan sedan = new Sedan("mysedan",1234,2000);
sedan.printType();
System.out.println("=== Truck ===");
Truck truck = new Truck("myTruck", 5678, 4000, 2);
truck.printType();
System.out.println("=== 업캐스팅 ===");
Car myCar = new Sedan("mysedan2",1313,1500);
myCar.printType();
}
=== Sedan ===
자동차 종류는 [sedan]입니다.
carName = mysedan
carNum = 1234
type = sedan
price = 2000
=== Truck ===
자동차 종류는 [truck]입니다.
carName = myTruck
carNum = 5678
type = truck
price = 4000
적재량 = 2t
=== 업캐스팅 ===
자동차 종류는 [sedan]입니다.
carName = mysedan2
carNum = 1313
type = sedan
price = 1500
'JAVA & Spring > JAVA 이론' 카테고리의 다른 글
[Java / CS] JVM과 Java의 메모리 구조 (0) | 2024.02.16 |
---|---|
[JAVA] 추상 클래스 (abstract class) (0) | 2023.05.18 |
[JAVA] static과 final (0) | 2023.05.17 |
[JAVA] 접근 제어 지시자( private, protected, default, public) / 정보은닉, 캡슐화 (0) | 2023.05.17 |
[JAVA] 생성자 / 오버로딩(overloading) (0) | 2023.05.17 |