관리자 글쓰기
한약 다이어트 일기
2022. 3. 6. 17:23 - Daybreak0_0

* DAY 1 (22. 3. 3.)

시작 몸무게: 58.6 kg

몸상태: 두통 심함, 어깨통증 심함ㅠㅠ

 

꼬박 지켰다가.. 저녁에 샐러드 먹었는데 너~~무 맛있음 ^^

어지럽고, 기력없음. 생각안듬!!! 


* DAY 2 (22. 3. 4.)

몸무게: 57.7 kg

몸상태: 두통, 어깨 통증 심함

 

어우 맨날 ㅊ먹다가 안먹으려니 너~~~무 힘들었다.

약 잘 챙겨먹었는데 저녁 9시에 엽떡 시켜서... 먹음....... 존맛...


* DAY 3 (22. 3. 5.)

몸무게: 58.0 kg

몸상태: 안아픔. 정화된 느낌. 배가고프지도 않았음 ㅎ

 

늦게일어나서 약 늦게 먹기시작 ㅠㅠ 9시까지 먹었다!

점심에 그릭요거트 2/3 먹음 배불러.


* DAY 4 (22. 3. 6.)

몸무게: 57.2 kg

몸상태: 개운했음 배가매우고파서 기력없 ㅠㅠ 어깨가 아플랑 말랑함

 

점심은 샐러드 반개.. 딸기 2개!

12시에 인나서 약은 덜먹을듯, 배고파 ~~~ 언제까지 해야돼? 

신문기사 읽기 특훈 1월 3주차
2022. 1. 17. 21:51 - Daybreak0_0

매일경제 1.10.(월) ~ 1.15.(토)

 

1. 11.(화)

- 변동성 낮을 때는 ETF로 분산투자

- 금리높아 예적금 추천

- 정부 정책으로 육성하는 리츠 추천

정리: 가치주/성장주형 ETF 40%, 유망주 미국한국주식 30%, 부동산 리츠 펀트 20%, 가상화폐 10%로 분산투자!

 

1. 12.(수)

안전운임제로 타격받는 업계

- 화학업체: 화학물질 운반을 위해 위험물 저장 탱크 필요 + 30% 할증, 무게 할증 1t 당 +10%

- 제지업계: 코로나19로 포장박스 수요 증가로 수요가 늘어났으나 부피가 크고 무게가 많이 나감. (+증량물 할증)

- 타이어업계: 타이어 차지하는 공간으로 컨테이너 물동량이 수만대. 

=> 안전운임은 불투명한 원가 조사와 할증률 적용 등 비합리적으로 산정됐다는 의견이 있음.

* 안전운임제: 화물차주의 적정운임을 보장하는 제도. 2020년부터 시행함.

 

 

'신문기사 읽기' 카테고리의 다른 글

신문기사 읽기 특훈 1월 2주차  (1) 2022.01.09
신문기사 읽기 특훈 1월 2주차
2022. 1. 9. 21:36 - Daybreak0_0

매일 경제 22.1.3.(월) ~ 22.1.8.(토)

 

'신문기사 읽기' 카테고리의 다른 글

신문기사 읽기 특훈 1월 3주차  (1) 2022.01.17
가비지 컬렉션
2016. 12. 19. 02:17 - Daybreak0_0

가비지 컬렉터 : 메모리 관리를 자동으로 해줌 

메모리의 스택, 힙 영역에서 객체들이 존재하는 힙영역에서 행해진다. ==> 가능한 많은 여유 메모리를 갖도록 관리함


가비지 컬렉터는 언제 실행될까?

JVM 제어 하에 있으며, 실행 시기도 JVM이 결정한다. 

사용 가능한 메모리가 적다고 감지될 때, JVM이 가비지 컬렉터를 실행시킨다.


객체가 가비지 컬렉션 대상이 되도록 만드는 코드


1. 참조를 null로 만들기


1
2
3
4
5
6
7
8
9
public class Garbage{
    public static void main(String[] args){
        StringBuffer sb = new StringBuffer("hello");
        System.out.println(sb);
        
        sb = null;
        // 이제 가비지 컬렉터의 대상이된다.
    }
}
cs


