Java

[Java] 객체 지향 클래스 ( 객체 지향 언어의 특성 / 추상화(Abstractioin) / 다형성(polymorphism) / 인터페이스(Interface) / static 변수 )

소댓 2023. 3. 16. 23:32

* 객체 지향 언어의 네 가지 특성
1. 캡슐화(encapsulation) : 객체의 내부 구조 및 데이터를 캡슐처럼 감싸 외부에서 직접 볼 수 없게 은닉하여 보호하는 것
2. 상속(inheritance) : 어떤 클래스가 가지고 있는 메서드와 변수를 상속해서 다른 클래스가 갖도록 하는 것
3. 추상화(Abstraction) : 공통된 특징을 묶어 하나의 클래스로 정의해 상위의 개념을 만들어 냄
4. 다형성(polymorphism) : 동일한 조작방법으로 동작시키지만 대상에 따라 다른 실행하게 하는 것

 

 

[ 추상화 ]

 

* 추상화(Abstraction)

Rabbit, Monkey, Whale -> Mammalia

 

* 구체화

 Mammalia -> Rabbit, Monkey, Whale

 

- Mammalia에 토끼의 공통된 특성 적고, 토끼가 포유류를 상속 받도록

> 추상화 :  하위 클래스의 공통된 특성들을 끌어모아 상위 개념으로 가져와서 상속받아 쓰도록 하는 것

 

- 부모에게 상속받은 메서드를 내 맘에 들게 수정해서 쓰는 것 >> method overriding

 

- 부모의 메서드를 자식들이 다 수정(오버라이딩)해서 사용하면,
   메서드에 내용을 적지 않고 제목만 적어도 제대로 실행됨

 

- 하지만, 자식 클래스에서 메서드 내용을 새로 오버라이딩하지 않았다면? 
  제대로 결과가 나오지 않음
  따라서 아래처럼 abstract 메서드로 만들고 추상 클래스로 만듬

 

  abstract method : 아직 정해지지 않은 메서드 --> 미완성
  public abstract void eating();
  public abstract void sleeping();

 

- 따라서, 꼭! 메서드를 입력하라는 에러가 뜸

 

 

* 추상 메서드 

- 클래스는 설계도 역할, 추상 메서드는 상속을 목적으로 갖는 중간 개념적 클래스
- 추상 메서드는 미 구현 메서드로, 추상메서드가 1개라도 존재하면 그 클래스는 추상 클래스여야 한다.
- 추상메서드가 1개도 없는 추상 클래스가 될 수도 있다.

 

- 추상 클래스는 조감도 같은 역할이기 때문에
  아래처럼 실제로 인스턴스를 만들어 사용할 수 없음
  Mammalia m2 = new Mammalia();

  >> 추상 클래스는 인스턴스화 불가능

 

 

▶ Rabbit

 

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
package day11;
// Mammalia 상속받기
public class Rabbit extends Mammalia {
 
    // 상속 받은 걸로 쓰도록 하기 위해 생략
//    int eye, nose, mouth, ear;
//    String name;
//    String species;
 
    Rabbit () {
        eye = 2;
        nose = 1;
        mouth = 1;
        ear = 2;
        name = "흰둥이";
        species = "토끼";
    }
    
    // 상속받은 메서드 수정 (annotation > @Override)
    @Override
    public void eating() {
        System.out.println("당근 냠냠");
    }
    @Override
    public void sleeping() {
        System.out.println("풀 위에서 쿨쿨");
    }
    public void jumping() {
        System.out.println("깡총깡총");
    }
}
cs

 

 

▶ Monkey

 

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
package day11;
 
public class Monkey extends Mammalia {
 
    // 상속 받은 걸로 쓰도록 하기 위해 생략
//    int eye, nose, mouth, ear;
//    String name;
//    String species;
 
