본문 바로가기

Java

Java(13) - 다형성, 추상화

728x90
반응형

<목차>

1) 다형성

   1-1) 개념, 형 변환

   1-2) 예제 풀이

2) 추상화

   2-1) 개념, 목적, 구조

   2-2) 예제 풀이

 

 

 

 

1) 다형성

1-1) 개념, 형 변환

개념

다형성 : 하나가 여러 형태를 갖는 성질

Animal(상위 클래스)움직이다라는 메서드를

Human, Tiger, Bird(세 개의 하위 클래스)“Override”해서 구현할 수 있음!

 

 

다형성을 이용한 형 변환

instanceof

해당 인스턴스가 비교 대상의 타입인지 알려주는 예약어

(인스턴스 instanceof 비교 대상)  -->  결과 : true of false

 

 

 

1-2) 예제 풀이

패키지 chapter10.polymorphism

Polymorphism.class

package chapter10.polymorphism;

class Animal {
	void move() {
		System.out.println("동물이 움직입니다.");
	}
}

class Human extends Animal {
	@Override
	void move() {
		System.out.println("사람이 두발로 걷습니다.");
	}
}

class Tiger extends Animal {
	@Override
	void move() {
		System.out.println("호랑이가 네 발로 뜁니다.");
	}
}

class Eagle extends Animal {
	@Override
	void move() {
		System.out.println("독수리가 하늘을 납니다.");
	}
}

public class Polymorphism {

	public static void main(String[] args) {
		// 다형성
		
		// 메서드 호출
		moveAnimal(new Animal());
		
		Animal a = new Human();
		
		moveAnimal(new Human());
		moveAnimal(new Tiger());
		moveAnimal(new Eagle());

	}
	
	public static void moveAnimal(Animal a) {
		a.move();
	}
	
	/*
	public static void moveAnimal(Tiger a) {
		a.move();
	}
	
	public static void moveAnimal(Eagle a) {
		a.move();
	}
	*/

}

 

 

 

 

Instanceof.class

package chapter10.polymorphism;

class Dog extends Animal {
	public char[] test;

	void bark() {
		System.out.println("멍멍");
	}
}

class Dove extends Animal {
	void fly() {
		System.out.println("퍼득 퍼득");
	}
}

public class Instanceof {

	public static void main(String[] args) {
		
		Dog happy = new Dog();
		Dove donald = new Dove();
		
		// 인스턴스 or 객체 instanceof 비교타입
		System.out.println(happy instanceof Animal);
		System.out.println(happy instanceof Dog);
		System.out.println(donald instanceof Animal);
		System.out.println(donald instanceof Dove);
		
		testAnimal(happy);
		testAnimal(donald);
	}
	
	static void testAnimal(Animal animal) {
		// animal.bark();   //err
		
		// 다운 캐스팅
		if (animal instanceof Dog) {
			Dog myDog = (Dog) animal;
			myDog.bark();
		} else if (animal instanceof Dove) {
			Dove myDove = (Dove) animal;
			myDove.fly();
		}
	}

}

 

 

 

 

Customer.class

package chapter10.polymorphism;

public class Customer {
	// 멤버 변수
	protected int customerID;     // 상속관계이거나 같은 패키지까지 접근 허용
	protected String customerName;
	protected String customerGrade;
	int bonusPoint;
	double bonusRatio;
	
	// 기본 생성자
	public Customer() {
		// 메서드 호출
		initCustomer();
	}
	
	// 명시적 생성자
	public Customer(int customerID, String customerName) {
		this.customerID = customerID;        // 초기화
		this.customerName = customerName;    // 초기화
		initCustomer();        // 메서드 호출
	}
	
	// 멤버 메서드
	private void initCustomer() {
		this.customerGrade = "SILVER";     // 초기화
		this.bonusRatio = 0.01;            // 초기화
	}
	
	// 멤버 메서드
	public int calcPrice(int price) {
		this.bonusPoint += price * this.bonusRatio;
		return price;
	}
	
	// 멤버 메서드
	public String showCustomerInfo() {
		return this.customerName + "님의 등급은 "
				+ this.customerGrade + "이며, 보너스 포인트는 "
				+ this.bonusPoint + "입니다.";
	}

	public int getCustomerID() {
		return customerID;
	}

	public void setCustomerID(int customerID) {
		this.customerID = customerID;
	}

	public String getCustomerName() {
		return customerName;
	}

	public void setCustomerName(String customerName) {
		this.customerName = customerName;
	}

	public String getCustomerGrade() {
		return customerGrade;
	}

	public void setCustomerGrade(String customerGrade) {
		this.customerGrade = customerGrade;
	}

}

 

 

 

GoldCustomer.class

package chapter10.polymorphism;

public class GoldCustomer extends Customer {
	double saleRatio;
	
	public GoldCustomer(int customerID, String customerName) {
		super(customerID, customerName);
		this.customerGrade = "GOLD";
		this.bonusRatio = 0.02;
		this.saleRatio = 0.1;
	}
	
	@Override
	public int calcPrice(int price) {
		this.bonusPoint += price * this.bonusRatio;
		return price - (int)(price * this.saleRatio);
	}

}

 

 

 

VIPCustomer.class

package chapter10.polymorphism;

