07-2) 타입 변환과 다형성
필드의 다형성
필드의 타입을 부모타입으로 선언하면 다양한 자식 객체들이 저장될 수 있어서 필드 사용 결과가 다양해진다.
이를 구현하기 위해 상속, 오버라이딩, 타입 변환을 이용하는 것이다.
매개변수의 다형성
자동 타입 변환은 필드 값을 대입할 때도 발생하지만, 주로 메소드를 호출할 때 많이 발생한다.
메소드를 호출할 때, 매개값을 다양화하기 위해 매개변수에 자식 객체를 지정할 수도 있다.
//부모클래스
public class Vehicle {
public void run() {
System.out.println("차량이 달립니다.");
}
}
//부모클래스를 이용하는 클래스
public class Driver {
public void drive(Vehicle vehicle) { //drive()메소드에서 Vehicle타입의 매개값을 받아서 run()메소드 호출
vehicle.run();
}
}
//자식클래스
public class Bus extends Vehicle {
@Override
public void run() { //Bus, Taxi클래스는 Vehicle클래스를 상속받아 run()메소드를 재정의
System.out.println("버스가 달립니다.");
}
}
//자식클래스2
public class Taxi extends Vehicle {
@Override
public void run() {
System.out.println("택시가 달립니다.");
}
}
//실행클래스
public class DriverExample {
public static void main(String[] args) {
Driver driver = new Driver();
Bus bus = new Bus();
Taxi taxi = new Taxi();
driver.drive(bus); //자동 타입 변환: Vehicle vehicle = bus;
driver.drive(taxi); //자동 타입 변환: Vehicle vehicle = taxi;
}
}
//실행결과:
//버스가 달립니다.
//택시가 달립니다.
강제 타입 변환
자식 타입->부모 타입으로 변환한 후, 다시 자식 타입으로 변환할 때만 강제 타입 변환을 사용할 수 있다.
자식타입 변수 - (자식타입) 부모타입; -> 부모 타입을 자식 타입으로 변환
//부모클래스
class Parent {
String field1;
void method1() {...}
void method2() {...}
}
//자식클래스
class Child extends Parent {
String field2;
void method3() {...}
}
//실행클래스
class ChildExample {
public static void main(String[] args) {
Parent parent = new Child();
parent.field1 = "xxx";
parent.method1();
parent.method2();
// parent.field2 = "yyy"; 불가능 ->field2와 method3은 Child타입에만 선언되있으므로
// parent.method3(); 불가능 Parent타입으로 자동 타입 변환이 안된다.
Child child = (Child) parent; //강제타입 변환 해줘야함
child.field2 = "yyy"; //가능
child.method3(); //가능
}
}
객체 타입 확인 - instanceof 연산자
- 어떤 객체가 어떤 클래스의 인스턴스인지 확인하기 위해 instanceof연산자를 사용한다.
- 형식: 객체 + instanceof + 클래스(타입)
->좌항 객체가 우항의 클래스 혹은 인터페이스 타입이면 T, 아니면 F를 리턴한다.
true이면 형변환이 가능하다는 의미이다.
- 강제 타입 변환을 할 때, instanceof 연산자로 확인하고 강제 타입 변환을 해야 한다. 그렇지 않으면 ClassCastException이 발생할 수 있다.
class A{}
class B extends A{}
public class Example {
public static void main(String[] args) {
A a = new A();
B b = new B();
System.out.println(a instanceof A); //true
System.out.println(b instanceof A); //true
System.out.println(a instanceof B); //false
System.out.println(b instanceof B); //true
}
}
07-3) 추상클래스
- 추상클래스는 실체클래스의 공통적 특성(필드,메소드)를 뽑아내어 선언한 클래스이다.- 추상클래스의 용도 1) 공통된 필드와 메소드의 이름을 통일할 목적, 2)실체 크래스 작성할 때 시간 절약
- 추상클래스는 new연산자로 객체 못만들고, 상속을 통해 자식클래스만 만들 수 있다.
//추상메소드 선언
public abstract class Animal { //추상클래스
public String kind;
public void breathe() {
System.out.println("숨을 쉽니다.");
}
public abstract void sound(); //추상메소드
}
//추상메소드 재정의
public class Dog extends Animal { //Animal클래스 상속
public Dog() {
this.kind = "포유류";
}
@Override
public void sound() { //추상메소드 재정의
System.out.println("멍멍");
}
}
//추상메소드 재정의
public class Cat extends Animal {
public Cat() {
this.kind = "포유류";
}
@Override
public void sound() { //추상메소드 재정의
System.out.println("야옹");
}
}
//실행클래스
public class AnimalExample {
public static void main(String[] args) {
Dog dog = new Dog();
Cat cat = new Cat(); //Dog와 Cat객체를 생성해서 sound()메소드를 호출
dog.sound();
cat.sound();
System.out.println("-----");
//변수의 자동 타입 변환
Animal animal = null;
animal = new Dog(); //자동 타입 변환
animal.sound(); //재정의된 메소드 호출
animal = new Cat(); //자동 타입 변환
animal.sound(); //재정의된 메소드 호출
System.out.println("-----");
//메소드의 다형성
animalSound(new Dog());
animalSound(new Cat());
}
public static void animalSound(Animal animal) { //Dog와 Cat 객체가 자동 타입 변환
animal.sound();
}
}
- 위 코드에서 sound()메소드를 호출하는 방법을 세가지로 표현1) Dog와 Cat 변수로 호출2) Animal 변수로 타입 변환해서 sound() 메소드 호출. 자식은 부모 타입으로 자동 타입 변환이 되고, 메소드가 재정의되어 있을 경우, 재정의된 자식 메소드가 호출되는 다형성의 특징이 그대로 적용된다.3) 부모 타입의 매개변수에 자식 객체를 대입해서 메소드의 다형성을 적용했다.
'Java' 카테고리의 다른 글
220118 혼자공부하는자바 Ch9 중첩 클래스와 중첩 인터페이스 (0) | 2022.01.18 |
---|---|
220118 혼자공부하는자바 Ch8 인터페이스 (0) | 2022.01.18 |
220115 혼자공부하는자바 Ch7 상속 (0) | 2022.01.15 |
220112 혼자공부하는자바 Ch6-5~ 모르는 부분 리마인드 (0) | 2022.01.12 |
220109 혼자공부하는자바 Ch6~ 모르는 부분 리마인드 (0) | 2022.01.11 |