    Monkey () {
        eye = 2;
        nose = 1;
        mouth = 1;
        ear = 2;
        name = "끼끼";
        species = "원숭이";
    }
 
 
    // 상속받은 메서드 수정 (annotation > @Override)
    @Override
    public void eating() {
        System.out.println("바나나 냠냠");
    }
    @Override
    public void sleeping() {
        System.out.println("나무 위에서 쿨쿨");
    }
    public void climbing() {
        System.out.println("나무 위로 슝슝");
    }
    
}
cs

 

 

▶ Whale

 

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
package day11;
 
public class Whale extends Mammalia {
    // 상속 받은 걸로 쓰도록 하기 위해 생략
//    int eye, nose, mouth, ear;
//    String name;
//    String species;
 
    Whale () {
        eye = 2;
        nose = 1;
        mouth = 1;
        ear = 2;
        name = "고래고래";
        species = "흰수염고래";
    }
    
    // 상속받은 메서드 수정 (annotation > @Override)
    @Override
    public void eating() {
        System.out.println("새우 냠냠");
    }
    @Override
    public void sleeping() {
        System.out.println("바다에서 쿨쿨");
    }
    public void swimming() {
        System.out.println("어푸어푸");
    }
    
}
cs

 

 

▶ Mammalia : 추상화 클래스

 

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
package day11;
 
// 클래스는 설계도 역할
// 추상 클래스는 건물 조감도 역할
 
// 추상 메서드는 미 구현 메서드로
// 추상메서드가 1개라도 존재하면 그 클래스는 추상 클래스여야 한다.
// 추상메서드가 1개도 없는 추상 클래스가 될 수도 있다.
 
// 상속을 목적으로 갖는 중간 개념적 클래스
public abstract class Mammalia {
    
    // 토끼에서 공통된 특성 가져옴
    int eye, nose, mouth, ear;
    String name;
    String species;
    
    
 
    // 부모의 메서드를 자식들이 다 수정(오버라이딩)해서 사용하면,
    // 메서드에 내용을 적지 않고 제목만 적어도 제대로 실행됨
//    public void eating() {
////        System.out.println("당근 냠냠");
//    }
//    public void sleeping() {
////        System.out.println("풀 위에서 쿨쿨");
//    }
    
    // 하지만, 자식 클래스에서 메서드 내용을 새로 오버라이딩하지 않았다면? 
    // 제대로 결과가 나오지 않음
    // 따라서 아래처럼 abstract 메서드로 만들고 추상 클래스로 만듬
    
    // 아직 정해지지 않은 메서드 --> 미완성
    public abstract void eating();
    
    public abstract void sleeping();
 
}
cs

 

 

▶ Rabbit, Monkey, Whale (+ Horse) - Test

 

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
39
40
41
42
43
44
45
46
47
package day11;
 
public class TesstMain {
 
    public static void main(String[] args) {
        
        // 인스턴스화
        Rabbit r1 = new Rabbit();
 
        r1.eating();
        r1.sleeping();
        r1.jumping();
        
        System.out.println("----------------");
        
        Monkey m1 = new Monkey();
        
        m1.eating();
        m1.sleeping();
        m1.climbing();
        
        System.out.println("----------------");
        
        Whale w1 = new Whale();
        
        w1.eating();
        w1.sleeping();
        w1.swimming();
        
        System.out.println("----------------");
        
        Horse h1 = new Horse();
        h1.eating();
        h1.run();
        h1.sleeping();
        
        System.out.println("----------------");
        
        // 추상 클래스는 조감도 같은 역할이기 때문에
        // 아래처럼 실제로 인스턴스를 만들어 사용할 수 없음
        // 추상 클래스는 인스턴스화 불가능
//        Mammalia m2 = new Mammalia();
        
        
        
    }
}
cs

 

 


[ Interface(인터페이스) ]

 

- 두 개 이상의 클래스에서 상속 받을 때,

  메서드를 호출하면 누구 것을 상속 받은 것인지? >> 다이아몬드 상속

  but, 자바의 원칙 : 단일 상속

  >> 따라서, 인터페이스 이용!

 

