Java

다형성

이번 시간에는 다형성(Polymorphism)이라는 주제에 대해서 알아보자. 다형성이란 하나의 메소드나 클래스가 있을 때 이것들이 다양한 방법으로 동작하는 것을 의미한다. 키보드의 키를 통해서 비유를 들어보겠다. 키보드의 키를 사용하는 방법은 '누른다'이다. 하지만 똑같은 동작 방법의 키라고 하더라도 ESC는 취소를 ENTER는 실행의 목적을 가지고 있다. 다형성이란 동일한 조작방법으로 동작시키지만 동작방법은 다른 것을 의미한다.

다형성은 객체나 인터페이스 또는 추상과 같이 철학적인 느낌을 자아내는 용어이다. 그래서 이 주제 또한 철학적이고 현학적인 느낌으로 여러분을 혼란스럽게 할 수 있으나 그것은 학습에 도움이 되지 않는다. 다형성이라는 것이 코드 상에서는 구체적으로 어떤 모습으로 드러나는지에 집중하자. 우선 코드를 보자.

overloading과 다형성

참고로 overloading이 다형성인지 아닌지에 대해서는 이견이 존재하는 것으로 보인다. 

오버로딩은 가장 이해하기 쉬운 다형성의 예라고 할 수 있다. 아래의 코드를 보자.

package org.opentutorials.javatutorials.polymorphism;
class O{
    public void a(int param){
		System.out.println("숫자출력");
		System.out.println(param);
	}
	public void a(String param){
		System.out.println("문자출력");
		System.out.println(param);
	}
}
public class PolymorphismOverloadingDemo {
	public static void main(String[] args) {
		O o = new O();
		o.a(1);;
		o.a("one");
	}
}

클래스 O의 메소드 a는 두개의 본체를 가지고 있다. 동시에 두개의 본체는 하나의 이름인 a를 공유하고 있다. 같은 이름이지만 서로 다른 동작 방법을 가지고 있기 때문에 오버로딩은 다형성의 한 예라고 할 수 있다.

클래스와 다형성

package org.opentutorials.javatutorials.polymorphism;
class A{}
class B extends A{}
public class PolymorphismDemo1 {
    public static void main(String[] args) {
		A obj = new B();
	}
}

이상하게 보이겠지만 클래스 B의 데이터 형이 클래스 A이다. 클래스 B는 클래스 A를 상속하고 있다. 이런 경우에 클래스 B는 클래스 A를 데이터 형으로 삼을 수 있다. 그럼 이렇게 하는 이유가 무엇인가 궁금해 질 것이다. 위의 코드를 변경한 아래의 코드를 보자.

package org.opentutorials.javatutorials.polymorphism;
class A{
    public String x(){return "x";}
}
class B extends A{
	public String y(){return "y";}
}
public class PolymorphismDemo1 {
	public static void main(String[] args) {
		A obj = new B();
		obj.x();
		obj.y();
	}
}

차이점은 아래와 같다.

아래 코드는 실행이 된다.

obj.x();

하지만 아래 코드는 실행되지 않는다.

obj.y();

클래스 B는 메소드 y를 가지고 있다. 그럼에도 불구하고 메소드 y가 마치 존재하지 않는 것처럼 실행되지 않고 있다. 10행의 코드를 아래와 같이 변경해보자.

B obj = new B();

그럼 아래 코드가 실행될 것이다.

obj.y();

즉 클래스 B의 데이터 형을 클래스 A로 하면 클래스 B는 마치 클래스 A인것처럼 동작하게 되는 것이다. 클래스 B를 사용하는 입장에서는 클래스 B를 클래스 A인것처럼 사용하면 된다. 여전히 왜 이런 기능이 있는지 의구심이 풀리지 않을 것이다. 아래 코드를 보자.

