
Person[] 김현정 = {
new Daughter(),
new Student(),
new Employee()
};
for (Person 역할 : 김현정) {
역할.자기소개(); // 각각 다르게 오버라이딩된 메서드 호출
}
Person 김달래 = new 학생();
김달래.자기소개(); // "안녕하세요 학생입니다."
Daughter d = new Daughter();
Student s = new Student();
Employee e = new Employee();
d.자기소개();
s.자기소개();
e.자기소개();
class Animal {}
class Dog extends Animal {
void sound() {
System.out.println("멍멍!");
}
}
Dog 달래 = new Dog(); // 달래는 강아지
Animal 동물 = 달래; // ✅ 업캐스팅 (자동 형변환)
Dog 다시달래 = (Dog) 동물; // ✅ 다운캐스팅 (명시적 형변환)
다시달래.sound(); // 멍멍
Animal 초코 = new Animal(); // 초코는 그냥 동물
Dog 가짜달래 = (Dog) 초코; // ❌ 컴파일은 되지만 실행하면 에러!
가짜달래.sound(); // ❌ 실제로 Dog가 아니라서 문제 생김
if (초코 instanceof Dog) { // 형변환 오류 주의사항. 초코는 그냥 동물이지 강아지가 아님 (false)
Dog 가짜달래 = (Dog) 초코;
가짜달래.sound();
}
영문 변수명
Dog d = new Dog(); // d는 강아지
Aimal a = d; // 업캐스팅 (자동 형변환)
Dog d2 = (Dog)a; // 다운캐스팅 (명시적 형변환)
d2.bark() // 멍멍
void buy(Product p) 메서드로 다양한 상품 구매 처리class Product {
int price;
}
class Tv extends Product {}
class Computer extends Product {}
class Buyer {
void buy(Product p) {
System.out.println("구매 완료!");
}
}
public class Main {
public static void main(String[] args) {
Buyer b = new Buyer();
b.buy(new Tv()); // Tv도 Product
b.buy(new Computer()); // Computer도 Product
}
}void moveUnit(Unit u) 메서드로 다양한 유닛 움직임public class Main {
// 매개변수 다형성 적용
static void moveUnit(Unit u, int x, int y) {
u.move(x, y);
}
public static void main(String[] args) {
Unit marine = new Marine();
Unit tank = new Tank();
moveUnit(marine, 5, 10); // Marine is moving.
moveUnit(tank, 3, 72); // Tank is moving.
}
}abstract class Animal {
abstract void sound(); // 추상 메서드, 자식 클래스에서 반드시 구현해야 함
}
class Dog extends Animal {
void sound() {
System.out.println("멍멍!");
}
}
a.sound();abstract class Animal {
abstract void sound(); // 추상메서드
void sleep() { // 일반메서드
System.out.println("잠자기");
}
}
Animal[] animals = {new Dog(), new Cat(), new Dallae()};
for(Animal a : animals) {
a.sound(); // 각 동물마다 다르게 소리냄 (추상메서드 오버라이딩)
a.sleep(); // 모두 동일하게 "잠자기" 출력 (일반메서드)
}
Unit[] group = { new Marine(), new Tank(), new Dropship() };for(int i=0; i<group.length; i++) group[i].move(100, 200);interface Runnable {
void run();
}
class Dog implements Runnable {
public void run() {
System.out.println("강아지가 달린다!");
}
}
class Cat implements Runnable {
public void run() {
System.out.println("고양이가 달린다!");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.run(); // "강아지가 달린다!"
}
}
class Dallae extends Dog implements petable, Trainable { ... }Trainable 인터페이스를 통해 훈련 가능한 객체만 골라서 처리void conductTraning(Trainable t) { t.train(); }interface Runnable {
void run();
}
class Dog implements Runnable {
public void run() {
System.out.println("강아지가 달린다!");
}
}
class Cat implements Runnable {
public void run() {
System.out.println("고양이가 달린다!");
}
}
public class Main {
public static void main(String[] args) {
Runnable runnable1 = new Dog();
Runnable runnable2 = new Cat();
runnable1.run(); // "강아지가 달린다!"
runnable2.run(); // "고양이가 달린다!"
}
}
강사님한테도 다시 물어봐서 얻은 정확한 답변!
전제조건이 ‘메서드가 하나일 경우’에는 인터페이스를 사용하는 것이 더 일반적이고 유연하다.
기능 중심의 설계가 필요할 때 인터페이스가 적합하며 다중 구현이 가능하기에 확장성도 좋기 때문이다.
발표 때 헛소리를 했습니다…
기본형의 형변환은 진짜 값을 잘라내는 것. 잃는거 맞음
double d = 1.5;
int i = (int) d; // i는 1 (0.5 사라짐)
double d2 = (double) i; // d2는 1.0 (이미 0.5는 날아감)
참조형의 형변환은 실제 값은 그대로 있지만 사용할 수 있는 기능의 범위만 제한되는 것. 잃는 거 아니고 참조타입을 부모타입, 자식타입 바꿔끼워가며 쓴다고 생각
Dog d = new Dog();
Animal a = (Animal) d; // 업캐스팅 – Dog의 정보는 살아있지만 Animal처럼 취급됨
a.sound(); // 컴파일 에러 – Animal엔 bark() 없음
Dog d2 = (Dog) a; // 다시 다운캐스팅하면 Dog 기능(bark) 사용 가능
d2.sound(); // 잘 동작됨