Interface 인터페이스

  - 서로 관계가 없는 물체들이 상호작용을 하기 위해서 사용하는 장치나 시스템
    Interface는 추상 메서드와 상수만 가질 수 있다.

 

- 인터페이스도 부모 자식관계가 성립함 > 대부처럼 부모역할 가능

   그 대신, 인터페이스에 있는 메서드만 호출 가능

 

- 자바는 단일 상속만 지원하기 때문에 두 개의 클래스에서 상속 받는 식으로 할 수 있는 것

 

* 다형성
- 동일한 조작방법으로 동작시키지만 대상에 따라 다른 실행하게 하는 것

 

 

▶ Horse

 

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
package day11;
// Mammalia 상속받은 클래스
 
// Flayble이라는 인터페이스 구현 (상속처럼 사용됨)
// public class Horse extends Mammalia implements 인터페이스명, 인터페이스명 {
    
public class Horse extends Mammalia implements Flyable {
    
// 자바는 단일 상속만 지원하기 때문에 
// 아래와 같이 두 클래스에서 상속 받는 것은 불가
//public class Horse extends Mammalia, Flyable {
 
    // eating(), sleeping() 메서드는 
    // 반드시 override 가능하도록 강제하려면?
    // 포유류 클래스에 eating과 sleeping의 내용을 비우면 안됨
    // > 대신, 포유류의 eating과 sleeping을 abstract메서드로 만듬
    
    public void run() {
        System.out.println("달려라 히잉히잉");    
    }
 
    
    // 위처럼 추상 클래스를 상속 받았으니, 추상 메서드를 구현해야 사용 가능함
    public void eating() {
        System.out.println("각설탕 냠냠");
    }
 
    public void sleeping() {
        System.out.println("서서 쿨쿨");
    }
 
    @Override
    public void fly() {
        System.out.println("펄럭 펄럭 날아요");
    }
    
    
}
cs

 

 

▶ Marine

 

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package day11;
 
public class Marine extends Terran implements Flyable{
    // 클래스의 전역변수
    
    Marine() { 
        hp = 100;
        x = 0;
        y = 0;
        사거리 = 4;
        공격력 = 5;
        방어력 = 3;
        공격속도 = 3;
        이동속도 = 4;
        System.out.println("마린 기본생성자 호출");
        // return XXX
    }
    
    Marine(int hp, int x, int y) { // 체력 500짜리 마린
        // 기본 생성자를 실행하고와
        this(); // 항상 가장 첫번째 라인에 등장해야 한다.
        this.hp = hp;
        this.x = x;
        this.y = y;
        System.out.println("hp x y 생성자 호출");
    }
    
    Marine(int hp, int 공격력, int 공격속도, int 이동속도) {
        // 기본생성자를 호출한 후에 다른값을 대입
        this();
        this.hp = hp;
        this.공격력 = 공격력;
        this.공격속도 = 공격속도;
        this.이동속도 = 이동속도;
        System.out.println("hp 공격력 공격속도 이동속도 생성자 호출");
    }
    
    Marine(int hp, int x, int y, int 공격력, int 이동속도) {
        this(hp, x, y); // 생성자 중 int, int, int 매갭ㄴ수 생성자를 호출
//        this.hp = hp;
//        this.x = x;
//        this.y = y;
        this.공격력 = 공격력;
        this.이동속도 = 이동속도;
        System.out.println("hp x y 공격력 이동속도 생성자 호출");
    }
    
    void 공격하기() {
        System.out.println("뚜뚜뚜뚜뚜");
    }
    