package org.opentutorials.javatutorials.polymorphism;
class A{
    public String x(){return "A.x";}
}
class B extends A{
	public String x(){return "B.x";}
	public String y(){return "y";}
}
public class PolymorphismDemo1 {
	public static void main(String[] args) {
		A obj = new B();
		System.out.println(obj.x());
	}
}

차이점은 아래와 같다.

클래스 A의 메소드 x를 클래스 B에서 오버라이딩하고 있다. 실행 결과는 아래와 같다.

B.x

엄청 헷갈릴 것이다. 찬찬히 따져보자.

  1. 클래스 B의 데이터 타입을 클래스 A로 인스턴스화 했을 때 클래스 B의 메소드 y는 마치 존재하지 않는 것처럼 실행되지 않았다. => 클래스 B가 클래스 A화 되었다.
  2. 클래스 B의 데이터 타입을 클래스 A로해서 인스턴스화 했을 때 클래스 B의 메소드 x를 실행하면 클래스 A에서 정의된 메소드가 아니라 클래스 B에서 정의된 메소드가 실행 되었다. => 클래스 B의 기본적인 성질은 그대로 간직하고 있다.

정리해보면 아래와 같다.

클래스 B를 클래스 A의 데이터 타입으로 인스턴스화 했을 때 클래스 A에 존재하는 맴버만이 클래스 B의 맴버가 된다. 동시에 클래스 B에서 오버라이딩한 맴버의 동작방식은 그대로 유지한다. 아래의 코드를 보자.

package org.opentutorials.javatutorials.polymorphism;
class A{
    public String x(){return "A.x";}
}
class B extends A{
	public String x(){return "B.x";}
	public String y(){return "y";}
}
class B2 extends A{
	public String x(){return "B2.x";}
}
public class PolymorphismDemo1 {
	public static void main(String[] args) {
		A obj = new B();
		A obj2 = new B2();
		System.out.println(obj.x());
		System.out.println(obj2.x());
	}
}

차이점은 아래와 같다.

실행결과는 아래와 같다.

B.x
B2.x

아래의 코드는 서로 다른 클래스 B와 B2가 동일한 데이터 타입 A로 인스턴스화 되었다.

A obj = new B();
A obj2 = new B2();

하지만 두 인스턴스의 메소드 x를 호출한 결과는 서로 다르다.

이것이 상속과 오버라이딩 그리고 형변환을 이용한 다형성이다.

하위 클래스를 상위 클래스의 데이터 타입으로 인스턴스화 했을 때 어떤 일이 일어나는지에 대해서는 어느정도 이해했을꺼라고 생각한다. 하지만 가장 큰 틀의 질문은 이걸 어디에 사용하는가?일것이다. 정당한 질문이다. abstract 수업의 예제 코드를 조금 변경해보자.

package org.opentutorials.javatutorials.polymorphism;
abstract class Calculator{
    int left, right;
    public void setOprands(int left, int right){
        this.left = left;
        this.right = right;
    } 
    int _sum() {
        return this.left + this.right;
    }
    public abstract void sum();  
    public abstract void avg();
    public void run(){
    	sum();
    	avg();
    }
}
class CalculatorDecoPlus extends Calculator {
	public void sum(){
		System.out.println("+ sum :"+_sum());
	}
	public void avg(){
		System.out.println("+ avg :"+(this.left+this.right)/2);
	}
} 
class CalculatorDecoMinus extends Calculator {
	public void sum(){
		System.out.println("- sum :"+_sum());
	}
	public void avg(){
		System.out.println("- avg :"+(this.left+this.right)/2);
	}
} 
public class CalculatorDemo {
    public static void main(String[] args) { 
    	Calculator c1 = new CalculatorDecoPlus();
        c1.setOprands(10, 20);
        c1.run();
        
        Calculator c2 = new CalculatorDecoMinus();
        c2.setOprands(10, 20);
        c2.run();
    }
  
}

차이점은 아래와 같다. 아래는 예전 코드다.

