08-06 다운 캐스팅과 instanceof

 

앞서 상속 관계를 가지는 구조에서 다형성을 활용하면 프로그램의 확장성이 높아진다는 것을 배웠다.

 

Animal ani = new Human()

 

상위 클래스로 묵시적으로 형 변환이 일어나는 것인데, 이 경우엔 Animal 클래스에서 선언한 메서드와 멤버 변수만 사용할 수 있다. 즉, Human 클래스에 더 많은 메서드와 멤버변수가 구현되어 있어도 사용할 수가 없는 것이다.

=> 다운캐스팅 ? 상위 클래스에서 형 변환되었던 하위클래스를 다시 원래 인스턴스의자료형으로 형변환하는 것 

(=downcating)

 

 

instanceof 예약어 ?

다운캐스팅 하기 전에 원래 인스턴스의 자료형을 확인해야 실행 오류를 막을 수 있다.

 

Animal hAnimal = new Human()

if(hAnimal instanceof Human) { 
	Human jm = (Human)hAnimal;
}

hAnimal의 원래 인스턴스형이 Human 클래스 자료형인가를 확인해줌.

instanceof의 반환값이 true면 다운 캐스팅을 함. 하위 클래스로 형변환을 할 때는 명시적으로 자료형을 작성해줘야 함.


"Do IT! 자바 프로그래밍 입문" 책을 읽고 요약하는 글입니다.

p.273~279

 

 

 

'CS 공부 > JAVA' 카테고리의 다른 글

[JAVA] 상속과 다형성 (2)  (0) 2023.07.14
[JAVA] 상속과 다형성 (1)  (0) 2023.06.26
이클립스 실행 오류...  (0) 2022.01.13
객체지향..ER다이어그램...  (0) 2021.02.21
5장 클래스 분리  (0) 2021.02.19

08-04 다형성

 

묵시적 클래스 형 변환과 가상 메서드를 사용한 객체지향의 주요 특징

= 하나의 코드가 여러 자료형으로 구현되어 실행되는 것

 

class Animal{ public void move() { "동물" 출력 }  }

class Tiger extends Animal { public void move() { "호랑이" 출력 } }

public class Test { .. public void moveAnimal(Animal animal) { animal.move() } }

가상 메서드 원리에 따라 호출되는 메서드는 자료형의 클래스의 메서드가 아니라 실제 인스턴스의 메서드다.

-> 어떤 매개변수가 넘어오더라도 자료형은 모두 Animal형으로 변환하지만, animal.move()는 실제 인스턴스에 따라 출력이 달라진다.

 

다형성의 장점? 

1) 프로그램의 확장성

2) 유지보수성

: 각 자료형에 따라 다르게 구현한다면 코드는 복잡해짐, 상위에서 공통 메서드 구현하고 하위에서 추가요소를 덧붙여 구현하면 각 클래스의 여러가지 구현도 할 수 있고(=확장성) 유지보수도 하기 쉬워짐

 

만약 재정의한 메서드가 가상 메서드 방식에 의해 자동으로 호출되지 않는다면 if-else if 문을 사용해서 따로 구현해야 할 것이다. 게다가 새로운 조건이 필요한 경우에는 또 다른 조건으로 구현해야 하기 때문에 코드의 유지보수가 어려워질 수 있따.

 

상속은 언제 사용할까?

IS-A (is a relationship; inheritance) : 일반적인 개념과 구체적인 개념

즉 일반 클래스를 점차 구체화하는(=확장되는) 상황에서 상속을 사용하는 것이다.

이질적인 클래스 간에는 상속을 사용하지 않는 것이 좋다

 

어떤 경우에 상속을 사용하지 말아야 할까?

HAS-A (has a relationship; association) : 한 클래스가 다른 클래스를 소유한 관계

예) Subject는 Student에 포함되는 것이기 때문에 상속을 사용해선 안됨

class Student { Subject majorSubject; }

 

알고가자!)  상속을 재사용의 개념으로 이해해선 안된다!

재사용할 수 있는 코드가 있다고 해서 무조건 상속을 하면 클래스 간의 결합도가 높아져서 오히려 상위 클래스의 변화가 하위 클래스에 미치는 영향이 커지게 된다. 결합도는 낮추고 응집도는 높이는 방향으로 소프트웨어는 설계되어야 함!

 

알고가자!)  여러 클래스를 한번에 상속받을 수는 없다. extends 뒤에는 상위 클래스 '하나만' 가능하다.

 

 