    // Marine, Medic, SiegeTank 통틀어서 'Terran'
    // Terran x = 자식의 참조값 가능
    // Terran과 Terran의 모든 후손까지 가능
    void 공격하기(Terran x) {
        System.out.println("공격하기 메서드 내부 x : "+x);
        x.hp -= 공격력;
        System.out.println("적 캐릭터 공격!!!");
    }
    
//    void 공격하기(Marine x) {
//        System.out.println("공격하기 메서드 내부 x : "+x);
//        x.hp -= 공격력;
//        System.out.println("적 캐릭터 공격!!!");
//    }
//    
//    // 추가
//    void 공격하기(Medic x) {
//        System.out.println("공격하기 메서드 내부 x : "+x);
//        x.hp -= 공격력;
//        System.out.println("적 캐릭터 공격!!!");
//    }
//    
//    // 추가
//    void 공격하기(SiegeTank x) {
//        System.out.println("공격하기 메서드 내부 x : "+x);
//        x.hp -= 공격력;
//        System.out.println("적 캐릭터 공격!!!");
//    }
    
    void 스팀팩() {
        System.out.println();
        if(hp >3 ) {
        System.out.println("오우예~~~");
        hp -= 3;
        공격속도 += 2;
        이동속도 += 2;
    } else {
        System.out.println("체력이 부족합니다.");
    }
    }
 
    // implements 추가하고 오류가 생겼을 때,
    // 클래스 이름 더블 클릭 > add unimplemented method 하면 생성됨
    @Override
    public void fly() {
        System.out.println("슈웅슈웅~~");
        
    }
    
}
cs

 

 

▶ Flyable : 인터페이스

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package day11;
//여러 사물들에게 날 수 있는 능력 부여
 
// GUI : window
// CUI : linux
 
// Interface
// 서로 관계가 없는 물체들이 상호작용을 하기 위해서 사용하는 장치나 시스템
 
// Interface는 추상 메서드와 상수만 가질 수 있다.
public interface Flyable {
 
    // 추상 메서드 : abstract >  메서드 바디가 없음
    // public abstract void fly();
    public void fly();
    
}
 
cs

 

 

▶ Horse, Marine, Flyable(interface) - Test

 

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
39
40
41
42
43
44
45
46
47
48
package day11;
 
public class TestMain02 {
public static void main(String[] args) {
 
    // Horse 날 수 있도록
    Horse h1 = new Horse();
    h1.eating();
    h1.sleeping();
    h1.run();
    h1.fly();
    
    // Marine 날 수 있게
    System.out.println("------------------");
    // Marine, Terran 클래스를 현재 패키지로 복사해오기
    
    Marine m1 = new Marine();
    
    m1.이동하기();
    m1.fly();
    System.out.println("------------------");
    
    
    Flyable f;
    
    f = h1; // 인터페이스도 부모 자식관계가 성립하기 때문에 가능
    
    f.fly(); // Flyable 인터페이스에 있는 메서드만 호출 가능
             // 즉 부모가 아는 변수나 메서드만 사용 가능하다.
    
    System.out.println("------------------");
    
    f = m1;
    f.fly();
    
    // 다형성
    // 동일한 조작방법으로 동작시키지만 대상에 따라 다른 실행하게 하는 것
    
    // * 객체 지향 언어의 네 가지 특성
    // 1. 캡슐화(encapsulation)
    // 2. 상속(inheritance)
    // 3. 추상화(Abstraction) : 공통된 특징을 묶어 하나의 클래스로 정의하는 것
    // 4. 다형성(polymorphism) : 동일한 조작방법으로 동작시키지만 대상에 따라 다른 실행하게 하는 것
    
    
}
 
}
cs

 

 

 


 

* getter, setter

- 직접 접근 막으려면 변수를 private로 만듦

> 그 변수를 사용하려면 getter setter 활용

 

* Interface 활용

- Gun, AK47, SlingShot 의 공통 특성들을 모아서(fire, reload)

  Weapon interface 만들어서 Police에 구현

  > implements 하고 @Override

 

- 위처럼 Police에 구현하니, 참조값만 변화하면서 사용 가능

 

 

▶ Gun

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package day11;
 
public class Gun implements Weapon {
    int bullet;
    
    public Gun() {
        this.bullet = 6;
    }
    @Override
    public void fire() {
        if(bullet>0) {
        bullet --;
        System.out.println("빵!!");
        } else {
            System.out.println("틱,,");
        }
    }
    @Override
    public void reload() {
        System.out.println("재장전중...");
        bullet = 6;
    }
}
cs

 

 