아래는 변경된 코드의 내용이다.

차이점은 Calculator를 상속 받은 클래스들을 인스턴스화 할 때 Calculator를 데이터 타입으로 하고 있다. 이렇게 되면 인스턴스 c1과 c2를 사용하는 입장에서 두개의 클래스 모두 Calculator인 것처럼 사용할 수 있다. 예제를 조금 수정해보자.

package org.opentutorials.javatutorials.polymorphism;
abstract class Calculator{
    int left, right;
    public void setOprands(int left, int right){
        this.left = left;
        this.right = right;
    } 
    int _sum() {
        return this.left + this.right;
    }
    public abstract void sum();  
    public abstract void avg();
    public void run(){
    	sum();
    	avg();
    }
}
class CalculatorDecoPlus extends Calculator {
	public void sum(){
		System.out.println("+ sum :"+_sum());
	}
	public void avg(){
		System.out.println("+ avg :"+(this.left+this.right)/2);
	}
} 
class CalculatorDecoMinus extends Calculator {
	public void sum(){
		System.out.println("- sum :"+_sum());
	}
	public void avg(){
		System.out.println("- avg :"+(this.left+this.right)/2);
	}
} 
public class CalculatorDemo {
	public static void execute(Calculator cal){
		System.out.println("실행결과");
		cal.run();
	}
    public static void main(String[] args) { 
    	Calculator c1 = new CalculatorDecoPlus();
        c1.setOprands(10, 20);
        
        Calculator c2 = new CalculatorDecoMinus();
        c2.setOprands(10, 20);
        
        execute(c1);
        execute(c2);
    }
}

차이점은 아래와 같다.

클래스 CalculatorDemo의 execute 메소드는 CalculatorDecoPlus와 CalculatorDecoMinus 클래스의 메소드 run을 호출하면서 그것이 '실행결과'라는 사실을 화면에 표시하는 기능을 가지고 있다. 이 때 메소드 execute 내부에서는 매개변수로 전달된 객체의 메소드 run을 호출하고 있다.

만약 메소드 execute의 매개변수 데이터 타입이 Calculator가 아니라면 어떻게 해야할까? 위와 같은 로직을 처리 할 수 없을 것이다. 메소드 execute 입장에서는 매개변수로 전달된 값이 Calculator이거나 그 자식이라면 메소드 run을 가지고 있다는 것을 보장 받을 수 있게 되는 것이다.

이 맥락에서의 다형성이란 하나의 클래스(Calculator)가 다양한 동작 방법(ClaculatorDecoPlus, ClaculatorDecoMinus)을 가지고 있는데 이것을 다형성이라고 할 수 있겠다. 

인터페이스와 다형성

위의 예제는 클래스의 상속 관계를 통해서 다형성을 설명하고 있는데, 다형성의 세계에서는 인터페이스도 중요한 수단이다. 인터페이스 수업에서는 언급하지 않은 것이 있다. 특정한 인터페이스를 구현하고 있는 클래스가 있을 때 이 클래스의 데이터 타입으로 인터페이스를 지정 할 수 있다. 말이 어렵다면 코드를 통해서 무슨 말인지 알아보자.

package org.opentutorials.javatutorials.polymorphism;
interface I{}
class C implements I{}
public class PolymorphismDemo2 {
    public static void main(String[] args) {
		I obj = new C();
	}
}

위의 코드를 통해서 알 수 있는 것은 클래스 C의 데이터 타입으로 인터페이스 I가 될 수 있다는 점이다. 이것은 다중 상속이 지원되는 인터페이스의 특징과 결합해서 상속과는 다른 양상의 효과를 만들어낸다. 아래 코드를 보자.

