다형성(Polymotphism)
- 객체의 다형성
- 하나의 객체가 여러 개의 타입을 가질 수 있는 것을
다형성
이라 함
- 다형성을 나타내는 예제
package Standard_Java;
class Tv{
boolean power;
int channel;
// True or False
void power(){ power = !power; }
void channelUp(){ channel++; }
void channelDown() { channel--; }
}
// 자바는 다중 상속을 지원하지 않음 (여러 개의 클래스를 상속받을 수 없음)
class CaptionTv extends Tv{
// 자식 클래스에서 새로 추가된 속성
String text;
void caption(){ }
}
class Other{
}
// java 파일 하나당 하나의 public 클래스 가질 수 있음
public class PolymorphismTest {
public static void main(String[] args) {
// is-a 관계. 즉, 상속 관계에서만 사용 가능
// CaptrionTv is Tv
Tv t1 = new Tv();
Tv t2 = new CaptionTv();
// 상속되지 않은 Other을 사용하면 오류가 나는 것 확인 가능
// 참조변수와 객체의 타입이 다르면 안됨
// Tv t3 = new Other();
CaptionTv c = new CaptionTv();
// Tv는 CaptionTv이다는 성립하지 않음
// 모든 학생은 사람이지만, 모든 사람이 학생일 수는 없다는 의미
// CaptionTv c2 = new Tv();
t2.power();
t2.channelUp();
// Tv 타입의 참조형 변수는 자식 타입의 속성 까지는 알 수 없음
// t2.text;
c.power();
c.channelDown();
c.text = "Unknown";
// Tv 타입만을 원소로 가질 수 있음
Tv[] arrT = new Tv[10];
}
}
추상 클래스
- 추상 메서드를 포함하는 클래스를
추상 클래스
라 함
- 추상 메서드란?
- 메서드의 내부가 정의되지 않은 메서드
- 선언부만 작성하고 구현부는 작성하지 않은 채로 남겨 둔 것
- 완성되지 않은 클래스
- 인스터너스화 할 수 없음
- 객체로 생성될 수 없다는 것을 의미
- 반드시 상속으로 추상 메서드를 메서드 재정의(오버라이딩)를 통해 메서드 내부를 정의해야만 인스턴스화 할 수 있음
package Standard_Java;
abstract class Abstract{
// 선언만 되어있고, 내부의 기능이 정의되지 않은 메서드
abstract void abstractMethod();
// 정의된 메서드가 있어도 무관함
void generalMethod() {
System.out.println("일반 메서드");
}
}
public class AbstractTest {
public static void main(String[] args) {
Abstract obj = new Abstract(); // 인스턴스화 할 수 없다는 오류 발생
}
}
- 추상 클래스 수정 후
- 상속이 계속 이어지더라도, 언젠가는 구현이 되어야 한다.
package Standard_Java;
abstract class Abstract{
// 선언만 되어있고, 내부의 기능이 정의되지 않은 메서드
abstract void abstractMethod();
// 정의된 메서드가 있어도 무관함
void generalMethod() {
System.out.println("일반 메서드");
}
}
class General extends Abstract{
// 메서드 재정의(오버라이드) 통해서 완성
void abstractMethod() {
System.out.println("이제는 완성");
}
}
public class AbstractTest {
public static void main(String[] args) {
Abstract obj = new General(); // 인스턴스화 할 수 없다는 오류 발생
}
}
package Standard_Java;
abstract class Abstract{
// 선언만 되어있고, 내부의 기능이 정의되지 않은 메서드
abstract void abstractMethod();
// 정의된 메서드가 있어도 무관함
void generalMethod() {
System.out.println("일반 메서드");
}
}
abstract class General extends Abstract{
}
// 언젠가는 구현되어야 함
class Final extends General{
// 메서드 재정의(오버라이드) 통해서 완성
void abstractMethod() {
System.out.println("이제는 완성");
}
}
public class AbstractTest {
public static void main(String[] args) {
Abstract obj = new Final(); // 인스턴스화 할 수 없다는 오류 발생
}
}
인터페이스
- 추상 클래스의 종류
- 추상 메서드만을 가지는 추상 클래스를
인터페이스
라고 함
- 인터페이스 작성의 형태
- 모든 멤버변수는 public static final 이어야 하며, 생략 가능하다
- 모든 메서드는 public abstract 이어야 하고, 생략 가능하다
- 단, static 메서드와 default 메서드는 예외
interface 인터페이스 이름{
public static final 타입 상쉬름 = 값;
public abstract 메서드이름(매개변수목록);
}
package Standard_Java;
interface Interface{
public abstract void abstractMethod1();
public abstract void abstractMethod2();
public abstract void abstractMethod3();
}
// 인터페이스의 상속은 extends가 아닌, implements로 상속이 됨
// 여러 개의 인터페이스 상속 받아서 구현
// 자바는 다중 상속 허용하지 않지만, 하나의 클래스(일반, 추상) 여러개의 인터페이스는 가능
class Sample implements Interface{
public void abstractMethod3() {};
public void abstractMethod1() {};
public void abstractMethod2() {};
}
public class InterfaceTest {
public static void main(String[] args) {
Sample s = new Sample();
}
}
실습
- 메서드 오버로딩을 통한 다형성 예제 - 2 (동물원)
package Standard_Java;
/*
1. 동물원 클래스 가정
2. 호랑이가 들어오면 닭을 먹이로 주고
3. 원숭이가 들어오면 바나나를 먹이로 주고 ..
*/
// 동물 클래스 정의
class Animal{
String name;
public void setName(String name){
this.name = name;
}
}
// 호랑이 클래스(동물 클래스 상속)
class Tiger extends Animal{
}
// 원숭이 클래스(동물 클래스 상속)
class Monkey extends Animal{
}
// 동물원 클래스 정의
class Zoo{
// 메서드 오버로딩
// 호랑이가 들어오면 닭, 원숭이가 들어오면 바나나
public void food(Tiger tiger) {
System.out.println("닭");
}
public void food(Monkey monkey){
System.out.println("바나나");
}
}
public class ZooProject {
public static void main(String[] args) {
Zoo zoo = new Zoo();
Tiger tiger = new Tiger();
Monkey monkey = new Monkey();
zoo.food(tiger);
zoo.food(monkey);
}
}
package Standard_Java;
/*
1. 동물원 클래스 가정
2. 호랑이가 들어오면 닭을 먹이로 주고
3. 원숭이가 들어오면 바나나를 먹이로 주고 ..
*/
// 동물 클래스 정의
class Animal{
String name;
public void setName(String name){
this.name = name;
}
}
// 동물이 계속 추가된다면??
interface Ground{
}
interface Birds {
// 날지 못하는 새 처리 위함
public String getAction();
}
// 호랑이 클래스(동물 클래스 상속)
class Tiger extends Animal implements Ground{
}
// 원숭이 클래스(동물 클래스 상속)
class Monkey extends Animal implements Ground{
}
class Lion extends Animal implements Ground{
}
class Eagle extends Animal implements Birds{
@Override
public String getAction() {
return "Fly";
}
}
class Duck extends Animal implements Birds{
@Override
public String getAction() {
return "Fly";
}
}
class Penguin extends Animal implements Birds{
@Override
public String getAction() {
return "Walk";
}
}
// 동물원 클래스 정의
class Zoo{
public void action(Ground ground){
System.out.println("Walk");
}
public void action(Birds bird){
System.out.println(bird.getAction());
}
public void food(Animal animal){
// 동물에 따라 먹이 다르게 표현
if(animal instanceof Tiger) System.out.println("닭");
else if(animal instanceof Monkey) System.out.println("바나나");
else if(animal instanceof Lion) System.out.println("소고기");
else if(animal instanceof Eagle) System.out.println("다람쥐");
}
}
public class ZooProject {
public static void main(String[] args) {
Zoo zoo = new Zoo();
Tiger tiger = new Tiger();
Monkey monkey = new Monkey();
Lion lion = new Lion();
Eagle eagle = new Eagle();
Duck duck = new Duck();
Penguin penguin = new Penguin();
zoo.action(tiger);
zoo.action(monkey);
zoo.action(lion);
zoo.action(eagle);
zoo.action(duck);
zoo.action(penguin);
zoo.food(tiger);
zoo.food(monkey);
}
}
package Standard_Java;
/*
1. 동물원 클래스 가정
2. 호랑이가 들어오면 닭을 먹이로 주고
3. 원숭이가 들어오면 바나나를 먹이로 주고 ..
*/
// 동물 클래스 정의
class Animal{
String name;
public void setName(String name){
this.name = name;
}
}
// 동물이 계속 추가된다면??
interface Ground{
}
interface Birds {
// 날지 못하는 새 처리 위함
public String getAction();
}
interface Foodable{
public void food();
}
// 호랑이 클래스(동물 클래스 상속)
class Tiger extends Animal implements Ground, Foodable{
public void food() {
System.out.println("닭");
}
}
// 원숭이 클래스(동물 클래스 상속)
class Monkey extends Animal implements Ground, Foodable{
public void food() {
System.out.println("바나나");
}
}
class Lion extends Animal implements Ground, Foodable{
public void food() {
System.out.println("소고기");
}
}
class Eagle extends Animal implements Birds, Foodable{
@Override
public String getAction() {
return "Fly";
}
public void food() {
System.out.println("다람쥐");
}
}
class Duck extends Animal implements Birds, Foodable{
@Override
public String getAction() {
return "Fly";
}
public void food() {
System.out.println("사료");
}
}
class Penguin extends Animal implements Birds{
@Override
public String getAction() {
return "Walk";
}
public void food(){
System.out.println("물고기");
}
}
// 동물원 클래스 정의
class Zoo{
public void action(Ground ground){
System.out.println("Walk");
}
public void action(Birds bird){
System.out.println(bird.getAction());
}
public void food(Foodable animal){
animal.food();
}
}
public class ZooProject {
public static void main(String[] args) {
Zoo zoo = new Zoo();
Tiger tiger = new Tiger();
Monkey monkey = new Monkey();
Lion lion = new Lion();
Eagle eagle = new Eagle();
Duck duck = new Duck();
Penguin penguin = new Penguin();
zoo.action(tiger);
zoo.action(monkey);
zoo.action(lion);
zoo.action(eagle);
zoo.action(duck);
zoo.action(penguin);
zoo.food(tiger);
zoo.food(monkey);
}
}
package Standard_Java;
/*
1. 동물원 클래스 가정
2. 호랑이가 들어오면 닭을 먹이로 주고
3. 원숭이가 들어오면 바나나를 먹이로 주고 ..
*/
// 동물 클래스 정의
class Animal{
String name;
public void setName(String name){
this.name = name;
}
}
// 동물이 계속 추가된다면??
interface Ground{
}
//interface Birds {
// // 날지 못하는 새 처리 위함
// public String getAction();
//}
abstract class Birds extends Animal{
public abstract String getAction();
public void getName() {
System.out.printf("너의 이름은 %s\n", this.name);
}
}
interface Foodable{
public void food();
}
interface GroundFoodable extends Ground, Foodable{
}
// 호랑이 클래스(동물 클래스 상속)
class Tiger extends Animal implements GroundFoodable{
public void food() {
System.out.println("닭");
}
}
// 원숭이 클래스(동물 클래스 상속)
class Monkey extends Animal implements GroundFoodable{
public void food() {
System.out.println("바나나");
}
}
class Lion extends Animal implements GroundFoodable{
public void food() {
System.out.println("소고기");
}
}
class Eagle extends Birds implements Foodable{
Eagle() { this.name = "독수리"; }
@Override
public String getAction() {
return "Fly";
}
public void food() {
System.out.println("다람쥐");
}
}
class Duck extends Birds implements Foodable{
Duck() { this.name = "오리"; }
@Override
public String getAction() {
return "Fly";
}
public void food() {
System.out.println("사료");
}
}
class Penguin extends Birds implements Foodable{
Penguin() { this.name = "펭귄"; }
@Override
public String getAction() {
return "Walk";
}
public void food(){
System.out.println("물고기");
}
}
// 동물원 클래스 정의
class Zoo{
public void action(Ground ground){
System.out.println("Walk");
}
public void action(Birds bird){
System.out.println(bird.getAction());
bird.getName();
}
public void food(Foodable animal){
animal.food();
}
}
public class ZooProject {
public static void main(String[] args) {
Zoo zoo = new Zoo();
Tiger tiger = new Tiger();
Monkey monkey = new Monkey();
Lion lion = new Lion();
Eagle eagle = new Eagle();
Duck duck = new Duck();
Penguin penguin = new Penguin();
zoo.action(tiger);
zoo.action(monkey);
zoo.action(lion);
zoo.action(eagle);
zoo.action(duck);
zoo.action(penguin);
zoo.food(tiger);
zoo.food(monkey);
}
}