[다형성과 상속]
(1) 다형성과 상속(extends, implements, Override)
- 우선 다형성이란? : 하나의 타입이 여러 형태로 동작할 수 있다는 성질, OOP의 특징, 객체는 각각 고유한 성질을 가진다
- 다형성은 어떻게 프로그래밍에서 나타나나?
1) 객체타입에서의 다형성 : 여러 역할을 가질 수 있음
- extends, implements 사용
- A 카페에서는 손님, B 카페에서는 바리스타
2) 메서드의 다형성 : 같은 타입을 구현하는 객체타입이지만 각각 다르게 동작할 수 있음
- 같은 Tire를 상속하고 Tire의 roll 메서드를 오버라이딩하지만 HankookTire, KumhoTire는 각각 다른 내부동작(성능)을 가짐
- 같은 객체 타입에서 파생됐지만 각각의 특성을 가짐
- 자바 syntax 다형성 구현 지원
1) abstract, interface - extends, implements + Override
- 하나의 객체타입이 여러개의 객체타입을 구현할 수 있음 : 다양한 역할을 할 수 있다 이말이지!
public class Person {
private String name;
public Person(String name){
this.name = name;
}
public static void main(String[] args) {
Person p1 = new Jinbro("jinbro1");
p1.getName(); //Jinbro.getName()
p1.sayHello(); //Person.sayHello()
Jinhyung jinhyung = new Jinhyung("jinhyung");
Person p2 = jinhyung;
System.out.println(jinhyung == p2); // true
}
public String getName() {
return name;
}
public void sayHello(){
System.out.println("Say Hello");
}
}
class Jinbro extends Person implements Barista, Customer{
public static void main(String[] args) {
Jinbro jinbro = new Jinbro("jinbro2");
jinbro.makeCoffee();
}
public Jinbro(String name) {
super(name);
}
@Override
public void order() {
//같은 역할(타입)이지만 다르게 동작(메서드 내부가 다름)
System.out.println("아메리카노요");
}
@Override
public String getName() {
return super.getName() + "입니다";
}
@Override
public void makeCoffee() {
}
}
class Jinhyung extends Person implements Customer {
public Jinhyung(String name) {
super(name);
}
@Override
public void order() {
System.out.println("딸기스무디!");
}
}
interface Customer{
public void order();
}
interface Barista{
public void makeCoffee();
}
- abstract : 공통된 특성(필드, 메서드)을 뽑아 만든 클래스, 역할의 표준화(코드 줄이기, 통일)
public abstract class Phone {
private String sound = "텔렐렐렐렐 ";
public void tell(){
System.out.println(sound + "전화를 겁니다");
}
public abstract void sms();
}
class SmartPhone extends Phone {
public static void main(String[] args) {
SmartPhone sp = new SmartPhone();
sp.tell();
}
/* SmartPhone에만 있는 기능 */
public void goAppStore(){
}
/* Phone 역할을 한다면 공통적으로 가지는 기능 */
@Override
public void tell() {
super.tell();
}
@Override
public void sms() {
/* 각각 다르게 작성할 수 있음 */
}
}
=> 우리가 new 키워드로 인스턴스는 만들지못함 : super를 호출하는 것 보면 abstract 키워드를 쓰면 내부적으로는 싱글턴인가...?
=> 생성자는 가져야함 : 내부적으로 추상클래스 인스턴스 생성한다고하니깐
=> extends로 상속할 수 있음 : 역할 부여받음
=> 공통된 특성을 가지고, 공통된 행동(메서드 내부처리)를 가질 수도 있고 다르게 할 수도 있음(abstract 메서드 - 오버라이딩)
- interface : abstract에서 필드는 빼고 공통된 메서드를 뽑아서 만듬
=> 뒤에서 더 살펴보겠음
2) 상위 객체타입 변수가 하위 객체타입 인스턴스의 주소값을 참조할 수 있도록 지원함
- 하위 객체타입 인스턴스가 상위 객체타입으로 자동형변환 : 주소값 그대로
=> 상위 객체타입 필드, 메서드 + 오버라이딩 메서드만 사용 가능 : 공통된 것만
=> 자동형변환된 이후 상위 -> 하위로 강제형변환(캐스팅)할 수 있음(반드시 이때만 가능) : 다시 사용가능함
=> 객체 instanceof 객체타입 : 캐스팅 전에 자동형변환된 객체타입이 맞는지, 그 타입이 맞는지 확인가능
=> 잘못된 캐스팅 에러 : ClassCastException 예외 발생
- 2번 항목이 가능하므로 : 필드 타입 표준화하면서 다양한 동작을 지원함
=> Tire를 상속받는 하위 타입이라면 모두 참조하도록 가능함, 인스턴스(하위)타입만 변경되지 Tire다
=> 같은 Tire를 상속받고 메서드 오버라이딩하지만 각 타이어에 따라 동작함
public class Car {
Tire frontLeftTire;
Tire frontRightTire;
Tire backLeftTire;
Tire backRightTire; //표준화된 타입으로 필드 타입 선언가능
public Car(){
frontLeftTire = new HankookTire(1000);
/*
1) Tire 타입을 HankookTire로 변경하지않아도됨 : Tire를 상속받았다면 모두 가능
2) 한국타이어의 성능을 맛볼 수 있지
*/
}
}
class Tire {
private int maxRotation;
public Tire(int maxRotation){
this.maxRotation = maxRotation;
}
public void roll(){
System.out.println("바퀴가 굴러갑니다");
}
}
class HankookTire extends Tire {
/* 1000회 더! */
public HankookTire(int maxRotation) {
super(maxRotation + 1000);
}
@Override
public void roll() {
/* 한국타이어 마음대로 움직인다! */
System.out.println("바퀴가 굴러가요오오오!!!!");
}
}
- 2번 항목이 가능하므로 : 메서드의 매개변수 타입 표준화하면서 다양한 동작을 지원
public class Driver {
public void drive(Vehicle vehicle){
//Sedan, Suv 모두 몰 수 있다!!!
vehicle.run();
if(vehicle instanceof Sedan){
Sedan sedan = (Sedan)vehicle;
System.out.println(sedan.getColor());
}
}
}
class Vehicle {
public void run(){
System.out.println("달립니다!");
}
}
class Sedan extends Vehicle {
private String color = "black";
@Override
public void run() {
System.out.println("조용조용조용하지만 빠르게 달립니다");
}
public String getColor() {
return color;
}
}
class Suv extends Vehicle {
@Override
public void run() {
System.out.println("거칠지만 더 빠르게 달립니다");
}
}
=> Vehicle이 가진 같은 메서드를 사용하지만 Sedan / Suv에 따라 다르게 동작하게
[정리]
1) 다형성은 하나의 타입이 여러 역할이나 행동처럼 여러 모습을 가질 수 있다는 것
2) 자바의 다형성 구현
- 여러 역할, 행동을 가질 수 있게 지원하는 것 : abstract, interface, Override
- 상속 관계 간에 자동형변환 된다는 것 : 필드 타입, 매개변수 타입 표준화
'java' 카테고리의 다른 글
[Java] 인터페이스 그리고 OOP 다형성 (0) | 2017.09.26 |
---|---|
[Java] JDBC와 RDBMS 개념 이야기 (0) | 2017.09.25 |
[Java] 객체지향과 상속 #1 - 상속이란? (0) | 2017.09.24 |
[Java] 어노테이션 - xml을 벗어나자 (0) | 2017.09.21 |
[Java] 클래스 - 객체지향, static, instance, 접근제어자, 싱글턴 등 (0) | 2017.09.19 |
댓글