본문 바로가기
java

[Java] 객체지향과 상속#2 - 자바 다형성 구현과 상속

by jinbro 2017. 9. 24.

[다형성과 상속]

(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

- 상속 관계 간에 자동형변환 된다는 : 필드 타입, 매개변수 타입 표준화


댓글