JAVA

221012 다형성

주영재 2022. 10. 12. 12:43

 

다형성
다형성이란 객체가 여러 형태를 가진다는 뜻. 하나의 객체가 여라가지 유형으로 사용됨을 의미
->다형성은 클래스의 형변환 의미

다형성은 상속을 전제조건으로 한다.

자식클래스가 부모클래스에 저장될 수 있다.
Person 부모, Student 자식


Student s = new student();
Person p = s;

가 가능하다. 부모가 더 크니까.

 

한번에 적으면
->Person p=new Student();

이는 int i=1///double d=i의 형식과 같은 것.


★★★이때, 
부모클래스에 있는 기능만 사용할 수 있지만,
(부모처럼 실행되지만)
오버라이딩 된 메서드는 먼저 실행된다.
(오버라이딩된건 student께 실행된다.)

왜 이렇게 하는가? 객체들의 타입을 하나로 통일하기 위해.

 

 

package day08.poly.basic;

//하나의 클래스 파일에 여러 클래스 선언이 가능합니다.
//단, 파일명과 동일한 클래스가 public이어야 합니다.
//자바는 1클래스 파일에 1클래스가 원칙. 여기서는 그냥 예시를 보기 위해.
class A{}
class B extends A{}
class C extends A{}
class D extends B{}
class E extends C{}



public class Basic {//사용자클래스
	//다형성(클래스형변환) - 자식의 주소가 부모에 저장되는 성질
	//멤버변수
	A a = new B();//A가 더 크기때문에 가능
	A a1 = new C();
	A a2 = new D();
	A a3 = new E();
	
	//다형성은 상속을 전제로 합니다.
	//B b = new C();--불가능
	
	//Object형에는 모든 클래스를 저장할 수 있습니다.
	Object obj=1;
	Object obj2=3.14;
	Object obj3="문자열";
	Object obj4=new A();
	//Object형으로 자동형변환. 따라서 필요할 때만 저장한다.
	
	
}

A, B, C, D중 A가 가장 큰 부모고, A에 B와 C가 상속되어 있고, D가 B에, E가 C에 상속되어 있다.

때문에 A a = new B();나 A a=new C();가 가능한 것.

또한, 상속관계에 맞지 않기 때문에 B b=new C();가 불가능한 것이다.

 

+)물론 모든 클래스는 Object 클래스를 상속하고 있기에 Object형에 모든 클래스를 저장할 수 있다.

그러나 Object형으로 자동형변환이 일어나기 때문에 필요할 때만 저장한다.

 

 

부모클래스

package day08.poly.basic;

public class Parents {
	
	public void method01() {
	System.out.println("부모의 1번 메서드");	
	}
	
	public void method02() {
	System.out.println("부모의 2번 메서드");
	}

}

자식클래스

package day08.poly.basic;

public class Child extends Parents{

	//오버라이딩 단축키 alt+shit+s
	@Override
	public void method02() {
		System.out.println("오버라이딩 된 2번 메서드");
	}
	
	public void method03() {
		System.out.println("자식의 3번 메서드");
	}

	//1번메서드-상속받음 2번메서드-오버라이딩 3번메서드-자신꺼
	//Child는 이렇게 3개 사용 가능
	
	
}

자식이 부모를 상속받았으므로 부모클래스의 메서드를 가져와 오버라이딩할수가 있다. 

 

 

+)오버라이딩 단축키-  alt + shift + s

 

main

package day08.poly.basic;