▶ AK47

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package day11;
 
public class AK47 implements Weapon {
 
    @Override
    public void fire() {
        System.out.println("뚜뚜뚜뚜뚜");
    }
    @Override
    public void reload() {
        System.out.println("AK47: 재장전");
    }
        
}
cs

 

 

▶ SlingShot(새총)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package day11;
 
public class SlingShot implements Weapon {
    @Override
    public void fire() {
        System.out.println("새총 발사");
    }
    
    @Override
    public void reload() {
        System.out.println("돌멩이 주워오는 중");
    }
    
}
cs

 

 

▶ Weapon : Interface

 

1
2
3
4
5
6
7
8
9
10
11
package day11;
// AK47, Gun, SlingShot 모두 하나로 공통 특성 모아
// Weapon이라는 인터페이스 만듦
 
// Police 경찰이 이 Weapon 인터페이스를 구현
public interface Weapon {
 
    public void fire();
    public void reload();
    
}
cs

 

 

▶ Police

 

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package day11;
 
// A is a B : 상속 >> 이런 관계일 때는 상속의 관계 사용 가능
// ex. 토끼는 포유류
 
// A has a B : 포함 관계
// 경찰은 총이다. >> xxx
// 경찰은 총을 가지고 있다.
 
public class Police extends Gun implements Weapon {
    // private 로 직접 접근 차단, setter getter로 접근 가능
    private String name;
    private String rank;
 
    Weapon w; // interface 사용 --> setter getter 추가
    
    // Police에서 gun을 사용하게 하기 위해 추가
//    Gun g;
    // gun 대신 AK47 추가
//    AK47 ak;
    // 새총 추가
//    SlingShot ss;
    
    Police (){
        this.name = "포순이";
        this.rank = "순경";    
    }
 
    // 총기 지급
//    public Gun getG() {
//        return g;
//    }
//
//    public void setG(Gun g) {
//        this.g = g;
//    }
 
//    public AK47 getAk() {
//        return ak;
//    }
//
//    public void setAk(AK47 ak) {
//        this.ak = ak;
//    }
    
    // 새총으로 수정
//    public SlingShot getSs() {
//        return ss;
//    }
//
//    public void setSs(SlingShot ss) {
//        this.ss = ss;
//    }
//    
    // interface setter getter 추가
    public Weapon getW() {
        return w;
    }
 
    public void setW(Weapon w) {
        this.w = w;
    }
 
    public void use() { // w으로 수정
        if(w != null) {
            w.fire();
        } else {
            System.out.println("무기를 지급해주세요");
        }
    }
    
    public void reuse() { // w으로 수정
        if(w != null) {
            w.reload();
        } else {
            System.out.println("무기를 지급해주세요");
        }
    }
    
    public void eating() {
        System.out.println("도넛을 먹어요");
    }
    
    public void arrest() {
        System.out.println("당신은 묵비권을 행사할 수 있으며 ...");
    }
 
    // police 클래스에서 오른쪽 클릭 > 
    // source - generate getter setter
    
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getRank() {
        return rank;
    }
 
    public void setRank(String rank) {
        this.rank = rank;
    }
 
 
 
    
}
cs

 

 

 

▶ Weapon이라는 Interface를 활용한 Gun, AK47, SlingShot > Test

 

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
39
40
41
42
43
44
45
46
package day11;
 
public class TestMain03 {
 