package org.opentutorials.javatutorials.polymorphism;
interface I2{
    public String A();
}
interface I3{
	public String B();
}
class D implements I2, I3{
	public String A(){
		return "A";
	}
	public String B(){
		return "B";
	}
}
public class PolymorphismDemo3 {
	public static void main(String[] args) {
		D obj = new D();
		I2 objI2 = new D();
		I3 objI3 = new D();
		
		obj.A();
		obj.B();
		
		objI2.A();
		//objI2.B();
		
		//objI3.A();
		objI3.B();
	}
}

주석처리된 메소드 호출은 오류가 발생하는 것들이다. objI2.b()에서 오류가 발생하는 이유는 objI2의 데이터 타입이 인터페이스 I이기 때문이다. 인터페이스 I는 메소드 A만을 정의하고 있고 I를 데이터 타입으로 하는 인스턴스는 마치 메소드 A만을 가지고 있는 것처럼 동작하기 때문이다.

이것은 인터페이스의 매우 중요한 특징 중의 하나를 보여준다. 인스턴스 objI2의 데이터 타입을 I2로 한다는 것은 인스턴스를 외부에서 제어할 수 있는 조작 장치를 인스턴스 I2의 맴버로 제한한다는 의미가 된다. 인스턴스 I2와 I3로 인해서 하나의 클래스가 다양한 형태를 띄게 되는 것이다.

비유

필자가 이해를 돕기 위해서 비유를 시도해보겠다. 누차 강조 하지만 비유는 비유일 뿐이다. 비유는 여러분의 머리속을 더욱 복잡하게 할 수 있다.

사람은 다면적인 존재다. Steve라는 사람이 있다. 이 사람은 집에서는 아버지이고 직업적으로는 프로그래머이고 또 종교단체 내에서는 신도(believer)가 될 수 있다. 하나의 사람이지만 그가 어디에 있는가? 누구와 관계하는가에 따라서 아버지이면서 프로그래머이고 또 신도인 것이다.

Rachel는 집에서는 엄마고 직장에서는 프로그래머다.

Steve와 Rachel이 같은 직장(Workspace)에 다니고 있다고 한다면 직장 입장에서는 두사람이 프로그래머라는 점이 중요할 뿐 이들의 가족관계나 종교성향에는 관심이 없다. 직장 입장에서 두사람은 프로그래머이고 프로그래머는 코딩을 통해서 무엇인가를 창조하는 사람들이다. 따라서 이들에게 업무를 요청할 때는 코딩을 요청하면 된다. 하지만 두 사람의 실력이나 성향에 따라서 코딩의 결과물은 달라질 것이다. 이러한 관계를 굳이 코드로 만들면 아래와 같다.

package org.opentutorials.javatutorials.polymorphism;

interface father{}
interface mother{}
interface programmer{
    public void coding();
}
interface believer{}
class Steve implements father, programmer, believer{
    public void coding(){
        System.out.println("fast");
    }
}
class Rachel implements mother, programmer{
    public void coding(){
        System.out.println("elegance");
    }
}
public class Workspace{
    public static void main(String[] args){
    	programmer employee1 = new Steve();
		programmer employee2 = new Rachel();
		
		employee1.coding();
		employee2.coding();
    }
}

위의 코드를 보면 알겠지만 Steve와 Rachel의 사용자인 직장에서는 Steve와 Rachel의 인터페이스인 programmer를 통해서 두사람과 관계하게 된다. 두 사람이 어떤 종교나 가족관계를 가졌건 인터페이스 programmer을 가지고 있다면 고용할 수 있다. 회사에서는 코딩을 할 수 있는 사람이 필요하고 어떤 사람이 programmer라는 인터페이스를 구현하고 있다면 그 사람은 반드시 coding이라는 메소드를 구현하고 있을 것이기 때문이다. 또 두 사람에게 업무를 요청 할 때는 programmer라는 인터페이스의 메소드인 coding을 통해서 요청하면 된다. 하지만 두 사람의 성향이나 능력에 따라서 그 업무를 수행한 결과는 다른데 Steve는 빠르게 코딩하고 Rachel은 우아하게 코딩하고 있다.