public class MainClass {
	public static void main(String[] args) {
		
	Child c = new Child();
	c.method01();//상속
	c.method02();//오버라이드
	c.method03();//내꺼
	
	System.out.println("----다형성----");
	//자식이 부모에 저장되는데, 부모처럼 사용되나 단, 자식의 오버라이딩된 메서드가 실행됩니다.
	Parents p = c;//Parent p = new Child();
	p.method01();
	p.method02();//오버라이드된 메서드 실행
	//p.method03();--불가능
	
	System.out.println(p==c);//true. 다형성은 잠깐 형변환된 것 뿐. 동일한 주소값을 나타냄
	
	System.out.println("----클래스 캐스팅----");
	//다형성이 적용되면, 자식이 가지고 있던 본래의 기능을 사용할 수 없기 때문에, 클래스캐스팅을 사용합니다
	
	Child cc=(Child)p;
	cc.method01();
	cc.method02();
	cc.method03();
	
	System.out.println("----주의할 점----");
	//다형성이 적용된 객체만 캐스팅이 가능합니다.
	Parents pp = new Parents();
	Child ccc=(Child)pp;//에러. ClassCastExeption. 클래스 캐스팅 에러

	}
}
부모의 1번 메서드
오버라이딩 된 2번 메서드
자식의 3번 메서드
----다형성----
부모의 1번 메서드
오버라이딩 된 2번 메서드
true
----클래스 캐스팅----
부모의 1번 메서드
오버라이딩 된 2번 메서드
자식의 3번 메서드
----주의할 점----
Exception in thread "main" java.lang.ClassCastException: class day08.poly.basic.Parents cannot be cast to class day08.poly.basic.Child (day08.poly.basic.Parents and day08.poly.basic.Child are in unnamed module of loader 'app')
	at day08.poly.basic.MainClass.main(MainClass.java:31)

자식객체를 생성하면 부모와 자식의 메서드를 모두 사용할 수 있는데. 메서드2번은 오버라이딩된 메서드가 실행된다.

부모에 자식객체를 저장하고 실행하면 저장된 부모처럼 사용되는데, 메서드는 오버라이딩된 메서드가 실행된다.

Parents p = c;는

Parents p=new child();와 같고, 이는

 

Child c = new Child();
Person p = c;

와 같다. 아래에서 위로 줄여진 것.

 

p==c가 true인 이유는 다형성이 잠깐 형변화한 것일 뿐, 동일한 주소값을 나타내기 때문이다.

다형성을 통해 부모에 자식을 저장하고 실행했을 때 부모의 메서드만 사용되지만, 메서드를 사용할 때만 잠깐 형변화한 것이고 Parents p = c;기 떄문에 둘은 같은 주소값을 나타낸다. 

 

 

 

 

 

 

강제 타입 변환
반대도 가능. 부모 타입을 자식 타입으로 변환이 가능
대신, 형변환이 일어났던 객체만 가능
Parent p = new Child();-원본이 child
p를 깎는 건 가능하다
Child c =(Child)p; 

Object o=new object()
Parent t = o;는 불가능. object는 parent 기능을 갖고 있지 않기 때문에

System.out.println("----클래스 캐스팅----");
	//다형성이 적용되면, 자식이 가지고 있던 본래의 기능을 사용할 수 없기 때문에, 클래스캐스팅을 사용합니다
	
	Child cc=(Child)p;
	cc.method01();
	cc.method02();
	cc.method03();
	
	System.out.println("----주의할 점----");
	//다형성이 적용된 객체만 캐스팅이 가능합니다.
	Parents pp = new Parents();
	Child ccc=(Child)pp;//에러. ClassCastExeption. 클래스 캐스팅 에러
----클래스 캐스팅----
부모의 1번 메서드
오버라이딩 된 2번 메서드
자식의 3번 메서드
----주의할 점----
Exception in thread "main" java.lang.ClassCastException: class day08.poly.basic.Parents cannot be cast to class day08.poly.basic.Child (day08.poly.basic.Parents and day08.poly.basic.Child are in unnamed module of loader 'app')
	at day08.poly.basic.MainClass.main(MainClass.java:31)

cc는 부모인 p를 저장했다. 이처럼 부모 타입을 자식 타입으로 변환하는 것도 가능

단, 형변환이 일어났던 객체만 가능하다. 위에서 Parents p = c;로 형변환을 했었기 때문에 반대가 가능한 것. 

cc는 p를 저장했으므로 부모의 메서드와 자식의 메서드를 모두 사용할 수 있다.

 

다형성이 적용되지 않은 객체는 형변환을 할 수 없다. ccc는 다형성을 적용하지 않았고, 때문에

ClassCastExeption-클래스 캐스팅 에러가 뜨는 것이다.