sb는 StringBuffer 객체의 유일한 참조이므로 sb가 null이 되면 StringBuffer 객체는 가비지 컬렉션의 대상이 된다.


2. 참조 변수를 다시 지정하기


1
2
3
4
5
6
7
8
9
10
public class Garbage{
    public static void main(String[] args){
        StringBuffer s1 = new StringBuffer("hello");
        StringBuffer s2 = new StringBuffer("goodbye");
        System.out.println(s1);
        
        s1 = s2; // s1의 참조 값을 변경한다.
        // "hello" StringBuffer 객체는 이제 가비지 컬렉터의 대상이된다.
    }
}
cs


** 메서드가 호출되면, 메서드가 실행되는 동안만 존재하는 지역 변수가 생긴다. 

메서드 실행이 끝나고 복귀되면, 그 메서드 내에서 생성된 객체는 가비지 컬렉션의 대상이 된다.


예외! 만일 메서드가 객체를 반환한다면, 그 객체의 참조를 갖는 참조 변수가 호출된 메서드에 존재할 것이므로, 가비지 컬렉션의 대상이 되지 않는다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.Date;
 
public class GarbageFactory {
 
    public static void main(String[] args) {
        Date d = getDate(); // Date 객체를 반환하는 메서드 
        System.out.println("d =" + d);
    }
    
    /*
     * 이 메서드는 Date, StringBuffer 두가지 객체를 생성
     * Date 객체를 반환하므로, 메서드의 실행이 끝나고 복귀하더라도 메서드에서 생성한 Date 객체는 가비지 컬렉션의 대상이 아님.
     * 반면, StringBuffer 객체는 now 참조 변수에 null을 넣지 않더라도 가비지 컬렉션의 대상이 된다.
     * */
    public static Date getDate(){
        Date d2 = new Date();
        StringBuffer now = new StringBuffer(d2.toString());
        System.out.println(now);
        return d2;
    }
 
}
 
cs


3. 참조를 고립시키기


적법한 참조를 갖고 있는 객체조차도 가비지 컬렉션의 대상이 될 수 있는 방법이 있다.

클래스의 인스턴스 변수는 같은 클래스의 다른 인스턴스를 참조하는 참조 변수이다. 

이 클래스 인스턴스는 두 개 있고, 상호 간에 참조를 한다고 해보자. 

만일 이 두개의 인스턴스를 참조하는 모든 다른 참조가 제거된다면, 두 인스턴스가 상호 참조를 갖고 있더라고 살아있는 스레드에서 두 인스턴스에 접근할 방법이 없으므로

가비지 컬렉터의 제거 대상이 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Island{
    Island i;
    
    public static void main(String[] args){
        
        Island i2 = new Island();
        Island i3 = new Island();
        Island i4 = new Island();
        
        i2.i = i3; // i2는 i3를 참조
        i3.i = i4; // i3는 i4를 참조
        i4.i = i2; // i4는 i2를 참조
        
        i2 = null;
        i3 = null;
        i4 = null;
        
        // i2, i3, i4는 가비지 컬렉션의 대상이 된다.
    }
    
}
cs



** 문제


1. 다음 코드에서 가비지 컬렉션의 대상이 되는 객체는 몇개인가?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
public class CardBoard {
 
    Short story = 200;
    private CardBoard go(CardBoard cb) {
        cb = null;
        return cb;
    }
    
    public static void main(String[] args) {
        CardBoard c1 = new CardBoard();
        CardBoard c2 = new CardBoard();
        CardBoard c3 = c1.go(c2);
        c1 = null;
    }
 
}
 
cs


답: 2개 . c1이 가비지 컬렉션 대상이 되고, 그 객체는 Short 래퍼 객체를 갖고 있으므로, 이 객체도 가비지 컬렉션의 대상이 된다.


2. main() 메서드에서 생성된 객체 수와 가비지 컬렉션의 대상이 되는 객체 수는?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Dozens {
    int[] dz = {1,2,3,4,5,6,7,8,9,0};
}
 
public class Eggs {
    
