상수, 변수, 객체, 메쏘드 등이 디양한 자료형(type)을 가질 수 있는 성질을 의미한다.
즉, 하나의 객체에 여러가지 타입을 적용할 수 있다는 것이다.
다형성을 이용하여 확장성이 뛰어나고 변경이 용이한 프로그래밍을 할 수 있다.
다형성을 구현하는 방법은 대표적으로 오버로딩(Overloading)과 오버라이딩(Overriding)이 있다.
오버로딩은 하나의 클래스에서 같은 이름의 메소드들을 여러개 가질 수 있게 하는 것을 뜻한다.
예를 들어 매개변수의 타입(type)이나 개수를 달리 하여 컴파일러에게 서로 다른 메써드로 인식되도록 할 수 있다.
오버로딩을 활용하면 '키패드'라는 이름의 기능이 휴대폰과 테블릿에서 각각 다르게 구현되도록 만들 수 있다.
오버 라이딩은 부모클래스를 상속받은 자식클래스가 부모의 메소드를 새롭게 정의하는 것을 뜻한다.
이를 활용하면 하나의 부모클래스를 상속받은 여러개의 자식클래스가 같은 이름을 가진서로 다른 기능을 구현하는 메소드를 사용할 수 있다.
예를 들어 동물(Animal)이라는 부모클래스를 물려받은 개(Dog)와 고양이(Cat) 클래스가 있고
동물마다 울음소리가 다르다고 했을 때 부모클래스에게 물려받은 울음소리(bark())메쏘드를 각 동물에 맞게 구현할 수 있게 된다.

위 그림에서 택시기사 객체(Taxi Driver)가 멤버변수로 자신이 소유한 자동차(MyCar = 아반떼)를 가진다고 가정하자.
이 때 자동차의 타입(type)을 부모클래스인 Taxi로 지정하면 나중에 다른차로 교체하더라도 부모타입인 Taxi 클래스의 기능을 상속받은 자동차(소나타, 그랜져, ...)로 교체해주기만 하면 된다!
다형성을 활용하면 하나의 부모타입이 다양한 자식타입의 참조변수(위에서 자동차 객체)를 가질 수 있게 되므로 확장성이 뛰어난 코드를 구현할 수 있다!