"Do IT! 자바 프로그래밍 입문" 책을 읽고 요약하는 글입니다.

p.259~272

 

'CS 공부 > JAVA' 카테고리의 다른 글

[JAVA] 상속과 다형성 (3)  (0) 2023.07.16
[JAVA] 상속과 다형성 (1)  (0) 2023.06.26
이클립스 실행 오류...  (0) 2022.01.13
객체지향..ER다이어그램...  (0) 2021.02.21
5장 클래스 분리  (0) 2021.02.19

08-01 상속이란?

B클래스가 A클래스를 상속받으면 B 클래스는 A 클래스의 멤버 변수와 메서드 사용 가능

-> 그 기반이 되는 기술이 '상속'

 

A 클래스: 부모, 상위 클래스

B클래스 : 자식, 하위 클래스

class B extends A { }

 

Customer 클래스와 VIPCustomer 클래스를 구현해본다고 하자.

VIPCustomer에게는 일반 고객에게 제공하는 혜택을 기본으로 하고 추가 속성과 메서드를 추가하면 됨.

public class VIPCustomer extends Customer {  }

 

Customer 클래스에서 사용한 변수인 customerGrade가 private으로 선언되어 있다면 protected로 바꾸자.

상위클래스에서 작성한 변수나 메서드 중 외부 클래스에서 사용할 순 없지만 항위 클래스에선 사용할 수 있도록 지정하는 예약어가 바로 protected ~!

그리고 get(), set() 메서드를 추가하자.

-> private 변수처럼 protected 변수도 외부 클래스에서 값을 가져올 수도, 지정할 수도 있게 된다.

 

 

08-02. 상속에서 클래스 생성과 형 변환

하위 클래스가 생성될 땐 상위 클래스의 생성자가 !반드시! 먼저 호출됨.

그리고 상위 클래스 생성자가 호출될 때 상위 클래스의 멤버변수가 힙 메모리에 생성되는 것임.

알고 가자!) 상위 클래스의 private 변수도 생성은 되지만 단지 하위 클래스에서 접근을 못하는 것일 뿐이다!

 

하위 클래스의 생성자에서 super()를 자동으로 호출하기 때문에 상위 클래스의 디폴트 생성자가 호출되는 것이다.

알고 가자!) super()는 컴파일러가 자동으로 추가하는 코드.

 

super로 상위클래스의 멤버변수나 메서드를 참조할 수도 있다.

super.showCustomerInfo()

 

상위클래스로 묵시적 형변환

Customer vc = new VIPCustomer()

VIPCustomer 클래스로 인스턴스를 생성할 때 이 인스턴스의 자료형을 Customer형으로 클래스형 변환하여 선언할 수 있음 = 업캐스팅(upcasting)

하지만, 클래스의 자료형이 Customer로 한정되어졌기 때문에 VIPCusotmer 클래스의 멤버변수와 메서드는 사용 불가능해짐.

만약 다시 사용하고 싶다면 VIPCustomer로 다운캐스팅(downcasting)하면 됨

 

알고가자!) 모든 하위 클래스는 상위 클래스 자료형으로 형 변환할 수 있지만, 그 역은 성립 불가

 

 

08-03. 메서드 오버라이딩

만약 '일반 고객은 정가를 그대로 지불하지만 VIP 고객은 10%할인은 받을 수 있다.' 는 가정이 생긴다면,

VIPCustomer에서 Customer 클래스의 calcPrice() 메서드를 그대로 사용할 수 없게 된다.

 

메서드 오버라이딩 : 상위 클래스에서 정의한 메서드가 하위 클래스에서 구현할 내용과 맞지 않을 경우 메서드를 재정의하는 것

 

알고가자!) 오버라이딩하려면 반환형, 메서드 이름, 매개변수 개수, 매개변수 자료형이 같아야 함

@Override

public int calcPrice(int price) { ... return price - (int)(price * 0.1)  }

 

 애노테이션 ? 컴파일러에게 특정한 정보를 제공해 주는 역할을 함, 만약 메서드의 선언부가 다르다면 컴파일 오류가 발생하여 개발자의 실수를 막아줌

예) @Override @FuntionalInterface @Deprecated @SuppressWarnings

 

가상 메서드 : 상속에서 상위 클래스와 하위 클래스에 같은 이름의 메서드가 존재할 때 호출되는 메서드는 인스턴스에 따라 결정됨.

선언한 클래스형 (x) 생성된 인스턴스 (o) 메서드를 호출

 

