같은 타입이지만 실행 결과가 다양한 객체 대입(이용) 가능한 성질
부모 타입에는 모든 자식 객체가 대입 가능
-자식 타입은 부모 타입으로 자동 타입 변환
public class Parent {
public void method1() {
System.out.println("Parent - method1");
}
public void method2() {
System.out.println("Parent - method2");
}
}
public class Child extends Parent{
@Override
public void method2() {
System.out.println("Child - method2");
}
public void method3() {
System.out.println("Child - method3");
}
}
public class Main {
public static void main(String[] args) {
Child child = new Child();
child.method1();
child.method2();
child.method3();
System.out.println();
Parent parent = child; //promotion
parent.method1();
//override 했기 때문에 child의 method2가 출력
parent.method2();
// parent.method3();
}
}
부모 타입이면 모두 자식 타입으로 강제 타입 변환할 수 있는 것 아님
먼저 자식 타입인지 확인 후 강제 타입 실행해야 함
package p09.instanceof_use;
class Parent{}
class Child extends Parent{}
/*
* method2() coding방식으로 하지말고, method1()방식으로 코딩할것
* => class casting 할때 반드시 instanceof 를 사용하여 강제 형변환 가능한지 먼저 체크할것
*/
public class InstanceOfEx {
public static void main(String[] args) {
Parent pa = new Child();
method1(pa);
method2(pa);
Parent pb = new Parent();
method1(pb);
method2(pb);
}
public static void method1(Parent parent) {
if(parent instanceof Child) {
Child child = (Child) parent; //casting
System.out.println("method1 - child instance 변환성공");
}else {
System.out.println("method1 - child instance 변환 할수 없습니다");
}
}
public static void method2(Parent parent) {
Child child = (Child)parent;
System.out.println("method2 - child instance 변환성공");
}
}
위와 같이 코딩 한 이유는 instanceof로 먼저 자식 타입인지 확인한후 casting이 가능한지 알아보기 위해서 이다.
추상(abstract)
• 실체들 갂에 공통되는 특성을 추출한 것
– 예1: 새, 곤충, 물고기 동물 (추상)
– 예2: 삼성, 현대, LG 회사 (추상)
추상 클래스(abstract class)
• 실체 클래스들의 공통되는 필드와 메소드 정의한 클래스
• 추상 클래스는 실체 클래스의 부모 클래스 역할 (단독 객체 X)
- 실체 클래스의 공통된 필드와 메소드의 이름 통일할 목적
• 실제 클래스를 설계자가 여러 사람일 경우,
• 실제 클래스마다 필드와 메소드가 제각기 다른 이름을 가질 수 있음 실제 클래스를 작성할 때 시간 절약
• 실체 클래스는 추가적인 필드와 메소드만 선언- 실체 클래스 설계 규격을 만들고자 할 때
• 실체 클래스가 가져야 할 필드와 메소드를 추상 클래스에 미리 정의
• 실체 클래스는 추상 클래스를 무조건 상속 받아 작성
public abstract class Phone {
public String owner;
public Phone(String owner) {
this.owner = owner;
}
public void turnOn() {
System.out.println("폰 전화를 켭니다");
}
public void turnOff() {
System.out.println("폰 전화를 켭니다");
}
}
public class SmartPhone extends Phone {
public SmartPhone(String owner) {
super(owner);
}
public void internetSearch() {
System.out.println("인터넷 검색을 합니다.");
}
}
/*
* 추상클래스 abstract_class
* 1. class가 추상 클래스로 선언되면, 추상클래스를 직접 new를 사용하여 인스턴스 생성 불가
* 2. 추상클래스를 사용하려면, 추상클래스를 부모로 한 자식 클래스를 new를 사용하여 인스턴스 만드는 것은 허용
* 3. 추상클래스 내부에 생성자는 있어야만 함
* -자식클래스를 통해 부모인 추상클래스를 힙메모리에 인스턴스로 생성후에 부모 추상클래스의 생성자를 호출
*/
public class SmartPhoneEx {
public static void main(String[] args) {
// Phone Phone = new Phone("홍길동"); //인스턴스 생성 불가
SmartPhone sp = new SmartPhone("홍길동");
sp.turnOn();
sp.internetSearch();
sp.turnOff();
}
}
메소드 이름 동일하지만, 실행 내용이 실체 클래스마다 다른 메소드
예: 동물은 소리를 낸다. 하지만 실체 동물들의 소리는 제각기 다르다.
구현 방법
• 추상 클래스에는 메소드의 선언부만 작성 (추상 메소드)
• 실체 클래스에서 메소드의 실행 내용 작성(오버라이딩(Overriding))
추상클래스와 추상메소드를 사용하는 목적
/*
public abstract class Animal {
public String kind;
public void breathe() {
System.out.println("숨을 쉽니다");
}
// 추상메소드 (abstract_method) :method body에 대한 coding이 없음
public abstract void sound();
}
#### 자식 클래스(Cat,Dog)
```java
public class Cat extends Animal{
public Cat() {
this.kind = "포유류";
}
@Override
public void sound() {
System.out.println("야옹");
}
}
public class Dog extends Animal{
public Dog() {
this.kind = "포유류";
}
@Override
public void sound() {
System.out.println("멍멍");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
Cat cat = new Cat();
dog.sound();
cat.sound();
System.out.println("------------------");
Animal animal = dog; //promotion
animal.sound(); //polymorphism
animal = cat; //polymorphism
animal.sound();
System.out.println("------------------");
animalSound(new Dog());
animalSound(new Cat());
}
// parameter promotion
public static void animalSound(Animal animal) {
animal.sound(); //polymorphism
}
}