Java
public class Phone {
String tel;
void call() { ... }
void disconnect() { ... }
}
publc class FeaturePhone extends Phone {
void mp3() { ... }
}
public class SmartPhone extends Phone {
String ip;
String mailAddress;
void web() { ... }
void email() { ... }
}
public class Iphone extends SmartPhone {
void faceId() { ... }
}
public static void main(String[] args) {
// 형변환없이 해당 타입의 변수에 담기
Phone p1 = new Phone(); // 성공
FeaturePhone p2 = new FeaturePhone(); // 성공
SmartPhone p3 = new SmartPhone(); // 성공
Iphone p4 = new Iphone(); // 성공
// Phone타입의 변수에 객체 담기
Phone p11 = new Phone(); // 성공 자식객체를 상위타입 참조변수에 대입
Phone p12 = new FeaturePhone(); // 성공 자식객체를 상위타입 참조변수에 대입
Phone p13 = new SmartPhone(); // 성공 자식객체를 상위타입 참조변수에 대입
Phone p14 = new Ihone(); // 성공 자식객체를 상위타입 참조변수에 대입
// FeaturePhone타입의 변수에 객체 담기
FeaturePhone p21 = new Phone(); // 오류 상위타입 객체를 대입할 수 없음
FeaturePhone p22 = new FeaturePhone(); // 성공 참조변수 타입과 동일한 개체 타입이라서 가능
FeaturePhone p23 = new SmartPhone(); // 오류 서로 상속관계가 아님
FeaturePhone p24 = new Iphone(); // 오류 서로 상속관계가 아님
// SmartPhone타입의 변수에 객체 담기
SmartPhone p31 = new Phone(); // 오류 상위타입 객체를 대입할 수 없음
SmartPhone p32 = new FeaturePhone(); // 오류 서로 상속관계 아님
SmartPhone p33 = new SmartPhone(); // 성공 참조변수 타입과 동일한 개체 타입이라서 가능
SmartPhone p34 = new Iphone(); // 성공 자식객체를 상위타입 참조변수에 대입
// Iphone타입의 변수에 객체 담기
Iphone p41 = new Phone(); // 오류
Iphone p42 = new FeaturePhone(); // 오류
Iphone p43 = new SmartPhone(); // 오류
Iphone p44 = new Iphone(); // 성공
}
package day2;
public class ClassCastingApp {
public static void main(String[] args) {
Panzer car1 = new Panzer();
PoliceCar car2 = new Panzer();
Car car3 = new Panzer();
System.out.println("### Panzer 타입의 참조변수로 Panzer 객체 참조하기");
// Panzer 객체의 메소드 사용가능
car1.setWeapon("기관총");
car1.fireWeapon();
// PoliceCar 객체의 메소드 사용가능 <-- Panzer의 상위 클래스임
car1.patrol();
// Car 객체의 메소드 사용가능 <-- PoliceCar의 상위 클래스임
car1.setColor("검정색");
car1.drive();
car1.stop();
System.out.println("### PoliceCar 타입의 참조변수로 Panzer 객체 참조하기");
// Panzer 객체의 메소드 사용가능
// car2.setWeapon("기관총"); // 오류 - 사용불가
// car2.fireWeapon(); // 오류 - 사용불가
// PoliceCar 객체의 메소드 사용가능 <-- Panzer의 상위 클래스임
car2.patrol();
// Car 객체의 메소드 사용가능 <-- PoliceCar의 상위 클래스임
car2.setColor("파랑색");
car2.drive();
car2.stop();
System.out.println("### Car 타입의 참조변수로 Panzer 객체 참조하기");
// Panzer 객체의 메소드 사용가능
// car3.setWeapon("기관총"); // 오류 - 사용불가
// car3.fireWeapon(); // 오류 - 사용불가
// PoliceCar 객체의 메소드 사용가능 <-- Panzer의 상위 클래스임
// car3.patrol(); // 오류 - 사용불가
// Car 객체의 메소드 사용가능 <-- PoliceCar의 상위 클래스임
car3.setColor("하얀색");
car3.drive();
car3.stop();
}
}
package day2;
public class ClassCastingApp2 {
public static void main(String[] args) {
Car car1 = new Car();
Car car2 = new PoliceCar();
Car car3 = new Panzer();
System.out.println("### Car타입의 참조변수로 Car객체 참조하기");
car1.drive(); // Car객체의 기능 사용하기
car1.stop(); // Car객체의 기능 사용하기
// PoliceCar car12 = (PoliceCar) car1; // 실행 오류, car1이 참조하는 객체에는 PoliceCar가 없음
// car12.patrol();
// String car13 = (String) car1; // 컴파일 오류, car1이 참조하는 객체와 String은 상속관계가 아님.
System.out.println("### Car타입의 참조변수로 PoliceCar객체 참조하기");
car2.drive(); // Car객체의 기능 사용하기
car2.stop(); // Car객체의 기능 사용하기
PoliceCar car22 = (PoliceCar) car2; // car2로 참조되는 객체에서 PoliceCar 객체로 옮겨가기
car22.patrol(); // PoliceCar객체의 기능 사용하기
((PoliceCar) car2).patrol(); // PoliceCar객체로 옮겨서 순찰기능 실행
System.out.println("### Car타입의 참조변수로 Panzer객체 참조하기");
car3.drive(); // Car객체의 기능 사용하기
car3.stop(); // Car객체의 기능 사용하기
PoliceCar car32 = (PoliceCar) car3; // car3로 참조되는 객체에서 PoliceCar 객체로 옮겨가기
car32.patrol(); // PoliceCar객체의 기능 사용하기
Panzer car33 = (Panzer) car3; // car3로 참조되는 객체에서 Panzer 객체로 옮겨가기
car33.fireWeapon(); // Panzer객체의 기능 사용하기
}
}
package day2;
public class ClassCastingApp3 {
public static void main(String[] args) {
Car[] carList = new Car[5];
carList[0] = new Car();
carList[1] = new Panzer();
carList[2] = new FireTruck();
carList[3] = new PoliceCar();
carList[4] = new Panzer();
// instansOf
// 향샹된 for문을 사용해서 배열에 저장된 다양한 Car객체를 순서대로 조회해서
// Car객체면 운전기능, 정지기능 실행해보기
// PoliceCar객체면 운전기능, 정지기능, 순찰기능 실행해보기
// FireTruck객체면 운전기능 ,정지기능, 화재진압기능 실행해보기
// Panzer객체면 운전기능, 정지기능, 순찰기능, 무기발사기능 실행해보기
for (Car car : carList) {
System.out.println("### car참조변수가 참조하는 객체 주요 기능 확인");
car.drive();
car.stop();
if (car instanceof FireTruck) {
FireTruck x = (FireTruck) car;
x.suppressFire();
}
if (car instanceof PoliceCar) {
PoliceCar x = (PoliceCar) car;
x.patrol();
}
if (car instanceof Panzer) {
Panzer x = (Panzer) car;
x.fireWeapon();
}
System.out.println();
}
}
}
메소드 중복정의
+ 하나의 클래스에 안에 동일한 이름의 메소드를 여러 개 정의하는 것
+ 접근제한자, 반환타입의 상관없다.
+ 메소드이름이 동일하고, 매개변수의 타입, 갯수가 다르기만 하면 된다.
+ 목적
* 하나의 클래스안에 매개변수만 다르고 수행하는 작업은 비슷한 경우 일관성있고 동일한 메소드 이름으로 실행하게 한다.
메소드 재정의
다형성
+ 실행방법은 동일하지만 사용하는 객체가 달라지면
다른 결과가 발현되는 것
+ 객체지향 프로그래밍의 주요한 특징이다
+ 메소드 재정의, 추상화, 인터페이스 등의 기술을 활용해서 다양하게 활용할 수 있다.
package day2.game;
public class GameApp2 {
public static void main(String[] args) {
Unit[] units = new Unit[4];
units[0] = new Marine();
units[1] = new Firebat();
units[2] = new Ghost();
units[3] = new BattleCruiser();
for (Unit unit : units) {
// - unit 참조변수는 다양한 종류의 Unit류 객체를 참조한다.
// - unit 참조변수가 참조하는 Unit류 객체는 모두 Unit클래스의 하위클래스고,
// 클래스의 목적에 맞게 move()나 attack()을 재정의하고 있다.
// - unit 참조변수가 참조하는 객체의 종류에 상관없이 unit.move(); unit.attack();를
// 실행하면 객체의 목적에 맞게 재정의된 move()나 attack()가 실행된다.
// - 결론
// * Marine, Firebat, Ghost, BattleCruiser객체에 재정의된 move()나 attack()를
// 실행하기 위해서 해당 객체 타입으로 형변환이 필요없어진다.
// * Unit클래스의 하위 클래스가 나중에 추가되더라도 이동기능, 공격기능을 실행하는 방법은
// 변하지 않는다.
// * 프로그램의 확장성이 높아진다.
unit.move();
unit.attack();
System.out.println();
}
}
}