다형성
package com.bit.day08.am;
class Lec06{
int su=1111;
void func(){
System.out.println("부모기능");
}
}
//다형성
public class Ex06 extends Lec06 {
int su=2222;
void func(){
System.out.println("자식기능");
}
public static void main(String[] args) {
Lec06 me1=new Lec06();
me1.func();
System.out.println("-----------------");
Ex06 me2=new Ex06();
me2.func();
System.out.println("-----------------");
Lec06 me3 = new Ex06(); //
me3.func();
}
}
//출력물
/*
부모기능
-----------------
자식기능
-----------------
자식기능
*/
오버라이드 대상 = 메소드
메소드는 내꺼로 실행하지만 필드의 값은 부모의 타입이므로 부모의 것으로 나온다.
package com.bit.day08.am;
class Lec06{
int su=1111;
void func(){
System.out.println("부모기능");
}
}
//다형성
public class Ex06 extends Lec06 {
int su=2222;
void func(){
System.out.println("자식기능");
}
public static void main(String[] args) {
Lec06 me1=new Lec06();
me1.func();
System.out.println(me1.su);
System.out.println("-----------------");
Ex06 me2=new Ex06();
me2.func();
System.out.println(me2.su);
System.out.println("-----------------");
Lec06 me3 = new Ex06();
me3.func();
System.out.println(me3.su);
//필드 접근시에는 부모타입이므로 부모의 값 1111 나옴(오버라이드가 안되니까)
}
}
자식에게만 있는 기능
package com.bit.day08.am;
class Lec06{
int su=1111;
void func(){
System.out.println("부모기능");
}
}
//다형성
public class Ex06 extends Lec06 {
int su=2222;
void func(){
System.out.println("자식기능");
}
void func2(){
System.out.println("자식만의 기능");
}
public static void main(String[] args) {
Lec06 me1=new Lec06();
me1.func();
System.out.println(me1.su);
System.out.println("-----------------");
Ex06 me2=new Ex06();
me2.func();
me2.func2(); //호출 가능.
System.out.println(me2.su);
System.out.println("-----------------");
Lec06 me3 = new Ex06();
me3.func();
me3.func2(); //오류 : 실행은 자식이지만 부모에 없기 때문에 실행되지 않는다.
System.out.println(me3.su);
}
}
타입을 부모타입으로 쓰면, 부모에 정의돼있는 것만 쓸 수 있다. 하지만 메소드에 한해서는 (오버라이드로 인해
구현은 내 객체에서 일어났으므로 정의된 내용인지 아닌지만 확인 후) 타입과 상관없이 내 객체의 메소드를 실행하도록 만들어졌다.
Object 클래스를 이용한 재정의
: 모든 클래스는 Object 클래스를 상속하므로, 내 클래스 안에서 object클래스의 메소드를 오버라이딩하여 사용할 수도 있다.
package com.bit.day08.am;
class Lec06{
int su=1111;
void func(){
System.out.println("부모기능");
}
}
//다형성
public class Ex06 extends Lec06 {
int su=2222;
void func(){
System.out.println("자식기능");
}
void func2(){
System.out.println("자식만의 기능");
}
public static void main(String[] args) {
Lec06 me1=new Lec06();
me1.func();
System.out.println(me1.su);
System.out.println("-----------------");
Ex06 me2=new Ex06();
me2.func();
me2.func2(); //호출 가능.
System.out.println(me2.su);
System.out.println("-----------------");
Lec06 me3 = new Ex06();
me3.func();
// me3.func2();
System.out.println(me3.su);
System.out.println("------------------");
Object obj=new Ex06();
System.out.println(obj); //지금 이걸 보여주는 이유가 무ㅓ지?
System.out.println(obj.toString()); //내가 오버라이딩한 메소드로 나옴
}
public String toString(){ //toString 메소드 오버라이딩
return "내가 재정의";
}
}
package com.bit.day08.am;
class Lec06{
int su=1111;
void func(){
System.out.println("부모기능");
}
}
//다형성
public class Ex06 extends Lec06 {
int su=2222;
void func(){
System.out.println("자식기능");
}
void func2(){
System.out.println("자식만의 기능");
}
public static void main(String[] args) {
Lec06 me1=new Lec06();
me1.func();
System.out.println(me1.su);
System.out.println("-----------------");
Ex06 me2=new Ex06();
me2.func();
me2.func2(); //호출 가능.
System.out.println(me2.su);
System.out.println("-----------------");
Lec06 me3 = new Ex06();
me3.func();
// me3.func2();
System.out.println(me3.su);
System.out.println("------------------");
Ex06 obj1=new Ex06();
Ex06 obj2=new Ex06();
System.out.println(obj1==obj2); //false
System.out.println(obj1.equals(obj2)); //false - value값 비교를 했기 때문에. 저 객체의 값이 뭔지 몰라서
}
//object 클래스 재정의 --> 오버라이드해서 덮어써서 비교. 재정의 후 출력하면 true가 나온다.
public boolean equals(Object obj) {
return toString().equals(obj.toString()); // =obj1.toString().equals(2222);
}
public String toString(){
return ""+su;
}
}
다형성 정리
package com.bit.day08.am;
//다형성 - 부모의 타입으로도 받을 수 있는 상황
//Lec07 lec = new Lec07(); --> "Lec07-func01()"
//Lec07 lec = new Lec07(); --> x
//Lec77 lec = new Lec77(); --> "Lec77-func01()"
//Lec77 lec = new Lec77(); --> "Lec77-func02()"
//Lec07 lec = new Lec77(); --> "Lec77-func01()"
//Lec07 lec = new Lec77(); --> "Lec77-func02()" x
class Lec07{
public void func01(){
System.out.println("Lec07-func01()");
}
}
class Lec77 extends Lec07{
public void func01(){
System.out.println("Lec77-func01()");
}
public void func02(){
System.out.println("Lec77-func02()");
}
}
public class Ex07 {
public static void main(String[] args) {
}
}
✏️다형성을 이용한 예제
: tv,라디오를 각각 동작시키고 싶으면 공통된 on, off동작 코드를 중복으로 가지게 된다. 다형성을 이용하여 공통된 코드를 하나로 모으고, 원하는 객체를 만들어 그 객체의 동작만 실행시킬 수 있다.
공통된 것들을 모아 부모클래스로 만들어주고, 하위객체는 공통기능 + 원하는 기능만 재정의 하여 실행할 수 있다.
package com.bit.day08.am;
public class Ex08 {
public static void main(String[] args) {
// Machine01 obj = new Machine01();
// Tv obj=new Tv();
// Machine01 obj=new Tv();
java.util.Scanner sc = new java.util.Scanner(System.in);
System.out.println("1.Tv 2.Radio 0.exit>");
int input=sc.nextInt();
Machine01 obj=null; //부모의 타입을 가진다.
if(input==1){
obj=new Tv();
} else if(input==2){
obj=new Radio();
}
obj.on();
obj.work();
obj.off();
}
}
// 라디오 클래스
public class Radio extends Machine01{
public void work(){
System.out.println("주파수를 잡아 소리를 들려줍니다");
super.work(); //부모클래스에 있는 work메소드 호출
}
}