221012 다형성
다형성
다형성이란 객체가 여러 형태를 가진다는 뜻. 하나의 객체가 여라가지 유형으로 사용됨을 의미
->다형성은 클래스의 형변환 의미
다형성은 상속을 전제조건으로 한다.
자식클래스가 부모클래스에 저장될 수 있다.
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-클래스 캐스팅 에러가 뜨는 것이다.