    public static void main(String[] args) {
        
        Police p = new Police();
        
        // System.out.println(p.name);
        // getter, setter --> police 테이블에서 추가
        System.out.println(p.getName());
        
        p.eating();
        p.arrest();
        
        
        // 경찰이 총을 사용하게 하려면? > 경찰이 fire, reload 메서드 사용
        // police 클래스가 gun을 상속하도록
//        p.fire();
//        p.reload();
        // 상속은 부모로부터 메서드를 물려받고 맘에 안들면 오버라이딩 가능
        // 그러나, 부모 자식 관계는 끊기가 어려움 > 상속도 마찬가지
        // 메서드가 마음에 안들면 안쓸 수는 있지만 없앨 수는 없다.
        
        // A is a B : 상속
        // A has a B : 포함 관계
        
        // 따라서, 상속 대신 멤버변수로 불러서 사용.. 
        // police 클래스에서 Gun, use, reuse 추가하고,
        // gun에 대한 getter setter 추가
 
        System.out.println("----------------------");
        
        // 비상상황에서 총기 지급
        Gun g = new Gun();
        AK47 ak = new AK47();
        SlingShot ss = new SlingShot();
    
        p.setW(g); // 참조값 바뀔 때마다 발사되는 무기 달라짐
        
        p.use(); 
        p.reuse(); 
        
    }
    
}
cs

 

 


* 포인터

- 자바도 포인터가 있지만,

  임의로 조작하는 것은 불가. 잃어버리면 찾을 수 없음.

 

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 day11;
 
public class TestMain04 {
public static void main(String[] args) {
    
    Police p = null;
    
    System.out.println(p);
    
    // NullPointerException error
    // null이라서 heap으로 갈 수 없는 에러
//    System.out.println(p.getName()); 
    // 자바도 포인터가 있지만 임의로 조작하는 것은 불가, 잃어버리면 찾을 수 없음
    System.out.println("-------------------");
 
    p = new Police();
    
    System.out.println(p.getName());
    
    p = null;
    
 
}
}
cs

 

 


 

* STATIC 변수

 

- static String company;  > 결과가 삼성, 삼성으로 나옴
  > company가 heap에 만들어지지 않고 static area에 만들어짐 : static은 공용 변수!
   따라서, '사과' 다음에 '삼성'으로 답이 바뀐 것

 

- static 변수는 앞에 '클래스이름.' 붙히면 new 하기 전에도 사용 가능 => null

 

static area stack heap
company
(공용: 사과/삼성)
sp1
#100





sp2
#200
#100
company 사과





#200
company 삼성

 

- System.out.println("sp1은 SmartPhone 의 인스턴스 : " + (sp1 instanceof SmartPhone)); 
> instanceof : 연산자 -> 참인지 거짓인지 boolean으로 알려줌

- filed 자동 추가
  TestMain05의 필드 요소 추가
  (source - generate constructor using fields)

 

 

* 메서드의 종류

 

- public : 누구나 어디서든 접근 가능한
- static : 정적인(new-인스턴스화 하지 않고도 접근 가능)
- void : return값이 없는
- main : method 이름이 main
- (String[] args) : String 배열을 매개변수로 갖는 메서드 -> args 바꿀 수 있지만 관습적으로 사용

 

 

 

 

▶ SmartPhone 

 

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
39
40
41
42
43
44
45
46
47
package day11;
 
public class SmartPhone {
 
    String productName, nation, phoneNumber; // 인스턴스 변수 -> 변수 선언하면 heap에 생김    
    static String company; // static 변수
    // 결과가 삼성, 삼성으로 나옴
    // > company가 heap에 만들어지지 않고 static area에 만들어짐 : static은 공용 변수!
    // 따라서, '사과' 다음에 '삼성'으로 답이 바뀐 것
            
    int price;
    
    public SmartPhone () {}
    
    public void call() {
        System.out.println("띠리리리리~~~");
    }
    
    public void receive() {
        System.out.println("전화받으세요~~~~");
    }
    
    public void PlayGame() {
        System.out.println("뿅뿅~~~");
    }
 
    // TestMain05의 필드 요소 추가
    // source - generate constructor using fields
    public SmartPhone(String productName, String nation, String phoneNumber) {
        super();
        this.productName = productName;
        this.nation = nation;
        this.phoneNumber = phoneNumber;
    }
    
 
    public SmartPhone(String productName, String nation, String phoneNumber, String company, int price) {
        super();
        this.productName = productName;
        this.nation = nation;
        this.phoneNumber = phoneNumber;
        this.company = company;
        this.price = price;
    }
    
}
 
