KDT/Java

231218 Java

001cloudid 2023. 12. 18. 12:55
728x90

다운 캐스팅 instanceof

package polymorphism;

 

import java.util.ArrayList;

 

//instanceof로 워래 인스턴스형 확인 후 다운 캐스팅

 

//상위 클래스 Animal

class Animal{

public void move() {

System.out.println("동물이 움직임");

}

}

 

//Animal을 상속받은 Human 클래스

class Human extends Animal{

public void move() {

System.out.println("사람이 두 발로 걷는다");

}

 

public void readBood() {

System.out.println("사람이 독서를 한다");

}

}

 

//Animal을 상속받은 Tiger 클래스

class Dog extends Animal{

public void move() {

System.out.println("개는 네 발로 뛴다");

}

 

public void hunting() {

System.out.println("개가 사냥을 한다");

}

}

 

//Animal을 상속받은 Brid 클래스

class Brid extends Animal{

public void move() {

System.out.println("새는 날개를 이용해 움직임");

}

 

public void flying() {

System.out.println("새가 하늘을 난다");

}

}

 

public class AnimalTest{

ArrayList<Animal> aniList = new ArrayList<Animal>();

public static void main(String[] args) {

AnimalTest aTest = new AnimalTest();

aTest.addAnimal();

System.out.println("다운 캐스팅");

aTest.testCasting();

}

 

public void addAnimal() {

aniList.add(new Human()); //ArrayList에 추가되면서 Animal형으로 형 변환

aniList.add(new Dog()); //ArrayList에 추가되면서 Animal형으로 형 변환

aniList.add(new Brid()); //ArrayList에 추가되면서 Animal형으로 형 변환

 

//배열 요소를 Animal형으로 꺼내서 move()를 호출하면 재정의된 함수가 호출됨

for(Animal ani : aniList) {

ani.move();

}

}

 

public void testCasting() {

for(int i = 0; i < aniList.size(); i++) { //무든 배열 요소를 하나씩 돌면서

Animal ani = aniList.get(i); //Animal형으로 가져옴

if(ani instanceof Human) {

Human h = (Human)ani;

h.readBood();

}

else if(ani instanceof Dog) {

Dog d = (Dog)ani;

d.hunting();

}

else if(ani instanceof Brid) {

Brid b = (Brid)ani;

b.flying();

}

else {

System.out.println("지원되지 않는 형");

}

}

}

}

그림 1. instanceof로 원래 인스턴스형 확인 후 다운 캐스팅하기

 

추상클래스

abstract class(추상 클래스) ↔ concrete class

 

추상 클래스는 항상 추상 메소드를 포함함. 추상 메소드는 구현 콛으가 없음. 즉 { } 안의 내용이 함수 몸체가 없다는 뜻

int add(int a, int b) {

return a + b;

}

{ } 안을 함수의 구현부(implementation)이라고 하며, 이 부분이 없는 함수는 추상 함수(abstract function)이고, 추상 메소드(abstract method)라고 함.

abstract int add(int a, int b);

추상 메소드는 위와 같이 선언만 하며 abstract 예약어를 사용함. 또한 { } 대신 ;를 사용

int add(int a, int b) {}

이는 추상 메소드가 아님. { }를 사용한 것만으로 메소드를 구현함 것, { } 안에 코드가 없을 뿐임

 

추상 클래스 구현

그림 2. 추상 클래스 구현하기 1

display()와 typing()은 추상 메서드이고, turnOn()과 turnOff()는 구현 코드가 있는 메소드.

public void display()와 public void typing() 완전하게 구현되지 않은 두 추상 메서드에서 오류가 발생함.

이를 해결하기 위해서는 몸체 부분을 작성하거나 이 메소드를 추상 메소드를 변경하는 방법이 있다.

 

그림 2. 추상 클래스 구현하기 2

메소드와 클래스 이름에 모두 오류가 표시되는데, 이는 추상 메소드가 속한 클래스를 추상 클래스로 선언하지 않았기 때문.

