하나의 메소드나 클래스가 있을 때 이것들이 다양한 방법으로 동작하는 것
overloading과 다형성
class O{
public void a(int param){ // int 형 매개변수
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");
}
}
클래스와 다형성
ex 1)
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(); // 데이터 타입이 A 인 B인스턴스
obj.x(); // 클래스 A에 있으므로 실행가능
obj.y(); // 오류발생
//obj가 클래스 A에 행세를 하고 있으므로 y메소드가 존재하지않는다로 간주
// 데이터 타입은 인스턴스와 동일할 수 있고 부모클래스일 수도 있다
// A인 것 처럼 동작
}
}
ex 2)
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()); //실행 결과 : B.x
// 오버라이딩
}
}
클래스 B를 클래스 A의 데이터 타입으로 인스턴스화 했을 때 클래스 A에 존재하는 맴버만이 클래스 B의 맴버가 된다. 동시에 클래스 B에서 오버라이딩한 맴버의 동작방식은 그대로 유지한다.
ex 3)
상속과 오버라이딩 그리고 형변환을 이용한 다형성
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());
}
}
ex 4)
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){ //Calculator 매개변수
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);
}
}
만약 메소드 execute의 매개변수 데이터 타입이 Calculator가 아니라면 처리가 불가능
이유 : ClaculatorDecoPlus,ClaculatorDecoMinus 둘 중 하나로 하게 된다면 execute(c1) 또는 execute(c2) 둘 중 하나는 오류가 발생하기 때문
하나의 클래스(Calculator)가 다양한 동작 방법(ClaculatorDecoPlus, ClaculatorDecoMinus)을 가지고 있는데 이것을
다형성이라고 한다 !!!!
인터페이스와 다형성
인터페이스를 구현하고 있는 클래스가 있을 때 이 클래스의 데이터 타입으로 인터페이스를 지정 할 수 있다
ex 1)
interface I{}
class C implements I{}
public class PolymorphismDemo2 {
public static void main(String[] args) {
I obj = new C();
// C의 데이터 타입으로 인터페이스 I가 될 수 있다
}
}
다중 상속이 지원되는 인터페이스의 특징과 결합해서 상속과는 다른 양상의 효과
ex 2)
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(); // A
obj.B(); // B
objI2.A(); // A
//objI2.B(); I2에는 B메소드가 없음 에러
//bjI2의 데이터 타입이 인터페이스 I이기 때문이다. 인터페이스 I는 메소드 A만을 정의
//objI3.A(); I3에는 A메소드가 없음 에러
objI3.B(); // B
}
}
인스턴스 objI2의 데이터 타입을 I2로 한다는 것은 인스턴스를 외부에서 제어할 수 있는 조작 장치를 인스턴스 I2의 맴버로 제한한다는 의미가 된다. 인스턴스 I2와 I3로 인해서 하나의 클래스가 다양한 형태를 띄게 되는 것이다.
ex 3)
// Steve : 아빠, 프로그래머, 신도
// Rachel : 엄마, 프로그래머
// 회사 입장에서는 둘다 프로그래머만 본다.
// 회사의 관점
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
}
}