본문 바로가기
프로그래밍 언어/JAVA

[JAVA] 오버라이딩(Overriding) 과 오버로딩(Overloading) // 다형성

by E145 2021. 1. 20.
반응형

 1. 메소드 오버라이딩(Overring)

 

 

 메소드 오버라이딩(Overriding)이란?

 

 - 메소드를 재정의하는 것.

 

 - 부모 클래스의 메소드를 자식 클래스가 동일한 형태로 다시 구현할 때 사용한다.

 


 

 

 메소드 오버라이딩 사용법

 

 - 인자, 이름은 똑같아야 하고, 리턴 유형은 호환 가능해야 한다.

 

 - 매개 변수 이름은 달라도 된다.

 

 - 메소드를 더 접근하기 어렵게 만들면 안 된다. 즉, 접근 단계는 그대로 유지하거나, 완화시켜야 한다.

   (public -> private로 변환하면 안된다.)

 

import java.util.*;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		child1 c=new child1();
		c.Method();
		
	}

}

class parent{
	public String name;
	public void Method() {
		System.out.println("parent Method");
	}
}

class child1 extends parent{
	public child1() {
		this.name="child1";
	}
	public void Method() {
		System.out.println(name+" Method");
	}
}

실행 결과

 

참조 객체 확인

 

 - instanceof를 이용하여, 현재 참조중인 객체가 어떠한 객체인지 확인할 수 있다.

 

 - instacneof는 하위 클래스 부터 검사해야 한다. 

   하위 클래스를 포함하는 부모 클래스를 검사하는 경우 true를 리턴한다.

public class start {

    public static void main(String[] args)  {

        parent p = new child();

        if(p instanceof child)
            System.out.println("현재 자식 클래스 참조중입니다.");
        else
            System.out.println("현재 부모 클래스 참조중입니다.");

        p = new parent();

        if(p instanceof child)
            System.out.println("현재 자식 클래스 참조중입니다.");
        else
            System.out.println("현재 부모 클래스 참조중입니다.");
    }

}

class parent{
    public int num=5;
    public void test(){
        System.out.println("parent Test");
    }
}

class child extends parent{
    public int num=7;
    public void test(){
        System.out.println("Child Test");
    }

    public void childTest(){
        System.out.println("ChildTest Test");
    }
}

 

 


2. 메소드 오버로딩(Overloading) 이란?

 

 

메소드 오버로딩(Overloading) 이란?

 

 - 이름이 같고, 인자 목록이 다른 메소드를 의미한다.

 - 오버로딩된 메소드는 이름만 같을 분 서로 다른 메소드이다.

 


 

메소드 오버로딩의 장점

 

 - 메소드를 호출하는 입장에서 편리하다

 


 

메소드 오버로딩 사용법

 

 - 인자 목록만 다르다면, 리턴 유형이 달라도 된다.

 

 - 리턴 유형만 바꿀 수는 없다.

 

 - 접근 단계를 마음대로 바꿀 수 있다.

 

import java.util.*;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		calc classCalc=new calc();
		System.out.println(classCalc.add(1, 2));
		System.out.println(classCalc.add(2.5, 5.322));
	}

}

class calc{
	public int add(int n1,int n2) {
		return n1+n2;
	}
	public double add(double n1, double n2) {
		return n1+n2;
	}
}

실행 결과

 


 

다형성

 

 - 같은 이름을 가진 메소드가 다른 활동을 하는 것.

 

 

클래스 타입의 변화

 

 - 부모 클래스 타입에 자식 클래스 객체를 선언하여 사용할 수 있다.(업캐스팅)

 

 - 부모 클래스에 선언된 멤버 변수와 메소드에 접근할 수 있지만, 자식 클래스의 멤버 변수, 메소드가 실행 된다.

 

 - 컴파일러는 자식 클래스에 부모 클래스의 메소드가 있는지 확인한다.

 

 - 실제 실행 시 메모리에 올라온 부모 클래스로 선언된 메소드를 실제 자식 인스턴스를 참조하여 실행한다.

 

public class start {

    public static void main(String[] args)  {
		
        // 부모 클래스 타입에 자식 클래스 인스턴스 참조값 저장
        parent p = new child();
        p.test();
    }

}

class parent{
    public int num=5;
    public void test(){
        System.out.println("parent Test");
    }
}

class child extends parent{
    public int num=7;
    public void test(){
        System.out.println("Child Test");
    }
}

 

 

public class start {

    public static void main(String[] args)  {

        parent p = new child();
        p.childTest();  // 자식 클래스만 정의된 메소드 실행
    }

}

class parent{
    public int num=5;
    public void test(){
        System.out.println("parent Test");
    }
}

class child extends parent{
    public int num=7;
    public void test(){
        System.out.println("Child Test");
    }

    public void childTest(){
        System.out.println("ChildTest Test");
    }
}

 

 - 부모 클래스 타입에 자식 클래스 인스턴스를 생성한 경우, 자식 클래스에서만 선언된 멤버 변수, 메소드는 실행이 불가능하다.

   부모 클래스는 자식 클래스가 어떠한 것을 선언했는지 알 수 없다.

 

 

필드의 다형성, 배열에서의 다형성

 

 - 클래스의 필드에 부모 클래스 변수를 선언한 후 자식 클래스 추가 및 수정이 된 경우 큰 수정 없이 간단하게 사용할 수 있다.

 

 - 배열을 부모 타입으로 선언하게 되면, 해당 부모를 상속 받는 자식들이 추가 및 수정이 되어도 일정한 방식으로 사용할 수 있다.

 

public class Main {

    public static void main(String[] args) {
        MyAnimal ma = new MyAnimal();

        ma.addAnimals(new Dog("바둑이"));
        ma.addAnimals(new Dog("몽몽이"));
        ma.addAnimals(new Dog("멍멍이"));

        System.out.println("== 변경 전 ==");
        ma.getMyAnimals();

        ma.setAnimals(0,new Cat("야옹이"));

        System.out.println("== 변경 후 ==");
        ma.getMyAnimals();
    }


}

class MyAnimal{
    Animal[] animals = new Animal[3];
    int index=0;
    public void addAnimals(Animal animal){
        animals[index++]=animal;
    }

    public void setAnimals(int index,Animal animal){
        animals[index]=animal;
    }

    public void getMyAnimals(){
        for(Animal animal : animals){
            animal.bark();
        }
    }
}

class Animal{
    String name;
    public void bark(){
        ;
    }
}

class Dog extends Animal{
    public Dog(String name){
        this.name=name;
    }
    @Override
    public void bark() {
        System.out.println(name+" : 멍멍");
    }
}

class Cat extends Animal{
    public Cat(String name){
        this.name=name;
    }
    @Override
    public void bark() {
        System.out.println(name+" : 야옹");
    }
}

 

 

반응형

댓글