오류 메세지 내용은 메소드에서 abstract 예약어를 제거, Laptop 클래스를 추상 클래스로 생성하면 해결될 것이다.

 

그림 3. 추상 클래스 구현하기 3

클래스에 abstract 예약어를 추가해주면 오류가 없어진다.

 

그림 4. 추상클래스 상속

Laptop은 추상 클래스이며, 추상 클래스를 상속받은 클래스는 추상 클래스가 가진 메소드를 상속받음. 따라서 상속 받은 클래스는 추상 메소드를 포함함. 그렇기 때문에 추상 메소드를 모두 구현하거나 DeskTop도 추상 클래스로 만들어야함.

즉 추상 클래스를 상속 받은 하위 클래스는 구현되지 않은 추상 메소드를 모두 구현해야 구체적인 클래스가 됨.

 

그림 5. 추상 메소드 구현

추상 메소드의 몸체 코드 작성

 

그림 6. 클래스 구현 1

상속받은 추상 메소드를 모두 구현하지 않고 display() 하나만 구현함. NoteBook 클래스는 추상 메소드를 하나 가지고 있기 때문에 추상 클래스가 됨.

 

그림 7. 클래스 구현 2

MyNoteBook은 모든 추상 메소드가 구현된 클래스이므로 abstract 예약어를 사용하지 않음

 

추상 클래스를 만드는 이유

그림 9. 추상 클래스 테스트

Laptop 클래스형으로 인스턴스를 4개 생성(그림 8). Labtop과 NoteBook에서 오류가 발생함.

Labtop 클래스와 NoteBook 클래스를 인스턴스로 생성할 수 없다는 오류 때문이다.

 

이것으로 알 수 있는 사실은 추상 클래스는 인스턴스로 생성할 수 없다.

추상 클래스는 모든 메소드가 구현되지 않았으므로 인스턴스로 생성할 수 없다.

 

추상 클래스에서 구현하는 메소드는 하위 클래스에서도 사용할, 하위 클래스에서도 구현 내용을 공유할 메소드를 구현함.

실제 하위 클래스에서 내용을 각각 다르게 구현해야 한다면, 구현 내용을 추상 메소드로 남겨 두고 하위 클래스에 구현을 위임하는 것이다.

구현 메소드 : 하위 클래스에서 공통으로 사용할 구현 코드. 하위 클래스에서 재졍의할 수 있음

추상 메소드 : 하위 클래스가 어떤 클래스냐에 따라 구현 코드가 달라짐

 

final 예약어

변수, 메소드, 클래스에 사용할 수 있음.

final 변수는 상수를 의미, final 메소드는 하위 클래스에서 재정의 할 수 없음, final 클래스는 상속할 수 없음

 

final 변수

package final_;

 

public class Constant {

int num = 30;

final int NUM = 100; //상수 선언

 

public static void main(String[] args) {

Constant cons = new Constant();

cons.num = 50;

//cons.NUM = 101; 상수에 값을 대입하여 오류 발생

 

System.out.println(cons.num);

System.out.println(cons.NUM);

 

}

}

그림 10. final 변수

 

상수 예시와 사용결과

package final_;

 

public class Define {

public static final int MIN = 1;

public static final int MAX = 9999;

public static final int ENG = 101;

public static final int MATH = 201;

public static final double PI = 3.14;

public static final String JAVA = "JAVA";

}

package final_;

 

public class UsingDefine {

 

public static void main(String[] args) {

System.out.println(Define.JAVA);

System.out.println("최솟값은 " + Define.MIN);

System.out.println("최댓값은 " + Define.MAX);

System.out.println("수학 과목 코드값은 " + Define.MATH);

System.out.println("영어 과목 코드값은 " + Define.ENG);

}

}

그림 11. 상수 사용

 

728x90

'KDT > Java' 카테고리의 다른 글

231221 Java  (0) 2023.12.21
231220 Java  (0) 2023.12.20
231214 Java  (0) 2023.12.14
231213 Java  (0) 2023.12.13
231211 Java  (0) 2023.12.11