※ 다형성
- 여러가지 형태를 가질 수 있는 능력
- 부모 타입의 참조변수로 자식의 인스턴스를 참조할 수 있도록 함으로써 다형성을 구현
- 여러 개의 개별적인 클래스를 하나의 부모 클래스 객체로 통합 관리하여 그 효율성을 높인 것
▼다형성 대표형식
- ★★★부모에 자식을 넣는다 ( = 부모에 자식 객체 대입 = 부모의 참조변수로 자식의 인스턴스 참조 )
Parent p = new Child;
p.method(); // => child 에서 오버라이딩 된 메서드 출력됨
▶ 다형성 특징
- 위와같이 다형성을 이용해 부모에 자식을 넣으면 자식의 오버라이딩 메서드가 호출됨
- 부모의 참조변수 (p) 로는 부모의 멤버들만 사용가능,
자식만의 메서드는 호출불가
- 부모타입이 파생된 모든 자식 타입을 가리킬 수 있으므로 부모 타입의 변수로 모든 자식 타입을 일관되게 관리할 수 있다
[ 부모의 참조변수로는 부모의 멤버만 접근 가능
단 , 오버라이딩 메서드가 있다면 자식의 오버라이딩 메서드 호출 ]
△ 위 문법 실감나게 익혀보기
lass Parent{
int x=100;
public void method() {
System.out.println("Parent");
}
}
class Child extends Parent{
int x=300;
public void method() {
System.out.println("Child~");
}
}
Parent p = new Child(); // 다형성
System.out.println("p.x="+p.x); // 부모의 참조변수로는 부모의 멤버만 접근가능.
//오버라이딩되었으면 300이 나왔겠지만 오버라이딩 안되었기때문에 위 기본조건을 따라 100이 나옴
p.method(); // => 300이 아님 !! 100이다 100 !!!
▶다형성을 이용하여 메서드 만들고 호출하기
1. 매개변수가 클래스 인 경우
▷만들기
public static void func1(Circle c){
c.draw();
c.delete();
c.sayCircle();
}
▷호출하기
Q. 클래스를 어떻게 매개변수로 넣지 ? => new 로 객체생성해서 !
Circle c = new Circle();
func1(c);
↓간단히
func1(new Circle());
만약 func1 메서드가 다른 클래스(Work) 에 소속되어있는 메서드라면
Work 클래스 호출 후 참조변수. 해서 호출하면된다 !
Work a = new Work();
a.func1(new Circle());
▷만들기
class AAA{
public void method1(Cat c) {
c.bark();
}
▷호출하기
AAA obj = new AAA();
obj.method1(new Cat());
1-1. 매개변수가 클래스 인 경우 - 매개변수의 다형성
▷만들기
public static void func2(Shape sh) {
sh.draw();
sh.delete();
}
△ 매개변수가 부모클래스(shape) 인 상황.
이럴땐 main()에서 >>>자식객체<<<를 넣어 호출한다 !
▷호출하기 (정석)
Shape sh = new Triangle();
Circle c = new Circle();
func2(c);
=> 1 ) 부모에 자식을 넣는다 ( 이때 자식은 아무 자식이나 넣어도 됨 )
2 ) 매개변수로 넣어줄 클래스 객체 생성을 한다
3 ) 메서드안에 객체생성한 참조변수를 넣어준다
= > Shape draw , delete : 그린다, 지운다 => Circle 클래스 참조변수 c 넣어줌 => 원을 그린다, 원을 지운다
: 그린다, 지운다 => 원을 그린다, 원을 지운다
↓간단히
func2(new Triangle());
func2(new Circle());
▷만들기
class AAA{
public void method2(Animal an) {
an.bark();
}
▷호출하기
AAA obj = new AAA();
obj.method2(new Cow());
2. 반환타입이 클래스인 경우
- return type 자리에 클래스명 써주면 됨 (★★★반환타입이 Circle(클래스)이면 Circle 객체가 리턴된다★★★) = ( 본인의 객체가 리턴되는 것 )
▷만들기
public static Circle func3() {
Circle c = new Circle();
return c;
}
▷호출하기
- 1 ) 메서드명 부르기 func3
- 2 ) class로 받기 Circle c2 = func3();
- 3 ) 참조변수. 으로 호출하기 c2.delete();
Circle c2 = func3();
c2.delete();
▷만들기
class AAA{
public Cat method3() {
return new Cat();
}
▷호출하기
AAA obj = new AAA();
Cat c=obj.method3();
2-1. 반환타입이 클래스인 경우 - 다형성이용
- ★★★ 반환타입이 Shape(부모) 이면 자식객체가 리턴된다 ★★★
▷만들기 [1]
public static Shape func4 (int type) {
Shape sh = null;
if(type==1) {
sh = new Circle();
}else if (type==2) {
sh = new Triangle();
}
return sh;
}
메서드에서 바로 리턴하는 경우 [2]
// [1] 이랑 결과는 똑같음
- 반드시 else 를 추가해줘야 함
public static Shape func4 (int type) {
Shape sh = null;
if(type==1) {
return new Circle();
}else if (type==2) {
return new Triangle();
}else {
return sh; // 반드시 else를 추가해줘야 함.
}
}
▷호출하기
Shape sh2 = func4(3);
sh2.draw();
▷만들기
class AAA{
public Animal method4() {
return new Cow();
}
▷호출하기
AAA obj = new AAA();
Animal an=obj.method4();
2-2. 반환타입이 클래스인 경우 - 다형성이용 또해보기
▷만들기
★★★ 반환타입이 Shape(부모) 이면 자식객체가 리턴된다 ★★★
public static Shape createShape(int type) {
//다형성 이용
Shape s2 = null; // 클래스 초기화
if(type==1) {
s2 = new Circle();
}else if (type==2) {
s2=new Triangle();
}
return s2;
= type 이 1 일경우 자식클래스 Circle리턴,
type 이 2 일경우 자식클래스 Triangle 리턴.
▷ 호출하기
( 만든 (반환타입이 클래스인) 메서드 호출하기 )
Shape s1 = createShape (type);
if(s1!=null) { //참조변수. 사용할때는 다음과 같이 if 문으로 null체크를 해주는것이 좋다
s1.delete();
s1.draw();
}else {
System.out.println("잘못입력 !");
return;
참조변수. 메서드명 으로 사용하면 됨 !
▶ 다형성 이용하여 클래스 배열만들기
(일반) Triangle 배열 만들고, 요소 3개 넣고, draw ()메서드 호출
Triangle [] arr = new Triangle[3];
arr[0] = new Triangle();
arr[1] = new Triangle();
arr[2] = new Triangle();
for(int i=0;i<arr.length;i++) {
arr[i].draw();
}
(다형성) Triangle 의 부모 Shape 배열만들고 호출
pArr[0] = new Circle();
pArr[1] = new Triangle();
pArr[2] = new Circle();
for(int i=0;i<pArr.length;i++) {
pArr[i].draw();
pArr[i].delete();
}
※ 빠른찾기
(1) #다형성 #오버라이딩메서드호출 #UpCasting
Animal ani=null;
switch (type){
case 1: ani = new Cat();
break;
case 2: ani=new Dog();
break;
case 3: ani=new Cow();
break;
default:
System.out.println("잘못 입력함!!!");
return;
}//switch
ani.bark();
(2) #다형성 #DownCasting #자식만의 메서드 호출
if (ani instanceof Cat){
Cat m=(Cat)ani;
m.showCat();
}else if (ani instanceof Dog) {
Dog t=(Dog)ani;
t.showDog();
}else if (ani instanceof Cow) {
Cow d=(Cow)ani;
d.showCow();
}
(3) #배열 #4개요소넣기 #오버라이딩메서드호출
Animal[] arr = new Animal[4];
arr[0]=new Cat();
arr[1]=new Dog();
arr[2]=new Cow();
arr[3]=new Dog();
for (int i=0; i<arr.length; i++) {
arr[i].bark();
}//for
(4) #배열 #DownCasting #모든배열요소의 자식만의 메서드 호출
for (int i=0; i<arr.length; i++) {
if (arr[i] instanceof Cat){
Cat m=(Cat)arr[i];
m.showCat();
}else if (arr[i] instanceof Dog) {
Dog t=(Dog)arr[i];
t.showDog();
}else if (arr[i] instanceof Cow) {
Cow d=(Cow)arr[i];
d.showCow();
}
}//for
(4-1) 자식만의 메서드를 호출하는 부분을 메서드로 만들어서 처리
for (int i=0; i<arr.length; i++) {
callAnimal(arr[i]);
}//for
}
(5) #배열 #DownCasting #자식만의 메서드 호출 #Only is one #instanceof 가 Cat 인것만 나옴
if (ani instanceof Cat){
Cat m=(Cat)ani;
m.showCat();
}else if (ani instanceof Dog) {
Dog t=(Dog)ani;
t.showDog();
}else if (ani instanceof Cow) {
Cow d=(Cow)ani;
d.showCow();
}
'JAVA' 카테고리의 다른 글
[JAVA] 추상클래스 / 추상메서드 / 인터페이스 Interface (0) | 2022.03.05 |
---|---|
[JAVA] DownCasting / instanceof / 클래스 배열 downcasting (0) | 2022.03.03 |
<Eclipse 이클립스 단축키> (0) | 2022.03.01 |
[JAVA] super() / final / 포함관계 (Has a) / 클래스를 멤버변수로 넣기 / classpath (0) | 2022.03.01 |
[JAVA] 상속 / 오버라이딩 / this,super / 검색하기 (0) | 2022.02.26 |