참고

  • 본 수업에 대해서 한상곤님께서 조언을 주셨습니다. 

댓글

댓글 본문
작성자
비밀번호
  1. 감사합니다
    현업3년차 개발자입니다.
    다형성 기본이 부족하여 검색하다
    6강의모두봤습니다.
    와..놀랍네요..설명 진짜 이해가기쉽게 잘해주시네요
    샘플강의였다면 정말 유료결재 해서 봤을듯 합니다
    강의가 많던데 낼 부터 퇴근 후 계속보게 될거같아요
    훌륭하십니다 이런 멋진 강의를 무료로 널리 알리시니
    많은 분들 정말 좋아할거같아요
    어딜가도 이런강의는 없을듯합니다.
    너무 감사합니다 잘 배웠습니다.
  2. 자바초보
    위에 execute(Calculator cal)에서 cal은 어디서 오는 것인가요?
    Calculator class에서 오는 건 알겟는데 cal 은 그 클래스에서 정의되어있는 것인가요?
    아니면 저 () 안에서 정의되는 것인가요?
  3. 조환희
    깔끔한 설명 너무 감사드립니다!!
  4. 수리
    다형성이 맨날 헷갈렸는데 완전 명쾌한 설명 감사드립니다!
  5. Daniel Heo
    잘봤습니다!!
  6. //인터페이스 : 한사람으로서 가지고 있는 속성들
    interface father{}
    interface mother{}
    interface programmer{
    public void coding();
    }
    interface believer{}

    //클래스 : 스티브라는 사람을 클래스로 정의하고 인터페이스로 스티브의 속성을 구현한다.
    class Steve implements father, programmer, believer{ //스티브의 고유속성을 인터페이스를 통해서 구현한다.
    public void coding(){
    System.out.println("fast");
    }
    }

    //클래스 : 레이첼이라는 사람을 클래스로 정의하고 인터페이스로 레이첼의 속성을 구현한다.
    class Rachel implements mother, programmer{ //레이첼의 고유속성을 인터페이스를 통해서 구현한다.
    public void coding(){
    System.out.println("elegance");
    }
    }
    //클래스 : 직장이라는 객체지향의 개념으로서 클래스를 생성한다.
    public class Workspace{
    public static void main(String[] args){
    programmer employee1 = new Steve(); //스티브의 직장에서의 역활(프로그래머)을 인스턴스화 한다.
    programmer employee2 = new Rachel(); //레이첼의 직장에서의 역활(프로그래머)을 인스턴스화 한다.

    employee1.coding(); //직장에서만 필요한 스티브만의 고유 속성(코딩)을 사용(fast)한다.
    employee2.coding(); //직장에서만 필요한 레이첼만의 고유 속성(코딩)을 사용(elegance)한다.
    }
    }

    2번째 복습하면서 한번 정리해봤어요.
    틀린점 있으면 누구라도 수정해주시면 좋겠어요^^
  7. 김지선
    감사합니다 이고잉님
    이고잉님같은분이계셔서 정말다행이고 영광입니다 ㅠㅠ
    언젠가 이고잉님과 함께 일하고싶습니다!!
    ㅎㅎ 그때까지 열심히 배우겠습니다
  8. 구녹수수
    마지막 강의 비유에 무릎을 탁 치고갑니다...! 진짜 아..!! 라는 감탄이 절로 나왔습니다!
  9. 근데 CalculatorDecoMinus나 CalculatorDecoPlus나 어차피 Calculator를 조상으로 가지고있으니까
    공통의 조상을 파라미터의 자료형을 해도 아무문제없지않나요??? 저렇게 참조변수의 자료형을 Calculator로 바꿀 필요 없지않나요?
  10. 다형성이라는 수업은 다른 수업들의 비해서 오히려 좀 편하게 볼 수 있었던 것 같습니다.
    비전공자로서 아무런 배경지식이 없었기 때문인지 몰라도 오히려 자바 강의 초반이
    새로운 개념들을 하나씩 익혀나가는 과정이다 보니 더 힘들지 않았나 싶습니다.

    제가 느끼는 다형성은 새로운 개념이나 기능을 배운다는 느낌 보다는
    이미 앞에서 배운 자바라는 언어의 특성과 이고잉님이 말씀하신 공학의 관한 법칙들
    이 하나의 체계화된 규칙속에서 자바가 가진 객체지향이라는 특성을 좀 더 잘 활용하는
    방법을 배우는 느낌 같았습니다.

    즐거웠습니다.^^
  11. 비유 최곱니다 ㅋㅋㅋㅋ
  12. 짱짱짱
    마지막에 비유 정말 감사합니다.
    다형성 드디어 이해하네요
  13. happydeveloper
    다형성을 잘 쓰면 IF / ELSE 문을 많이 줄일 수 있다고 해서 다시 공부하려고요~
  14. 자바 입문러
    마지막 강의에서 나오는 소스 중 father mother 인터페이스 부분 중 아이와 놀아주기 메소드 등을 넣어서 직장에서는 father mother 역할을 하지 못한다는 비유를 하면 사람들이 좀 더 쉽게 이해할 수 있지 않을까싶네요
  15. java basic
    마지막 비유 소름 돋았습니다. 너무 잘 가르치셔서..
  16. circlestar
    잘들었습니다 좋은 강의 입니다 .
  17. supersonic
    마지막 강의가 오히려 앞쪽에서 소개되면 인터페이스 이해가 더 쉬울것 같습니다.
  18. Weaver
    마지막 비유도 이해에 도움이 되었습니다 감사합니다~
  19. joo0914krs
    감사합니다
  20. 다형성 혼자 공부하다가, 애매하여 강의 들으러 왔습니다. 역시나 좋군요. 많은 도움되었습니다. 감사합니다.
  21. JustStudy
    고맙습니다
  22. 임해
    댓글로 횟수 기록해둠 : 느낌
    2번 : 처음 들을 때는 뭔가 뭔지 모르고 들어서 의미하는 바를 몰랐다면 2번째 들을 때는 다형성이라는 개념이 너무 막혀서 들으러 온 것이라 뭔가 감을 잡고 가는 느낌입니다. 마지막 비유는 저에게도 와닿네요.
    3번 : 3번을 보고 딱 다형성을 받아만 들입니다. 여전히 왜 사용하는 지는 모르겠지만...
  23. JSPARK
    저도 마지막 비유에서 감동을 느끼네요~
  24. choyuichan
    마지막 비유가 정말 좋네요! 감사합니다^^
  25. 김트라슈
    좋은 강의 감사합니다
  26. somnium
    감사합니다~~
  27. 감사합니다 ~ ~ ^ ^
  28. 오빠는다르다
    감사합니다!!!!!!!!!!!
  29. 닉슨
    진짜 설명 잘하시는 듯 마지막 비유는 참 좋네요 저는ㅎㅎ
  30. 박첩구드
    감사합니다. 점점 어려워지네요 ㅠㅠ
  31. Lawliet
    와 마지막 6번째 동영상 보면서 중간중간 이해가 힘들거나 빵꾸가 났던 개념들이
    완전히 퍼펙트하게 이해됐습니다.

    물론 실력을 늘리기 위해서는 스스로 코딩도 해보고 시행착오도 겪어보는 과정이 필요하겠지만,
    그에 앞서서 이렇게 이해하기 쉽게 좋은 강의 해주셔서 감사합니다.
    열번이고 스무번이고 두고두고 방문해서 영상 계속 볼 계획입니다.
    다시한 번 감사드립니다.
  32. 슈슈
    와..한 번에 이해된 것 같습니다.ㅠㅠ 좋은 강의 너무 감사합니다
    이고잉님은 진짜 복잡한 것을 단순하게 하는 능력이 탁월한 것 같아요!!
  33. 윤재
    Interface에 대한 비유는 정말 탁월한 것 같습니다.
    이것 때문에 Interface와 다형성에 대해서 더 잘 이해 한 것 같습니다.

    객체 쪽으로 넘어오면서 프로그래밍이 단순히 문법을 외우는 것보다는
    설계를 하는 것이 더 중요하다는 것을 알게 되었네요
  34. 김천원
    이 페이지 전체가 이해가 안갔는데 몇번이고 읽어보고 다른 예제들도 찾아서 해보고 또 읽어보고 하니까 조금 알겠네요 ㅎㅎ 이해가 되기 시작해서 정말 신납니다
  35. 와... 이렇게 쉽게 이해할 수 있도록 도움을 주셔서 감사합니다.
  36. Halora
    예시가 너무 귀여워요ㅋㅋ 감사합니다.
  37. cocohodu
    좋은강의 감사합니다
  38. 자바몬
    c1, c2는 변수에염.. 타입을 선언해주는 이유는 calculator를 담을 그릇으루 해주는거구염~
    대화보기
    • kadlrea@hanmail.net
      참조 클래스 메소드를 호출하지 않고 자식클레스에 의해 오버라이딩을 한 함수를 호출한다는거죠?
    • 오현규
      맞아요 뭔가 좀 이상한거 같습니다 저도 ... 똑같이 느끼고 있습니다.
      대화보기
      • Zero_Gravity
        매번 좋은강의 감사합니다
      • moonlight
        비유가 엘레강스 해서 빠르게 이해됩니다.
      • Ben Kim
        다형성 마지막 동영상 강의 비유 너무 멋져요.
        이고잉님 다시 한번 감사합니다.
      • 풍운도장
        쉽게 와닿지 않네요. egoing님 말씀대로 일단 정주행하고 다시 오렵니다.^^
      • Sung Gil Yun
        감사합니다. 처음이라 이해하기 힘들지만. . .
        노력하고 있습니다.^^
      • 감사
        교수님께 4시간동안 수업했던내용을 도저히 이해를 못해서 찾다가 여길 왔는데 강의를 듣다보니 교수님 말씀과 맞물려 30분만에 이해가 되네요. 너무 좋은 명강의에 감사드립니다. 도입부부터 마지막 쉬는겸 하는 비유정리까지 어느하나 아쉬운게 없이 어지간한 유료강의보다 좋은거같습니다.
      • 성현구
        완전히 는 아니지만 뭔가 꽉 막혔던 내용이 조금은 이해가 된거 같습니다! 정말 감사합니다 ㅠㅠ!
      • couldbe
        코드 실행 오류!

        public class Workspace{
        public static void main(String[] args[]){

        에서 배열변수 이름 args에 대괄호 [] 는 없애야 합니다. 코딩실수이신 것 같습니다.

        (그리고 페북 생활코딩 그룹에 가입신청이 한달째 대기 중인데 승인 부탁드려요^^ 아이디: ie-w--- )
      • KeepCalm_
        4/6강의에 다형성의 필요성을 설명하시기 위해 Calculator 예제에서 참조변수 c1 과 c2를 Calculator형 에서

        CalculatorDecoPlus c1 = new CalculatorDecoPlus();

        CalculatorDecoMinus c2 = new CalculatorDecoMinus();

        로 바꾸어서 비교해주셨는데, 위의 경우로 바꾸기만하고 동일한 execute 메서드를 추가하지않고 실행해도

        실행결과에 영향을 미치지 않습니다. 그렇다면 다형성의 필요성을 설명하기위한 예제로는 부적합하지 않을까요?
      • thexl
        비유 지림ㄷ
      버전 관리
      egoing
      현재 버전
      선택 버전
      graphittie 자세히 보기