-여러 가지 형태를 가질 수 있는 능력
-하나의 참조변수로 여러 타입의 객체를 참조할 수 있는 것, 즉, 조상타입의 참조변수로 자손타입의 객체를 다룰 수 있는 것이 다형성
-서로 상속관계에 있는 타입간의 형변환만 가능하다.
-자손 타입에서 조상타입으로 형변환하는 경우, 형변환 생략가능
자손타임 -> 조상타입 (Up-casting) : 형변환 생략가능
자손타입 <- 조상타입 (Down-casting) : 형변환 생략불가
-car클래스-
public class Car {
String color;
int door;
void drive() {
System.out.println("자동차가 갑니다.");
}
void stop() {
System.out.println("자동차가 멈춘다.");
}
}
-FireEngine클래스-
public class FireEngine extends Car {
void drive() {
System.out.println("소방차가 갑니다.");
}
void stop() {
System.out.println("소방차가 멈춘다.");
}
void water() {
System.out.println("물을 뿌립니다.");
}
}
-Ambulacne클래스-
public class Ambulance extends Car{
void drive() {
System.out.println("구급차가 갑니다.");
}
void stop() {
System.out.println("구급차가 멈춘다.");
}
void siren() {
System.out.println("사이렌을 울립니다.");
}
}
-Ex11 출력 클래스-
public class Ex11 {
public static void main(String[] args) {
Car myCar = new Car();
FireEngine Fire = new FireEngine();
Ambulance ambulance = new Ambulance();
myCar.drive();
myCar = Fire;
myCar.drive();
myCar = ambulance;
myCar.drive();
}
}
-Ex12 출력 클래스-
public class Ex12 {
public static void main(String[] args) {
Car [] cars = new Car[3];
cars[0] = new Car();
cars[1] = new FireEngine();
cars[2] = new Ambulance();
//Car myCar = new Car();
for(Car myCar : cars) {
myCar.drive();
}
}
}
-Ex13 출력 클래스-
public class Ex13 {
void driveCar(Car myCar) {
myCar.drive();
}
public static void main(String[] args) {
Ex13 ex13 = new Ex13();
Car myCar = new Car();
FireEngine Fire = new FireEngine();
Ambulance ambulance = new Ambulance();
ex13.driveCar(myCar);
ex13.driveCar(Fire);
ex13.driveCar(ambulance);
}
}
-3개 코드는 다르지만 출력은 전부 똑같음-
-Ex14 출력 클래스-
public class Ex14 {
public static void main(String[] args) {
Car myCar = new Car();
//FireEngine fire = (FireEngine)myCar;오류인데 오류메세지 안보여줌
try {
FireEngine fire = (FireEngine)myCar; //자기자신을 가르키는것임
fire.drive();
}catch(Exception e){
e.printStackTrace();
}
}
}
-Ex15 출력 클래스-
public class Ex15 {
public static void main(String[] args) {
Car myCar = new FireEngine();
myCar.drive();
myCar.stop();
//myCar.water();
FireEngine fire = (FireEngine)myCar; //다운캐스팅
fire.water();
}
}
-참조변수가 참조하는 인스턴스의 실제 타입을 체크하는데 사용.
-이항연산자이며 피연산자는 참조형 변수와 타입, 연산결과는 true,false
-instanceof의 연산결과가 true이면, 해당타입으로 형변환이 가능하다.
-Ex16 출력클래스-
public class Ex16 {
public static void main(String[] args) {
Car myCar = new Car();
FireEngine Fire = new FireEngine();
Ambulance ambulance = new Ambulance();
System.out.println("mycar instanceof car: "+(myCar instanceof Car));
System.out.println("mycar instanceof FireEngine: "+(myCar instanceof FireEngine));
System.out.println("mycar instanceof Ambulance: "+(myCar instanceof Ambulance));
System.out.println("mycar instanceof car: "+(Fire instanceof Car));
System.out.println("mycar instanceof FireEngine: "+(Fire instanceof FireEngine));
//System.out.println("mycar instanceof Ambulance: "+(Fire instanceof Ambulance));
System.out.println("mycar instanceof car: "+(ambulance instanceof Car));
//System.out.println("mycar instanceof FireEngine: "+(ambulance instanceof FireEngine));
System.out.println("mycar instanceof Ambulance: "+(ambulance instanceof Ambulance));
}
}
-Ex17 클래스-
public class Ex17 {
public static void main(String[] args) {
Car c1,c2,c3;
c1 = new Car();
c2 = new FireEngine();
c3 = new Ambulance();
System.out.println("c1 instanceof car: "+(c1 instanceof Car));
System.out.println("c1 instanceof FireEngine: "+(c1 instanceof FireEngine));
System.out.println("c1 instanceof Ambulance: "+(c1 instanceof Ambulance));
System.out.println("==============");
System.out.println("c2 instanceof car: "+(c2 instanceof Car));
System.out.println("c2 instanceof FireEngine: "+(c2 instanceof FireEngine));
System.out.println("c2 instanceof Ambulance: "+(c2 instanceof Ambulance));
System.out.println("==============");
System.out.println("c3 instanceof car: "+(c3 instanceof Car));
System.out.println("c3 instanceof FireEngine: "+(c3 instanceof FireEngine));
System.out.println("c3 instanceof Ambulance: "+(c3 instanceof Ambulance));
}
}
-소방차이면 물을 뿌리고 구급차이면 사이렌을 울리는 코드를 작성하세요.
public class Ex18 {
public static void main(String[] args) {
Car [] cars = new Car[3];
cars[0] = new Car();
cars[1] = new FireEngine();
cars[2] = new Ambulance();
//Car myCar = new Car();
for(Car myCar : cars) {
myCar.drive();
//소방차이면 물을 뿌리고 구급차이면 사이렌을 울리는 코드를 작성하세요.
if(myCar instanceof FireEngine) {
FireEngine fire = (FireEngine)myCar;
fire.water();
}else if(myCar instanceof Ambulance) {
Ambulance siren = (Ambulance)myCar;
siren.siren();
}
myCar.stop();
}
}
}
-멤버변수가 중복정의된 경우, 참조변수의 타입에 따라 연결되는 멤버변수가 달라진다. (참조변수타입에 영향받음)
-메서드가 중복정의된 경우, 참조변수의 타입에 관계없이 항상 실제 인스턴스의 타입에 정의된 메서드가 호출된다. (참조변수타입에 영향받지 않음)
-자식들은 부모의 추상메서드를 오버라이딩해서 구현해줘야함.
-unit 클래스-
package chap07;
public abstract class Unit {
int x, y;
Unit(int x, int y){
this.x = x;
this.y = y;
}
abstract void move(int x, int y);
void stop() {
System.out.println("현재 유닛이 멈춥니다.");
}
}
-marine 클래스-
public class Marine extends Unit {
Marine(int x, int y) {
super(x, y);
}
void move(int x, int y){
System.out.println("마린이: "+x+", "+y+" 위치로 이동합니다.");
this.x = x;
this.y = y;
}
void stimpack() {
System.out.println("마린이 미쳤어요!");
}
}
-tank 클래스-
public class Tank extends Unit {
Tank(int x, int y) {
super(x, y);
}
void move(int x, int y){
System.out.println("탱크가: "+x+", "+y+" 위치로 이동합니다.");
this.x = x;
this.y = y;
}
void changemode() {
System.out.println("음성모드로 변경");
}
}
-dropship 클래스-
public class Dropship extends Unit {
Dropship(int x, int y) {
super(x, y);
}
void move(int x, int y){
System.out.println("수송선이: "+x+", "+y+" 위치로 이동합니다.");
this.x = x;
this.y = y;
}
void load() {
System.out.println("수송선이 병력을 태웁니다.");
}
void unload() {
System.out.println("수송선이 병력을 내립니다.");
}
}
-Ex20 출력 클래스-
public class Ex20 {
void play(Unit unit,int x, int y) {
unit.move(x,y);
if(unit instanceof Marine) {
Marine marine = (Marine)unit;
marine.stimpack();
}else if(unit instanceof Tank) {
Tank tank = (Tank)unit;
tank.changemode();
}else if(unit instanceof Dropship) {
Dropship dropship = (Dropship)unit;
dropship.load();
dropship.unload();
}
}
public static void main(String[] args) {
//유닛의 모든 기능을 수행하는 메서드
Unit [] units = new Unit[4];
units[0] = new Marine(10,20);
units[1] = new Tank(10,20);
units[2] = new Marine(20,35);
units[3] = new Dropship(60,20);
//play() 메서드를 이용해 모든 유닛을 사용하는 코드를 입력하세요.
Ex20 ex20 = new Ex20();
for(Unit unit : units) {
ex20.play(unit,unit.x,unit.y);
}
}
}
-일종의 추상클래스, 추상클래스(미완성 설계도)보다 추상화 정도가 높다.
-실제 구현된 것이 전혀 없는 기본 설계도,(알맹이 없는 껍데기)
-추상메서드와 상수만을 멤버로 가질 수 있다.
-인스턴스를 생성할 수 없고, 클래스 작성에 도움을 줄 목적으로 사용된다.
-미리 정해진 규칙에 맞게 구현하도록 표준을 제시하는 데 사용된다.
자바의정석-남궁성 참고