알고가자!) 인스턴스가 생성될 때마다 변수는 생성되지만, 메서드는 실행해야 할 명령 집합이므로 여러개 생성되지 않는다. 

일반적으로 메서드를 호출하면 '메서드 영역의 주소를 참조'하여 명령이 실행되는 것이다. 즉, 인스턴스가 달라도 동일한 메서드가 호출된다.

 

하지만 가상 메서드는 '가상 메서드 테이블'을 만든 후, 각 메서드 이름과 실제 메모리 주소가 짝을 이루고 있다가 테이블의 주소 값을 찾아서 해당 메서드의 명령을 호출하는 원리이다.

 

재정의된 메서드는 실제 인스턴스에 해당하는 메서드가 호출되고,

재정의되지 않은 메서드는 메서드 주소가 같으며 상위 클래스의 메서드가 호출된다.

 

// VIPCustomer 인스턴스를 Customer 형으로 변환
Customer vc = new VIPCustomer(10030, "나몰라", 2000)

=> 원래 Customer 형 메서드가 호출되는 것이 맞지만, 가상 메서드 방식에 의해 VIPCustomer 메서드가 호출된다!!


"Do IT! 자바 프로그래밍 입문" 책을 읽고 요약하는 글입니다.

p.232~258

'CS 공부 > JAVA' 카테고리의 다른 글

[JAVA] 상속과 다형성 (3)  (0) 2023.07.16
[JAVA] 상속과 다형성 (2)  (0) 2023.07.14
이클립스 실행 오류...  (0) 2022.01.13
객체지향..ER다이어그램...  (0) 2021.02.21
5장 클래스 분리  (0) 2021.02.19

https://blog.naver.com/winter6120/221000738717

 

[환경변수] JAVA_HOME/CLASSPATH/PATH/TOMCAT_HOME

* 환경 변수를 설정하는 이유 path는 파일이 있는 그 폴더가 아닌 다른 폴더에서 해당 폴더에 접근하기 위...

blog.naver.com

https://goodgid.github.io/Java-JDK-JRE/

 

JDK와 JRE의 차이점

Index

goodgid.github.io

 

어찌저찌 교수님 강의록이랑 구글링 해보면서 실행오류 해결하긴 함!

'CS 공부 > JAVA' 카테고리의 다른 글

[JAVA] 상속과 다형성 (2)  (0) 2023.07.14
[JAVA] 상속과 다형성 (1)  (0) 2023.06.26
객체지향..ER다이어그램...  (0) 2021.02.21
5장 클래스 분리  (0) 2021.02.19
5장 Mydate 예제  (0) 2021.02.19

6장 클래스와 객체2의 연습문제를 풀다보니 저번학기에 들은 데이터베이스 시간에 과제를 했던 게 생각났다. 제공된 요구사항을 바탕으로 ER다이어그램을 만드는 게 과제였는데 어떤 걸 엔티티로 해야 할지 관계로 짜야 할지 계속 고민하다가 눈물 날 뻔한 과제였다. 그래서 어찌어찌 내긴 했는데 교수님께서 올려주신 정답과는 다른 방식으로 짰다...

교수님께선 ER다이어그램을 짜는데엔 정답은 없다고 하셨지만 과연 내가 만든 게 효율적인 답안이었을진...

 

어쨌든 그 기억이 났다.

 

콩다방과 별다방을 클래스로 만들어야 하는 건 알겠는데

그다음부턴 어째야 할지 모르겠다

메뉴도 클래스로 만들고 해야하나

객체지향 프로그래밍... 어려운것....

그래도,,,,

뭔가....

재밌는 것,,,,

'CS 공부 > JAVA' 카테고리의 다른 글

[JAVA] 상속과 다형성 (2)  (0) 2023.07.14
[JAVA] 상속과 다형성 (1)  (0) 2023.06.26
이클립스 실행 오류...  (0) 2022.01.13
5장 클래스 분리  (0) 2021.02.19
5장 Mydate 예제  (0) 2021.02.19

Student 클래스

Student 생성자를 만들 때 그 안에 분리했던 Subject 클래스의 생성자도 추가해주어야 한다. (생성자는 클래스가 생성될 때 자동으로 호출된다)

그래야 Test에서 Park.math.Subjectname이나 Park.math.scorePoint를 선언할 수 있게 된다.

package ch5;

public class Student3 {
	int studentID;
	String studentName;
	Subject Korean;
	Subject math;
	