public class VIPCustomer extends Customer {
	private int agentID;
	double saleRatio;
	
	public VIPCustomer(int customerID, String customerName, int agentID) {
		super(customerID, customerName);
		this.customerGrade = "VIP";
		this.bonusRatio = 0.05;
		this.saleRatio = 0.2;
		this.agentID = agentID;
	}
	
	@Override
	public int calcPrice(int price) {
		this.bonusPoint += price * this.bonusRatio;
		return price - (int)(price * this.saleRatio);
	}
	
	@Override
	public String showCustomerInfo() {
		return super.showCustomerInfo() + " [담당 상담원 번호: " + this.agentID + "]";
	}
}

 

 

 

CustomerTest.class

package chapter10.polymorphism;

public class CustomerTest {

	public static void main(String[] args) {
		Customer[] customerList = new Customer[5];
		
		customerList[0] = new Customer(10010, "이순신");
		customerList[1] = new Customer(10020, "신사임당");
		customerList[2] = new GoldCustomer(10030, "홍길동");
		customerList[3] = new GoldCustomer(10040, "이율곡");
		customerList[3].bonusPoint = 1000;
		customerList[4] = new VIPCustomer(10050, "김유신", 1588);
		customerList[4].bonusPoint = 2000;
		
		System.out.println("====== 고객 정보 출력 ======");
		for (Customer c : customerList) {
			System.out.println(c.showCustomerInfo());
		}
		
		System.out.println("====== 할인율과 보너스 포인트 계산 ======");
		int price = 10000;
		for (Customer c : customerList) {
			int cost = c.calcPrice(price);
			System.out.println(c.getCustomerName() + "님이 " + cost + "원 지불하셨습니다.");
			System.out.println(c.getCustomerName() + "님의 " + "현재 보너스 포인트는 " + c.bonusPoint + "점입니다.");
		}

	}

}

 

 

 

 

 

 

2) 추상화

2-1) 개념, 목적, 구조

추상화 : 공통된 행동, 필드를 묶어 하나의 클래스를 만드는 것

 

 

추상 클래스(= 미완성 설계도)

- 하나 이상의 추상 메서드(선언만 되어있고, 구현부가 없는 메서드)를 포함한 클래스

- 추상 클래스를 상속받는 자식 클래스는 부모 클래스의 추상 메서드를 반드시 구현해야만 하는 강제성을 갖는다.

 

=> 완성되지 않은 코드를 가지고 있을 경우, 인스턴스를 생성할 수 없다!!

 

 

추상화 목적

- 공통된 필드와 메서드를 통일할 목적 : 필드와 메서드의 이름을 통일하여 유지보수성을 높이고 통일성을 유지할 수 있다.

- 실체 클래스 구현 시 시간 절약 : 추상 클래스로부터 받은 추상 메서드의 구현부만 만들면 되므로 처음부터 끝까지 만들 필요가 없다.

- 규격에 맞는 실체 클래스 구현 : 설계자의 의도로써 만들어진 추상 클래스를 개발자가 사용하면 추상 메서드를 반드시 이용해야 한다. 오버라이딩하지 않으면 컴파일 에러로 실행부터 안 된다.

 

 

추상 클래스의 구조

(접근 제어자) abstract class 클래스명 {
    멤버 변수;
    멤버 메서드;
    추상 메서드;
}

// 예시 코드
public abstract class Computer {
    // 멤버 변수
    String productNum;
    
    // 멤버 메서드
    public void turnOn() {
        System.out.println(this.name);
    }
    
    // 추상 메서드
    public abstract void display();
    public abstract void typing();
}

 

 

(중요) 추상 메서드는 구현부가 없기 때문에 추상 클래스를 상속받는 하위 클래스가 반드시 구현해야만 한다.

 

 

 

 

2-2) 예제 풀이

패키지 chapter11.interface_part

AbstractTest.class

package chapter11.interface_part;

abstract class Animal {     // 추상화 예약어 abstract
	String name;     // 멤버 변수
	
	Animal(String name) {     // 생성자
		this.name = name;
	}
	
	void alive() {     // 멤버 메서드
		System.out.println("살아 있다");
	}
	
	abstract void move();    // 추상 메서드
}

abstract class Human extends Animal {
	Human(String name) {
		super(name);
	}
	
	@Override
	/*
	void move() {
		System.out.println("두 발로 걷다");
	}
	*/
	abstract void move();
}

class Student extends Animal {
	Student(String name) {
		super(name);
	}
	
	@Override
	void move() {
		System.out.println("땡땡이 치기");
	}
}

class Tiger extends Animal {
	Tiger(String name) {
		super(name);
	}
	
	@Override
	void move() {
		System.out.println("네 발로 걷다");
	}
}

class Eagle extends Animal {
	Eagle(String name) {
		super(name);
	}
	
	@Override
	void move() {
		System.out.println("날다");
	}
}

public class AbstractTest {

	public static void main(String[] args) {
		// Animal a = new Animal("동물");     // 추상 클래스는 인스턴스 생성 불가함!
		// Animal b = new Human("사람");
		Animal e = new Student("학생");
		Animal c = new Tiger("호랑이");
		Animal d = new Eagle("독수리");
		
		// b.alive();
		// b.move();
		c.move();
		d.move();
		e.move();

	}

}