상속
상속을 사용하면 코드의 중복이 제거되고 재사용성이 크게 증가하여 생산성과 유지 보수성에 매우 유리해짐
public class 자식클래스 extends 부모클래스 {
}
※ 주의
상속은 확장의 개념. 부모 클래스의 멤버의 개수는 자식 클래스의 멤버의 수보다 클 수가 없다.
클래스 간의 관계
상속관계 : is -a ( 스포츠카는 자동차다 )
포함관계 : has -a ( 자동차가 4개의 타이어, 4개의 문을 가지고 있음 )
Main.java
// 자동차 객체 생성
Car car = new Car("GV80", "Black", 50000000);
// 자동차 부품 : 타이어, 차문, 핸들 선언
Tire[] tires = new Tire[]{
new Tire("KIA", 150000), new Tire("금호", 150000),
new Tire("Samsung", 150000), new Tire("LG", 150000)
};
Door[] doors = new Door[]{
new Door("LG", "FL"), new Door("KIA", "FR"),
new Door("Samsung", "BL"), new Door("LG", "BR")
};
Handle handle = new Handle("Samsung", "S");
// 자동차 객체에 부품 등록
car.setTire(tires);
car.setDoor(doors);
car.setHandle(handle);
Car.java
Tire[] tire;
Door[] door;
Handle handle;
public Car(String model, String color, double price) {
this.model = model;
this.color = color;
this.price = price;
}
public void setTire(Tire ... tire) {
this.tire = tire;
}
Car.java 에는 Tire, Door, Handle 클래스가 포함되어있고 Main.java 에서는 Car , Tire, Door, Handle 객체가 생성된 후에
자동차 객체에 부품등록을 하여서 포함시키고 있다.
Car.java 에서는 이미 해당 클래스가 포함되어 선언이 되어있고, setTire() 메서드 매개변수로 ... 을 받아 여러 개의 매개변수를 받을 준비까지 되어있다.
단일 상속과 다중 상속
Java 는 다중 상속을 허용하지 않음.
여러 부모 클래스가 한 자식클래스에 상속할 수 없다. ( 멤버 이름이 겹친다든지 문제가 발생 )
final 클래스와 final 메서드
final 키워드를 클래스에 지정하여 선언하면 최종적인 클래스가 됨으로 더 이상 상속할 수 없는 클래스가 됨
final 키워드를 메서드에 지정하여 선언하면 최종적인 메서드가 됨으로 더 이상 오버라이딩할 수 없는 메서드가 됨
Object
Object 클래스는 Java 내 모든 클래스들의 최상위 부모 클래스 → 모든 클래스는 Object 메서드를 사용할 수 있음
부모 클래스가 없는 자식 클래스는 컴파일러에 의해 자동으로 Object 클래스를 상속받게 됨.
오버라이딩
부모 클래스로부터 상속받은 메서드의 내용을 재정의 하는 것
조건
- 선언부가 부모 클래스의 메서드와 일치해야 합니다.
- 접근 제어자를 부모 클래스의 메서드 보다 좁은 범위로 변경할 수 없습니다.
- 예외는 부모 클래스의 메서드 보다 많이 선언할 수 없습니다.
@Override
public double brakePedal() {
speed = 100;
System.out.println("스포츠카에 브레이크란 없다");
return speed;
}
@Override
public void horn() {
booster();
}
자식 클래스에서 @Overriding 을 적어주고 메서드를 재정의 해준다.
super 와 super()
super 은 부모 클래스의 멤버를 참조할 수 있는 키워드
public void setCarInfo(String model, String color, double price) {
super.model = model; // model은 부모 필드에 set
super.color = color; // color는 부모 필드에 set
this.price = price; // price는 자식 필드에 set
}
자식 클래스에서 위처럼 메서드를 설정하면 super 을 붙인 model 과 color 은 부모 클래스에 접근해서 부모 클래스의 필드의 값을 수정한다.
price 는 this 를 사용했기 때문에 자식 클래스에 해당하는 price 필드를 수정한다.
다형성
자동 타입 변환
부모 타입 변수 = 자식 타입 객체; 는 자동으로 부모 타입으로 변환이 일어남.
→ 자식 객체는 부모 객체의 멤버를 상속받기 때문에 부모와 동일하게 취급될 수 있음
Mammal mammal = new Whale();
( Mammal 이 Whale 의 부모 타입 )
강제 타입 변환
반대로 부모 타입 객체는 자식 타입 변수로 자동으로 타입 변환되지 않음.
// 자식타입객체가 자동 타입변환된 부모타입의 변수
Mammal mammal = new Whale();
mammal.feeding();
// 자식객체 고래의 수영 기능을 사용하고 싶다면
// 다시 자식타입으로 강제 타입변환을 하면된다.
Whale whale = (Whale) mammal;
whale.swimming();
※ 주의
아무 때나 강제 타입 변환이 가능한 게 아니라, 자식 타입 객체가 부모 타입 변환된 후 다시 자식 타입으로 변환될 때만 강제 타입 벼환이 가능
다형성
여러 가지 형태를 가질 수 있는 능력
예를 들어 '자동차의 바퀴를 교체하면 승차감이 좋아진다' 와 같음
Tire tire = new HankookTire("HANKOOK");
Tire tire = new KiaTire("KIA");
Tire 의 자식 클래스 HankookTire 과 KiaTire 선언.
public Car(Tire tire) {
this.tire = tire;
}
...
Car car1 = new Car(new KiaTire("KIA"));
Car car2 = new Car(new HankookTire("HANKOOK"));
매개변수에도 다형성이 적용될 수 있음
Car 생성자에서 매개변수의 타입이 부모 타이어이기 때문에 자식 타이어 객체들을 매개값으로 전달할 수 있음
( 결국은 Car car1 = new Car (tire) ) 와 같은 셈
Tire getHankookTire() {
return new HankookTire("HANKOOK");
}
Tire getKiaTire() {
return new KiaTire("KIA");
}
...
Tire hankookTire = car1.getHankookTire();
KiaTire kiaTire = (KiaTire) car2.getKiaTire();
반환 타입이 부모타이어이기 때문에 자식 타이어 객체들을 반환값으로 지정할 수 있음.
마찬가지로 자동 타입 변환이 된 반환값인 자식 타이어 객체를 강제 타입 변환할 수도 있음 ( 조건이 성립 )
instanceof
다형성 기능으로 해당 클래스 객체의 원래 클래스명을 체크하는 것이 필요한데 instanceof 가 이 기능을 한다.
// 다형성
class Parent { }
class Child extends Parent { }
class Brother extends Parent { }
public class Main {
public static void main(String[] args) {
Parent pc = new Child(); // 다형성 허용 (자식 -> 부모)
Parent p = new Parent();
System.out.println(p instanceof Object); // true 출력
System.out.println(p instanceof Parent); // true 출력
System.out.println(p instanceof Child); // false 출력
Parent c = new Child();
System.out.println(c instanceof Object); // true 출력
System.out.println(c instanceof Parent); // true 출력
System.out.println(c instanceof Child); // true 출력
}
}
{대상 객체} instance of {클래스 이름} 와 같은 형태로 사용하면 응답값은 boolean 으로 결과를 출력해냄
추상 클래스
추상 클래스
미완성된 설계도
abstract 키워드를 사용하여 선언
public abstract class 추상클래스명 {
}
- 추상 클래스는 추상 메서드를 포함할 수 있다. ( 추상 메서드가 없어도 추상 클래스로 선언 가능 )
- 추상 클래스는 자식 클래스에 상속되어 자식 클래스에 의해서만 완성될 수 있음
- 추상 클래스는 여러 개의 자식 클래스들에서 공통적인 필드나 메서드를 추출해서 만듦
추상 메서드
아직 구현되지 않은 미완성된 메서드
public abstract class 추상클래스명 {
abstract 리턴타입 메서드이름(매개변수, ...);
}
추상 메서드는 일반적인 메서드와는 다르게 블록 {} 이 없음 ( 정의만 할 뿐, 실행 내용은 가지고 있지 않음 )
추상 클래스 상속
public class 클래스명 extends 추상클래스명 {
@Override
public 리턴타입 메서드이름(매개변수, ...) {
// 실행문
}
}
extends 를 통해 추상 클래스에 상속시키고 @Override 를 필수로 사용해 추상 메서드를 완성시킨다.
여러 개의 클래스에서 공통된 부분을 뽑아서 코드를 간단화하고 이를 묶어서 추상 클래스로 만들어서 뽑아쓰게 만든다고 이해하자.
'컴퓨터 프로그래밍 > Java' 카테고리의 다른 글
[Java] 예외처리 (0) | 2024.07.30 |
---|---|
[Java] 인터페이스 (0) | 2024.07.30 |
[Java] this와 this(), 접근 제어자, package와 import (0) | 2024.07.29 |
[Java] 생성자 (0) | 2024.07.28 |
[Java] 인스턴스 멤버와 클래스 멤버 (0) | 2024.07.26 |