    public static void main(String[] args) {
        Dozens[] da = new Dozens [3];
        da[0= new Dozens();
        Dozens d = new Dozens();
        da[1= d;
        d = null;
        da[1= null;
    }
 
}
 
cs


답:

5 객체 / 2개의 객체가 GC의 대상이된다.

da는 Dozens 객체를 저장하는 배열 참조이다. 각각의 Dozens객체는 int 값을 저장하는 배열을 갖고 있다.

따라서, 생성된 객체 수는 5개 ( da 배열 객체 1개, Dozens 객체 2개,  각 Dozens 객체들이 가지는 int배열 객체 두개)

가비지 컬렉션 대상이 되는 객체는 2개 ( d가 참조했던 Dozens객체 한개, 그 객체가 갖는 int 배열 객체 한개)


3. 가비지 컬렉션의 대상이 되는 객체는 몇개?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Beta {} 
class Alpha {
    static Beta b1;
    Beta b2;
}
 
public class Tester {
 
    public static void main(String[] args) {
        Beta b1 = new Beta();
        Beta b2 = new Beta();
        
        Alpha a1 = new Alpha();
        Alpha a2 = new Alpha();
        
        a1.b1 = b1;
        a1.b2 = b1;
        a2.b2 = b2;
        a1 = null;
        b1 = null;
        b2 = null;
        
    }
 
}
 
cs


답 : 1개. 

a2가 참조하는 Alpha 객체 참조는 아직 살아 있고, a1만 null값이므로, a1이 참조하는 Alpha 객체만 가비지 컬렉션의 대상이 된다.

'Java 정리' 카테고리의 다른 글

CH2_ 올바른 값의 반환  (0) 2016.06.16
CH2_참조 변수 Casting  (0) 2016.06.16
오버라이딩과 오버로딩  (0) 2016.06.15
오사카 복태랑_ 오꼬노미야끼 야끼소바
2016. 7. 31. 21:48 - Daybreak0_0


후... 오사카 난바 존맛집이었다... 한국인도 간간히 있고 꽤 로컬스러운 곳이었다.





말 필요없다.

사진 고고


계란야끼소바



단면 ~_~





네기야끼

타코야끼도 오꼬노미야키도 파를 얹어야 존맛인거같다. 네기! 

아 타코야끼처럼 위에 얹어 나올줄 알았는데 속재료 였다 ㅋㅋ





또먹고싶당

'일상' 카테고리의 다른 글

잠실_ 스시준 초밥  (0) 2016.06.07
return과 break
2016. 7. 21. 11:23 - Daybreak0_0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  <script>
        /*
         예제02: 무한 루프를 돌며 숫자를 입력받고 입력받은 수의 합을 화면에 출력하는 기능을 sample()이라는 함수에 만들어 주세요.
         단, 입력 값이 0이면 즉시 실행을 멈춰 주세요.
        */
 
        function sample(){
            var sum =0;
            var count=1;
 
            // 무한루프 시작
            while(true){
                var value = parseInt(window.prompt("수 입력",1));
                if(value==0){
                    document.write("종료합니다.");
 
                    //함수 탈출
                    // break; // while() 루프를 빠져나와 document.write("총 "+count+"번 실행했습니다."); 을 실행함
                    return// 함수를 아예 빠져나온다. 
                }
 
                // 입력 값 더하기
                sum+=value;
 
                // 입력 값 출력하기
                document.write(count +". "+sum+"<br>");
                count++;
            }
 
            document.write("총 "+count+"번 실행했습니다.");
        }
 
        // 함수 호출
        sample();
 
    </script>
cs


CH2_ 올바른 값의 반환
2016. 6. 16. 15:44 - Daybreak0_0

목표 . 주어진 코드를 보고 오버라이딩이나 오버로딩이 잘 되었는지 판단하기 

        메서드 반환 타입이 적합한지 확인

        반환 타입과 실제 반환되는 값의 두 가지 관점을 본다. 

        반환 타입에 관련해서 오버로딩과 오버라이딩 시에 다른 점을 알아본다.


반환 타입의 선언


## 오버로딩된 메서드의 반환 타입


메서드 오버로딩은 메서드 이름을 같은 것으로 재사용할 수 있음을 말한다. 

오버로딩된 메서드는 기본 메서드와 전혀 다른 메서드이다. 이름만 같다 ! 


따라서, 슈퍼 클래스에서 상속받은 메서드를 서브 클래스에서 오버로딩하면, 오버라이딩과는 달리 반환 타입의 제약이 없다.

메서드를 오버로딩하려면 메서드 인가를 다르게 해야 한다는 것을 잊지 말자 ! 


1
2
3
4
5
6
7
8
9
10
11
12
public class Foo {
    void go() {}
}
 
public class Bar extends Foo [
    
    // Foo 클래스의 go() 메서드를 오버로딩 한 것이다.. 
    // 반환 타입이 달라도 상관이 없다 
    String go(int x) {
    return null;
}
 
cs

1
2
3
4
5
6
7
8
9
10
11
12
public class Foo {
    void go() {}
}
 
public class Bar extends Foo [
    
    // Foo 클래스의 go() 메서드를 오버라이딩 한 것이다. (인자 값이 같으므로)
    // 반환 타입이 다르면 안된다. 에러가 생길 것이다.
    String go( ) {
    return null;
}
 
cs



## 오버라이딩과 반환타입 


서브클래스에서 슈퍼클래스의 메서드를 오버라이딩할 때는 메서드 시그니처 ( 메서드 이름, 인자, 반환 타입) 이 정확히 같아야 한다.

jdk 1.5 이후에는 서브 클래스의 오버라이딩 메서드에 선언한 반환 타입이 슈퍼 클래스 메서드에서 반환 하는 타입의 서브 타입이라면 써도 된다.



1. 객체 참조 경우 null 반환 가능


2. 배열도 반환 가능


1
2
3
public String[] go() {
    return new String[] {"Fred""Barney""Wilma"};
}
cs


3. 기본값 반환 경우 메서드에서 선언한 반환 타입으로 묵시적 변환이 가능하면 다 가능


1
2
3
4
public int foo() {
    char c = 'c';
    return c;
}
cs

4. 3번 처럼 기본형 값을 반환하는 경우, 메서드에서 선언한 반환 타입으로 명시적 변환이 가능하다면 다 가능

1
2
3
4
public int foo() {
    float f = 32.5f;
    return (int) f;
}
cs


5. 반환 타입이 void 이면 아무 값도 변환할 수 없다.


6. 객체 참조를 반환하는 경우 메서드에서 선언한 반환 타입으로 묵시적 변환이 가능하다면, 다 가능


1
2
3
public Animal getAnimal(){
    return new Horse(); // Horse가 Animal의 서브클래스라면 가능
}
cs


7. 인터페이스를 반환 타입으로 선언한 메서드에서 그 인터페이스를 구현한 클래스의 객체를 반환할 수 있다.


public interface Chewable {   }

public class Gum implements Chewable {  }


public class TestChewable {

// 인터페이스를 반환 타입으로 하는 메서드

public Chewable getChewable() {

return new Gum(); // 반환 객체의 참조 타입은 Chewable 인터페이스로 업캐스팅됨

}

}


'Java 정리' 카테고리의 다른 글

가비지 컬렉션  (0) 2016.12.19
CH2_참조 변수 Casting  (0) 2016.06.16
오버라이딩과 오버로딩  (0) 2016.06.15
CH2_참조 변수 Casting
2016. 6. 16. 11:40 - Daybreak0_0

목표. 객체 참조의 캐스팅이 언제 필요한지 결정하고, 객체참조의 캐스팅에 관련되는 컴파일 에러와 런타임 에러를 파악한다.

.


1
2
3
4
class Animal {
    void makeNoise() {System.out.println("generic noise"); }
}
 
cs

1
2
3
4
5
class Dog extends Animal {
    void makeNoise() {System.out.println("bark"); }
    void playDead() {System.out.println("roll over");}
}
 
cs

1
2
3
4
5
6
7
8
9
10
11
class CastTest2 {
    public static void main(String[] args) {
        Animal[] a = {new Animal(), new Dog(), new Animal()};
        for(Animal animal : a){
            animal.makeNoise();
            if(animal instanceof Dog) {
                animal.playDead(); // Dog에만 있는 메서드 호출하려고함 
            }
        }
    }
}
cs


animal 참조변수를 통해서 Dog 클래스에만 있는 메서드를 호출하려고 하면? 


위의 코드에서는 컴파일 에러가 발생한다. 

"Animal 클래스에는 playDead() 메서드가 없어서 찾을 수 없다는 것" 


if(animal instanceof Dog) {

Dog d = (Dog) animal; // 참조 변수의 타입을 다운캐스팅한다.

d.playdead();

}


다운 캐스팅 하는 이유는? 

클래스 상속 구조의 아래쪽에 있는 서브 클래스의 메서드를 호출하기 위함

컴파일러에게 " Dog 객체를 참조하는 것이 확실하므로 참조 변수 타입을 Dog으로 하라" 라고 알려주는 것이다. 



if(animal instanceof Dog) {

Dog d = (Dog) animal; // 참조 변수의 타입을 다운캐스팅한다.

d.playdead();

}


이 코드를 쓰지 않고 바로 다운캐스팅하면? 


1
class Animal {  }
cs
1
class Dog extends Animal{  }
cs
1
2
3
4
5
6
class DogTest{  
    public static void main(String[] args){
        Animal animal = new Animal();
        Dog d = (Dog) animal; // 컴파일은 되지만 런타임 에러가 생긴다.
    }
}
cs

java.lang.ClassCastException 런타임 오류가 발생한다.

Dog도 Animal 타입의 한 종류인데 왜 animal 참조변수로 참조 할 수 없는 것인가?
컴파일할 때는 클래스 상속 구조를 참조하여 타입간의 관계만을 확인하므로, 다운캐스팅 코드가 정상적이지만,
실행 시에는 객체의 실제 타입을 기준하여 다운캐스팅하므로 런타임 에러가 발생한다. 
즉, 서브 클래스 객체는 슈퍼 클래스 타입이 될 수 있지만 슈퍼클래스 객체는 서브 클래스 타입이 될 수 없다.

## 정리

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package animal;
 
public class DogTest {
 
    public static void main(String[] args) {
        
        Animal animal = new Animal();
        // animal 참조변수를 Dog 타입으로 다운캐스팅 한다해도 실행 시에 객체의 실제 타입을 
        // 기준으로 다운캐스트하므로 런타임 에러가 발생한다.
        Dog d2 = (Dog) animal;
        d2.makeNoise();
        
        Dog d = new Dog();
        Animal a1 = d;
        Animal a2 = (Animal) d;
        // 런타임시 하위 클래스인 Dog의 메소드가 호출된다.
        // 참조 타입에는 자신의 타입클래스보다 상위 클래스만 올 수 있다.. 
        a1.makeNoise();
        a2.makeNoise();
        
        
    }
 
}
cs


런타임 오류

1
2
3
Exception in thread "main" java.lang.ClassCastException: animal.Animal cannot be cast to animal.Dog
    at animal.DogTest.main(DogTest.java:13)
 
cs


'Java 정리' 카테고리의 다른 글

가비지 컬렉션  (0) 2016.12.19
CH2_ 올바른 값의 반환  (0) 2016.06.16
오버라이딩과 오버로딩  (0) 2016.06.15
오버라이딩과 오버로딩
2016. 6. 15. 11:49 - Daybreak0_0

method overriding


1
2
3
4
5
public class Animal {
    public void eat() {
        System.out.println("Generic Animal Eating Generically");
    }
}
cs

1
2
3
4
5
class Horse extends Animal  {
    public void eat() {
        System.out.println("Horse eating hay, oats, " + "and horse treats");
    }
}
cs

- 슈퍼 클래스로부터 추상 메서드를 상속받은 실체 서브 클래스의 경우 그 메서드를 오버라이딩하여 실행할 코드를 구현해야 한다.
  그렇지 않으면 서브 클래스에서도 추상 메서드를 갖는 것이 되어 서브 클래스가 추상 클래스가 된다. 
  ** 추상 메서드는 반드시 오버라이딩 해야한다. 


- Animal의 모든 서브 클래스들은 각자 자신의 오버라이딩된 eat() 메서드를 가져야한다. 

- Animal 서브 클래스의 인스턴스를 슈퍼 클래스인 Animal 타입의 참조 변수로 참조하면, 그 참조를 통해 eat() 메서드를 호출했을 때,

  그 인스턴스가 속하는 서브 클래스의 eat() 메서드가 다형적으로 실행된다. 


1
2
3
4
5
6
7
8
class TestAnimals  {
    public static void main(String[] args) {
        Animal a = new Animal();
        Animal b = new Horse(); // Animal타입이지만 Horse 객체이다.
        a.eat(); // Animal의 eat()를 실행
        b.eat(); // Horse의 eat()을 실행
    }
}
cs


- Animal 타입의 참조를 통해서 Horse 객체의 메서드를 호출한다. 

- Animal 타입의 참조를 사용할 때는 Animal 클래스에 있는 메서드만 호출이 가능하다 ** 

- 컴파일러는 인스턴스 자신의 타입이 아닌 참조의 타입을 살피며, 런타임 시에는 인스턴스의 타입에 맞는 메서드가 다형적으로 실행된다.

  슈퍼 타입의 참조를 사용해서 그 슈퍼 타입의 서브 타입 인스턴스를 참조할 수 있다.

- 서브 클래스에서 오버라이딩된 메서드의 접근 변경자는 슈퍼 클래서 메서드의 접근 변경자보다 접근 범위가 같거나 더 넓어야 한다. (좁아질수 x)

  예, 슈퍼클래스의 메소드 접근 변경자가 public이면 서브 클래스에서 오버라이딩된 메서드의 접근 변경자를 protected로 할 수 x


## 오버라이딩한 메서드의 슈퍼 클래스 버전을 호출하고 싶다면?

- super 키워드 사용
- super 키워드는 인스턴스 메서드만 호출이 가능하다 (static 메서드는 오버라이드 할 수 없음)

## 오버라이딩을 잘못한 예

잘못 오버라이딩한 코드 

코드의 문제

private void eat() {   } 

슈퍼 클래스의 메서드보다 접근 변경자 범위가 좁다. 

public void eat( ) throws IOException {   } 

슈퍼 클래스 메서드에 선언하지 않은 checked 예외를 선언했다.

public void eat(String food) {  }

인자 목록이 다르므로 오버라이딩이 아닌 오버로딩이 되었다. 

public string eat( ) {   }

반환 타입이 다르므로 오버라이딩이 아니며, 인자 목록이 같으므로 오버로딩도 아니다. 



method overloading


- 하나의 클래스에서 같은 이름의 메서드들을 여러개 가질 수 있는데, 메서드 인자들은 달라야 한다. (반환타입은 같아도 되고 달라도 된다.)

- 인자들의 타입이나 개수가 다르면 컴파일러가 이름이 같더라도 알수 있기 때문이다. ==> 오버로딩된 메서드는 오버라이딩 메서드와 달리 실행할 메서드가 컴파일 시점에서 결정된다. 

- 인자의 타입이나 개수가 달라야 하지만, 타입과 개수가 같으면 순서만 달라도 된다.

- 오버로딩된 메서드들의 접근 변경자도 상관없다. (같든 다르든)


같아야 되는 것 

달라야 되는 것 

상관없음 

메서드 이름

인자의 타입 

반환 타입 

인자 개수

접근 변경자 

 

checked 예외



1
pubic void changeSize(int size, String name, float pattern) {  }
cs


1
2
3
public void changeSize(int size, String name) {  }
public int changeSize(int size, float pattern) {  }
public void changeSize(float pattern, String name) throws IOException {  }
cs





1
2
3
4
5
public class Animal {
    public void eat() {
        System.out.println("Generic Animal Eating Generically");
    }
}
cs

1
2
3
4
5
6
7
8
class Horse extends Animal  {
    public void eat() {
        System.out.println("Horse eating hay");
    }
    public void eat(String s) {
        System.out.println("Horse eating " + s);
    }
}
cs


## 오버로딩을 잘못한 예

오버로딩한 코드 

출력 결과

Animal a = new Animal(); 

a.eat();

Generic Animal Eating Generically

Horse h = new Horse(); 

h.eat(); 

Horse eating hay

Animal ah = new Horse(); 

ah.eat();

Horse eating hay

다형성이 구현된다.

- 참조 타입 (Animal)이 아닌

실제 객체 타입 (Horse)를 기준으로 메서드가 결정됨

Horse h3 = new Horse(); 

h3.eat("apples");

Horse eating hay

Animal a2 = new Animal();

a2.eat("apples");

컴파일 에러!

String을 받는 eat( ) 메서드가 Animal 클래스에 없다.

Animal a3 = new Horse();

a3.eat("Carrot");

컴파일 에러!
컴파일러는 참조 타입을 기준으로, 

String을 인자로 받는 eat() 메서드가 Animal 클래스에 있는지 찾는다. 없으므로 에러. 


## 오버라이딩과 오버로딩의 차이점


 

오버라이딩 

오버로딩 

 인자

반드시 같아야 한다.

반드시 달라야 한다. 

반환 타입

같아야 한다. 

같거나 다를 수 있다. 

예외

슈퍼 클래스의 오버라이딩되는 메서드에 선언한 예외보다 범위가 좁은 예외는 가능, 예외를 추가하거나 범위가 큰 예외를 선언할 수 없다. 

같거나 다를 수 있다. 

접근 변경자

범위가 더 좁은 접근 변경자를 지정할 수 없다. 

같거나 다를 수 있다. 

호출

해당 객체의 타입을 기준으로 런타임 시 결정 

참조 타입을 기준으로 컴파일 시에 결정 


'Java 정리' 카테고리의 다른 글

가비지 컬렉션  (0) 2016.12.19
CH2_ 올바른 값의 반환  (0) 2016.06.16
CH2_참조 변수 Casting  (0) 2016.06.16
[객체지향] 다형성
2016. 6. 14. 17:58 - Daybreak0_0

- 자바의 모든 클래스들은 기본적으로 Object 클래스로부터 상속받고 있으므로, Object 클래스와 IS-A- 관계가 설정되어있음

- 따라서, 자바의 모든 객체는 자신의 클래스 타입이면서 Object 타입이다.


객체에 접근하는 방법은 참조 변수를 통하는 것!! 


- 참조변수는 클래스나 인터페이스를 자신의 타입으로 선언할 수 있다. 참조 변수가 인터페이스 타입으로 선언되면, 그 인터페이스를 구현하는 어떤 클래스의 객체도 참조할 수 있다. 

- 자바는 다중 상속이 불가능하다. 


class PlayerPiece extends GameShape, Animatable {  }  // 불가능 !!


그렇다면?

클래스 대신 Animatable 인터페이스를 정의하고, 그것이 필요한 GameShape 서브 클래스에서만 그 인터페이스를 구현하도록 하면 된다.


public interface Animatable {

public void animate();

}


그리고 이 인터페이스를 구현하도록 수정한


class PlayerPiece extends GameShape implements Animatable {

public void movePiece() {

System.out.println("moving game piece");

}

pubic void animate() {

System.out.println("animation. ..");

}

     // ... 

}


PlayerPiece 객체는 언제든지 다음 4가지 형태로 다형적인 처리(상속받은 메서드의 실행을 다르게 하는)가 가능해진다.


  • Object 
  • GameShape
  • PlayerPiece
  • Animatable
따라서, PlayerPiece 객체 참조 변수는 다음과 같이 선언해도 문제가 없다.

PlayerPiece player = new PlayerPiece();
Object o = player;
GameShape shape = player;
Animatable mover = player;

객체는 PlayerPiece 하나만 있지만, 참조변수는 4 가지의 서로 다른 타입으로 되어있다. 
그리고 모든 참조 변수는 똑같은 객체를 참조한다. 그렇다면, 어떤 참조변수를 사용했을 때 displayShape() 메서드를 호출할까?
컴파일러가 허용하는 메서드 호출은 객체 자신의 타입과는 무관하게 참조 변수의 타입을 기준으로 한다.. 
GameShape이나 PlayerPiece 타입의 참조 변수를 이용해서 displayShape() 메서드를 호출할 수 있다.