	public Student3() {
		Korean = new Subject("국어");
		math = new Subject("수학");
	}
	public Student3(int id, String name) {
		studentID = id;
		studentName = name;
		
		Korean = new Subject("국어");
		math = new Subject("수학");
	}
}

Subject 클래스

package ch5;

public class Subject {
	String SubjectName;
	int scorePoint;
	
	public Subject(String name) {
		SubjectName = name;
	}
}

Test 클래스

package ch5;

public class StudentTest {

	public static void main(String[] args) {
		Student3 Park = new Student3(201935, "박정미");
		Park.math.scorePoint = 50;
		System.out.println(Park.studentName);
		System.out.println(Park.math.SubjectName);
		System.out.println(Park.math.scorePoint);

		Student Jeong = new Student();
		Jeong.setStudentName("쩡미");
		System.out.println(Jeong.getStudentName());

	}

}

 

'CS 공부 > JAVA' 카테고리의 다른 글

[JAVA] 상속과 다형성 (2)  (0) 2023.07.14
[JAVA] 상속과 다형성 (1)  (0) 2023.06.26
이클립스 실행 오류...  (0) 2022.01.13
객체지향..ER다이어그램...  (0) 2021.02.21
5장 Mydate 예제  (0) 2021.02.19

Mydate 클래스

package ch5;
import java.util.Calendar;

public class Mydate {
	private int day;
	private int month;
	private int year;
	private boolean isValid = true;
	
	public Mydate(int day, int month, int year) {
		setYear(year);
		setMonth(month);
		setDay(day);
	}


	public int getDay() {
		return day;
	}

	public void setDay(int day) {
		switch(month) {
			case 1: case 3: case 5: case 7: case 8: case 10: case 12:
				if(day<1 || day>31) {
					isValid = false;
				}
				else {
					this.day = day;
				}
				break;
			
			case 4: case 6: case 9: case 11:
				if(day<1 || day>30) {
					isValid = false;
				}
				else {
					this.day = day;
				}
				break;
			
			case 2:
				if((year%4==0) && (year%100!=0) || (year%400==0)) {//윤년
					if(day<1 || day>29) {
						isValid = false;
					}
					else {
						this.day = day;
					}
				}
				else { //윤년아님
					if(day<1 || day>28) {
						isValid = false;
					}
					else {
						this.day = day;
					}
				}
				break;
			default:
				isValid = false;
		}
	}

	public int getMonth() {
		return month;
	}

	public void setMonth(int month) {
		if(month<1 || month>12) {
			isValid = false;
		}
		else {
			this.month = month;
		}
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		if(year > Calendar.getInstance().get(Calendar.YEAR)) {
			isValid = false;
		}
		else {
			this.year = year;
		}
	}
	
	public String isValid() {
		if(isValid == true) {
			return "유효한 날짜!";
		}
		else {
			return "유효하지 않은 날짜!";
		}
	}
	
}

MydateTest 클래스

package ch5;
import java.util.Calendar;
import java.util.Date;

public class MydateTest {
	public static void main(String[] args) {
		Mydate date1 = new Mydate(29,2,2021);
		System.out.println(date1.isValid());
		Mydate date2 = new Mydate(25,12,2020);
		System.out.println(date2.isValid());
	}
	
}

Calendar 클래스에 대해서 처음 배웠다.

- Date 클래스처럼 날짜와 시간에 관한 정보를 표현할 때 사용한다.

- 추상클래스이므로 객체를 직접 생성할 순 없지만 getInstance()메소드를 이용하여 시스템의 날짜와 시간 정보를 표현할 수 있다.

클래스의 주요 상수
클래스의 메소드

Calendar클래스는 추상 클래스로 생성자를 제공하지 않음.

따라서 Calendar 클래스의 객체를 생성하기 위해 new 연산자를 사용할 수 없다.

그대신 getInstance() 메소드를 사용하여 현재 날짜와 시간의 객체를 얻어올 수 있다.

 

Calendar.getInstance().get(Calendar.YEAR) => 현재연도를 알 수 있다.

 

출처: hyeonstorage.tistory.com/205

'CS 공부 > JAVA' 카테고리의 다른 글

[JAVA] 상속과 다형성 (2)  (0) 2023.07.14
[JAVA] 상속과 다형성 (1)  (0) 2023.06.26
이클립스 실행 오류...  (0) 2022.01.13
객체지향..ER다이어그램...  (0) 2021.02.21
5장 클래스 분리  (0) 2021.02.19

+ Recent posts