5강. 다형성(polymorphism)
추천글 : 【Java】 Java 목차
1. 개요 [본문]
2. signature [본문]
3. method overriding [본문]
4. hiding static variable [본문]
5. hiding static method [본문]
6. method overloading [본문]
7. operator overloading [본문]
8. generics [본문]
a. GitHub
1. 개요 [목차]
⑴ 다형성 : 같은 기호를 쓰더라도 다른 변수, 명령어를 지칭하는 것
⑵ 용어 1. up-casting
Parent parent = new Child();
① intrinsic casting과 explicit casting
Parent parent1 = new Child(); // Intrinsic Casting
Parent parent2 = (Parent) (new Child()); // Explicit Casting
② 필요성 1. 고정된 메모리를 할당하는 배열은 주소만 저장하므로 서로 다른 객체들의 배열을 만들 수 있음
Child[] cArray = new Child[2];
cArray[0] = new Son();
cArray[1] = new Daughter();
⑶ 용어 2. down-casting
Child child = (Child) new Parent(); // error
① down-casting에서 Parent class가 Child class의 내용을 전부 담지 않으므로 강제 형변환이 불가능함
② up-casting이 선행되었다면 Parent class가 Child class의 내용을 모두 가지므로 down-casting이 예외적으로 허용
⑸ 용어 3. static binding
① 정의 : 변수들의 타입이 컴파일 타임에 확정된 경우
② 컴파일 타임 : compiler가 binary로 변환할 때
③ 예 : private, final, static
⑹ 용어 4. dynamic binding
① 정의 : 변수들의 타입이 컴파일 과정에서 확정되지 않고 JVM의 runtime 중에 dynamic하게 할당되는 경우
② 즉, 실제로 프로그램을 돌려보면서 입력되는 거 보면서 어떤 function을 고를지를 결정하는 것
③ 즉, explicit type을 통해 해당 method가 있는지 확인하고, runtime에서 수행할 때 실제 object의 method 호출
④ 예 : method overriding, equals(), toString(), hashCode()
⑺ 용어 5. object type casting
① 목적 : 메모리 내 저장된 정보가 있어도 type definition에 따라 접근할 수 없을 수 있어서 강제 형변환이 필요함
② explicit type을 따라가는 경우 (hiding) : static method, attribute, method parameter
③ actual type을 따라가는 경우 (overriding) : instance method
④ (참고) static method : hiding static method와 관련
⑤ (참고) attribute : hiding static variable과 관련
2. signature [목차]
① 개요
○ 정의 : 함수를 호출 시 식별자로 사용되는 요소
○ compile time에 결정됨
② C : 함수의 이름
○ C에서 동일한 이름을 가진 method를 동시에 선언할 수 없음
③ java : method name, parameter format
○ java에서 동일한 이름을 가진 method를 동시에 선언할 수 있음
○ return type은 signature가 아님 : return type이 다르면 java compiler는 에러를 일으킬 수 있음
int add(int, int);
double add(int, int); // compile error
○ signature는 explicit type을 기준으로 함 (ref)
3. method overriding [목차]
⑴ 개요
① 정의 : child class에서 새롭게 정의된 method가 parent class에서 받은 inherited method를 덧쓰는 것
② variable은 overriding 개념이 아니라 hiding 개념이 적용됨
③ (출제 예상) 예제
class Parent {
int x = 1;
void print(){System.out.println("Parent");}
}
class Child extends Parent {
int x = 2;
void print(){System.out.println("Child");}
}
public class Main {
public static void main(String[] args) {
Child child = new Child();
Parent parent = (Parent) child;
System.out.println(parent.x); // 1
parent.print(); // Child
}
}
⑵ 요건
① child class가 parent class로부터 상속을 할 것
② child class의 method와 parent class의 method의 signature가 같을 것
③ child class의 method와 parent class의 method의 return type이 같을 것
④ parent class의 method가 public, protected, default일 것
○ private의 경우 child class에서 invisible하기 때문
○ default라고 해도 package가 다르면 child class에서 invisible하기 때문에 상속되지 않음
○ 일반적으로 object method는 대부분 public
○ (출제 예상) .clone()과 .finalize()는 private
⑤ parent class의 method가 non-static일 것 : static이면 overriding이 아니라 hiding이 적용됨
⑶ 문법
① constructor overriding은 허용되지 않음
② typo 방지
○ child class에서 @override를 추가해서 typo를 방지할 수 있음 (선택)
○ parent class에 abstract를 쓰면 child class에서 override할 것이라는 계약을 하게 됨
③ overriding method가 overridden method보다 같거나 더 넓은 범위여야 함
○ overridden method가 public이면 overriding method는 public이어야 함
○ overridden method가 protected이면 overriding method는 protected 또는 public이어야 함
○ private 또는 static method는 overridden method가 될 수 없음
⑷ 예제 1 : method overriding은 parent.print();와 관련
class Parent {
int x = 1;
void print(){System.out.println("Parent");}
}
class Child extends Parent {
int x = 2;
void print(){System.out.println("Child");}
}
public class Main {
public static void main(String[] args) {
Child child = new Child();
Parent parent = (Parent) child;
System.out.println(parent.x); // 1
parent.print(); // Child
}
}
⑸ 예제 2
public class Main{
public static void main(String[] args){
A a1 = new A();
A a2 = new B();
A a3 = new D();
a1.m2(); // "A.m2"
a2.m2(); // "B.m2"
a3.m2(); // "C.m2"
((B) a2).m1(); // "B.m1"
// a2.m1() is error
}
}
class A{
public void m2(){
System.out.println("A.m2");
}
public void m3(){
System.out.println("A.m3");
}
}
class B extends A{
public void m1(){
System.out.println("B.m1");
}
public void m2(){
System.out.println("B.m2");
}
}
class C extends A{
public void m2(){
System.out.println("C.m2");
}
public void m3(){
System.out.println("C.m3");
}
}
class D extends C{
public void m1(){
System.out.println("D.m1");
}
public void m3(){
System.out.println("D.m3");
}
}
4. hiding static variable : variable hiding, variable shadowing이라고도 함 [목차]
⑴ 개요
① 정의 : object type casting에서 variable이 explicit type을 따라가는 것
② (주석) 굳이 static일 필요는 없는 듯
③ variable은 method와 달리 overriding이 아니라 hiding의 개념이 적용됨
⑵ 예제 1
class P1 {
static int x = 2;
}
class P2 extends P1 {
static double x = 3;
void print() {
System.out.println(x + " " + super.x + " " + ((P1) this).x);
}
}
public class Main {
public static void main(String[] args){
P2 p = new P2();
p.print();
// 3 2 2
}
}
① hiding static variable은 구체적으로 ((P1) this).x와 관련
② parent class에서 선언한 static 변수에 대하여,
○ child class에서 같은 이름으로 다시 선언 시 : 상속이 일어나지 않음
○ parent static 변수인 x = 2는 p의 메모리에 저장돼 있음
○ child class에서 x = 3을 선언하지 않았을 시 : child object는 parent class의 static 변수를 상속
③ 위와 같은 논리는 non-static variable, static method에도 적용됨
⑶ 예제 2
class A{
int a = 0; public void add() { a++; }
}
class AA extends A{
int a = 14;
}
class B{
int b = 0; public void add() { b++; }
}
class BB extends B{
int b = 14; public void add() { b++; }
}
public class Main{
public static void main(String[] agrs){
AA a = new AA();
BB b = new BB();
a.add(); b.add();
System.out.println(a.a); // 14; hidden a = 1
System.out.println(b.b); // 15; hidden b = 0
}
}
① method는 일단 같이 있던 variable에 우선순위를 부여함
② (참고) 실제로 JVM은 current class에서 먼저 찾아보고 없으면 parent class, grandparent class, ... 순으로 탐색
5. hiding static method [목차]
⑴ 개요
① 정의 : object type casting에서 static method가 explicit type을 따라가는 것
⑵ 예제 1
class Super{
static String greeting() { return "Goodnight"; }
String name() { return "Richard"; }
}
class Sub extends Super {
static String greeting() { return "Hello"; }
String name() { return "Henry"; }
}
public class Main {
public static void main(String[] args){
Super s = new Sub();
System.out.println(s.greeting() + ", " + s.name());
// Goodnight, Henry
}
}
① Sub class를 생성하는 과정에서 greeting()은 parent method와 child method가 공존함 (hiding)
② Sub class를 생성하는 과정에서 name()은 덧씌여짐
⑶ 예제 2
class Parent {
int x = 1;
static void print1(){System.out.println("Parent1");}
void print2(){System.out.println("Parent2");}
}
class Child extends Parent {
int x = 2;
static void print1(){System.out.println("Child1");}
void print2(){System.out.println("Child2");}
}
public class Main {
public static void main(String[] args) {
Parent person = new Child();
System.out.println(person.x); // 1
person.print1(); // Parent1
person.print2(); // Child2
}
}
6. method overloading [목차]
⑴ 개요
① 정의 : 동일한 method name, return type, 다른 parameter type인 경우
② 목적 1. 서로 다른 data type으로 같은 task를 처리하기 위해
③ 목적 2. 자료형에 따라 약간 다르게 처리하기 위해
⑵ 문법 : overloaded method를 override하는 게 가능
⑶ 예제 (추후 업데이트)
7. operator overloading [목차]
⑴ argument type에 따라 +, *, &, % 등의 연산자가 다른 의미를 갖는 것
⑵ java는 user-driven operator overloading을 제공하지 않음
⑶ 예
String s = "Dog" + " barks.";
s += "Too Loud!";
float f = 0.5 % 0.3;
8. (출제 예상) generics [목차]
⑴ 개요
① 정의 : 하나 이상의 변수 타입을 정의하는 클래스. parametric polymorphism
② 장점 : robustness, no type casting
⑵ 문법
① generic class : class C<T1, ..., Tn>
class Wrapper<T> {
T obj;
void add(T obj) { this.obj = obj; }
T get() { return obj; }
}
○ T는 symbol에 불과함 : T뿐만 아니라 E도 많이 쓰임
○ T는 아무 타입이 될 수 있으나 primitive type이 될 수 없음
○ T에 특정한 타입이 오도록 한정할 수 있음
○ T t = new T(); 같은 느낌은 안됨 : 컴파일 타임에 해당 생성자 유무를 확인할 수 없으므로
② generic method
class ArrayPrinter {
public static <E> void printArray(E[] elements) {
for(E element : elements) {
System.out.print(element.toString() + " ");
}
}
}
○ generic이 올 것임을 예고하는 <E> 등이 public static final 등 이후에 옴
③ generic constructor
public <T> Main (T t) { ... }
○ generic이 올 것임을 예고하는 <E> 등이 public static final 등 이후에 옴
④ wildcards in generic
○ <? extends T> : T 또는 T의 sub type을 이용
○ <?> : Object 또는 Object의 sub type을 이용
○ <? super T> : T 또는 T의 super type을 이용
⑤ generic는 class든 interface든 모두 extends로 작성
○ T implements Comparable<T>가 아니라 T extends Comparable<T>
입력: 2020.09.23 17:34
'▶ 자연과학 > ▷ Java' 카테고리의 다른 글
【Java】 6강. 자료구조 (0) | 2020.10.20 |
---|---|
【Java】 Java 목차 (0) | 2020.09.23 |
【java】 4강. 상속(inheritance) (0) | 2020.09.23 |
【Java】 3강. 캡슐화 (0) | 2020.09.23 |
【Java】 2강. 클래스 (0) | 2020.09.23 |
최근댓글