cs

 

 

▶ SmartPhone > Test

 

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
39
40
41
42
43
44
45
46
47
48
49
package day11;
 
public class TestMain05 {
 
    // public : 누구나 어디서든 접근 가능한
    // static : 정적인(new-인스턴스화 하지 않고도 접근 가능)
    // void : return값이 없는
    // main : method 이름이 main
    // (String[] args) : String 배열을 매개변수로 갖는 메서드 -> args 바꿀 수 있지만 관습적으로 사용
    
    
    public static void main(String[] args) {
        
        System.out.println(SmartPhone.company); 
        // static 변수는 앞에 '클래스이름.' 붙히면 new 하기 전에도 사용 가능 => null
        
        SmartPhone sp1 = 
                new SmartPhone("아이폰14""미국"
                        "010-1111-2222""사과"1500000);
        
        SmartPhone sp2 = 
                new SmartPhone("갤럭시23""한국"
                        "010-2222-3333""삼성"1500000); 
        
        // > company가 heap에 만들어지지 않고 static area에 만들어짐 : static은 공용 변수!
        // 따라서, '사과' 다음에 '삼성'으로 답이 바뀐 것
        
        System.out.println("sp1의 제조사 : " + sp1.company); // 삼성
        System.out.println("sp2의 제조사 : " + sp2.company); // 삼성
        
        System.out.println("sp1은 SmartPhone 의 인스턴스 : " + 
                                (sp1 instanceof SmartPhone)); // true
        // instanceof : 연산자 -> 참인지 거짓인지 boolean으로 알려줌
        
        sp1.company = "LG"// => static 변수는 공용이기 때문에 static의 company가 LG로 바뀜
        
        SmartPhone sp3 = new SmartPhone(); 
        // -> 생성자가 하나도 없을 경우에 ... 
        System.out.println("sp3의 제조사 : " + sp3.company);
        
        System.out.println("-------------------------------");
        
        // static method 모음... static method는 new 없이 사용 가능
        System.out.println(Math.PI); // static method
        System.out.println(Math.random()); // static method
        // printStart(); // static method
        
    }
}
cs

 

 

더보기

[ 응용 ]

 

10. 다음 ?? 에 적절한 단어를 채우세요

자바에서 상속받는 클래스를 서브 클래스(sub class) 라고 부르며, extends 키워드를

이용하여 상속을 선언한다. 상속받은 클래스에서 상속해준 클래스의 멤버를 접근할 때

super 키워드를 이용한다.

 

11. Animal 클래스를 작성한다.

 

조건1 : 멤버변수 name, age

조건2: eating(String name) : name을 먹어요 메세지 출력

sleeping() :

package day11;

public class Animal {

	String name;
	int age;
	
	Animal() {
		
	}
	
	public void eating(String name) {
		this.name = name;
		System.out.println(name+"을 먹어요");
	}
	
	public void sleeping() {
		System.out.println("쿨쿨");
	}

		
	}
 

 

12. Animal 클래스를 상속받은 Cat 클래스를 작성

조건1 : 멤버변수 : kind

조건2 : 다양한 매개변수있는 생성자를 작성한다.

 

package day11;
// Animal 클래스 상속 받은 Cat 클래스
public class Cat extends Animal {

	String kind;
	
	Cat(){
		name = "야옹이";
		kind = "코숏";
		age = 3;
	}
	
	@Override
	public void eating (String name) {
		System.out.println(name+"얌얌");
	}
	
	@Override
	public void sleeping () {
		System.out.println("Zzz");
	}
	
	public void dancing () {
		System.out.println("Dancing~~~ cat");
	}
	
	public static void main(String[] args) {
		Cat c1 = new Cat();
		
		c1.eating("생선");
		c1.dancing();
		
	}
}