@지난 시간 복습
1) static 변수는 메서드 안에 못쓴다. static 변수는 클래스영역에만 사용가능하다.
2) 동일한 클래스에 다른메서드를 호출하려면 꼭 메서드를 만들어 메서드 안에만 다른 메서드를 호출할 수 있다.
클래스영역에 바로 메서드 호출 시 오류가 먹는다.
3) 부모에 매개변수 가있는 생성자가 있는데 default 생성자를 만들어주지 않은 경우에는 상속받고 있는 자식클래스를 만 들어주면 오류가 먹는다.
(매개변수가 있는 생성자 만들 시 default 생성자를 꼭 만들어주는 게 좋다.)
4) 문자 + 숫자시 = 문자형태가 되는 거는 문자가 숫자보다 크기가 크기 때문이다.
( int -> long -> float -> double 자료형의 크기별로 나타낸 것이다. long 형안에 int형 쓸 수 있고 , float 안에 long, int형 을 쓸수 있는 것도 같은 맥략이다.)
5) bolean의 기본값은 false이다.
6) int형의 변수나, String형의 변수나 이식에 어떤 값을 추가해 주는 거면 해당 변수에 초기값을 설정해줘야 한다.
(int a = 0; , String list = ""; 이렇게 설정해 주는 게 좋다.)
※JAVA - 다형성
1. 객체지향 언어에서도 중요한 부분에 속합니다.
조상타입의 참조변수로 자손타입의 인스턴스(객체)를 다룸
ex) Tv tv = new SmartTv(); // Tv 부모, SmartTv 자식클래스
2. 다형성 장점
1) 유지보수: 여러 객체들을 하나의 타입으로 관리할 수 있기 때문에 유지보수가 편하다.
2) 재사용성: 객체의 재사용이 쉽다.
3) 느슨한 결합: 클래스 간의 의존성을 줄여서 확장성은 높이고 결합도는 낮춘다.
3. 업캐스팅이란?
1) 부모타입변경, 자식클래스의 필드나 메서드는 못쓰고 부모클래스에 있는 메서드나 필드만 출력가능하다.
-> Unit :부모클래스, Ani :자식클래스
Unit u = (Unit) new Ani(); -> Ani라는 자식객체를 Unit의 부모타입으로 참조변수 u에 적용한 것이다.
2) 업캐스팅 하는 이유: 상속관계에서 상속받은 서브클래스가 몇 개이든 간에 하나의 인스턴스 타입(부모타입)으로 묶 어서 관리할 수 있기 때문이다.
4. 다운캐스팅이란?
1) 업캐스팅한 자식클래스를 복구하는 개념이다. 원래 자식클래스의 필드와 기능을 회복하는 것이다.
2) 다운캐스팅 하게 되면 부모에 있는 필드나 메서드는 물론 , 자식클래스에 있는 필드나 메서드도 같이 쓸 수 있다.
5. instanceof 연산자
객체에 대한 클래스(참조형) 타입에만 사용할 수 있고 true , false를 반환해 준다.
(int, double 같은 기본형 타입은 사용불가능하다.)
※다형성 기본예제 1
class Tv {
int volumn;
int channel;
boolean power; //초기값 false
void power() {
power = !power; // true
System.out.println(power?"Tv 켜짐":"Tv 꺼짐"); //power->true 이니 참이된다.
}
void channelUp() {
channel+=1;
}
void channelDown() {
channel-=1;
}
void volumnUp() {
volumn+=1;
}
void volumnDown() {
volumn-=1;
}
} //Tv클래스 끝
class SmartTv extends Tv {
boolean ottPower; //SmartTv에만 있는 변수; false
void ott() {
ottPower=!ottPower; // true
System.out.println(power?"Tv 켜짐":"Tv 꺼짐");
System.out.println(ottPower?"OTT 켜짐":"OTT 꺼짐");
}
void power() {
power = !power; //부모의 Tvㄹ부터 상속받은 변수; true
ott();
}
} //SmartTv 클래스 끝
class RollableTv extends Tv {
boolean rolling;
void rolling() {
rolling=!rolling;
if(rolling) System.out.println("화면 펼침");
else System.out.println("화면 말려들어가짐");
}
void volumnUp() {
volumn+=2;
}
void volumnDown() {
volumn-=2;
}
}RollableTv클래스 끝
public class Ex25_1_다형성 {
public static void main(String[] args) {
// 다형성
Tv stv = new SmartTv(); // 다형성인 경우 SmartTv로 인스턴스를 생성했더라도 Tv 한테 있는 멤버들만 사용 가능
System.out.println(stv.power);
stv.power();
System.out.println(stv.power);
System.out.println("====================");
Tv rtv = new RollableTv();
System.out.println(rtv.volumn);
rtv.volumnUp();
System.out.println(rtv.volumn);
}
}
1) Tv stv = new SmartTv(); // 다형성인 경우 SmartTv로 인스턴스를 생성했더라도 Tv 한테 있는 멤버들만 사용 가능
System.out.println(stv.power);
stv.power();
System.out.println(stv.power);
-> 이렇게 자식클래스 객체를 부모클래스타입으로 설정한 경우 변수의 값이 같아도 부모 타입의 변수의 값을 가져와 쓰게 되고, 메서드는 오버라이딩된 자식클래스의 메서드를 재정의해 쓰게 된다.
// 다형성
Tv stv = new SmartTv(); // 다형성인 경우 SmartTv로 인스턴스를 생성했더라도 Tv 한테 있는 멤버들만 사용 가능
System.out.println(stv.power); //결과값: false 자식에 새롭게 변수가 지정된것이고 그초기값은 false이다
stv.power(); //결과값: TV켜짐, OTT켜짐
System.out.println(stv.power); //결과값: true ,위에 stv.power()실행시 power변수가 true로 바뀐다.
System.out.println("====================");
※다형성 기본예제 2
class Parent {
int x = 100;
void method(){
System.out.println("부모 메서드");
}
}
class Child extends Parent{
int x = 200;
void method(){
System.out.println("자식 메서드");
}
}
public class Ex25_2_다형성2 {
public static void main(String[] args) {
Parent p = new Child(); //타입이 Parent인 Child 인스턴스를 생성 -> Child에 있는 멤버중에 Parent클래스(타입)에 있는 멤버위주로만 쓸수있는것이다.
Child c =new Child(); //타입이 Child인 Child 인스턴스를 생성
/* Parent 참조변수 */
System.out.println(p.x); //p꺼의 변수 x - 상속받는 클래스중에 같은 이름의변수는 앞에 타입에 따라 달리 출력이된다
p.method(); //Child 꺼의 메서드 method 출력됨
System.out.println("==================");
/* Child(본인) 참조변수 */
System.out.println(c.x); //타입이 Child 니까 Child 에 있는 x변수가 출력이된다.
c.method(); //Child 꺼의 메서드 method 출력됨
}
}
1) Child 인스턴스를 생성하더라도 멤버변수는 원래 꺼가 출력됨.
-> 상속받는 클래스중에 같은 이름의 변수는 앞에 타입에 따라 달리 출력이 된다
-> 타입에 있는 변수가 뽑아진다 , 오버라이드 된 메서드 타입이 아니라 인스턴스화한 객체의 클래스에 메서드값이 출 력 됨.
2) 상속된 다형성인 경우, 메서드는 new 한 객체껄 가져오고, 변수는 참조한 타입의 클래스 걸 가져온다.
method는 오버라이드 된다.
※다형성 기본예제 3
- 시나리오 -
-> 커피 구매 애플리케이션 제작한다 치고
그냥 코드를 짜게 되면 각 메뉴마다 가격이나 이름 같은 정보들이 다 다르기 때문에 각 메뉴마다 구매하는 메서드를 구 현해야 한다.
그런데 다형성을 이용하면 개별적인 커피의 구매 메서드를 따로 구현하지 않아도 된다.(그냥 한방에 모든 메뉴를 구매 할 수 있는 기능 만들 수 있음)
상위 클래스 Coffee의 자료형을 매개변수로 전달받으면, 하위 클래스 타입의 참조변수는 매개변수로 전달될 수 있다.
class Coffee {
int price;
public Coffee(int price) {
this.price = price;
}
}
class Americano extends Coffee {
public Americano(int price) {
super(price);
}
@Override
public String toString() {
return "아메리카노";
}
}
class Latte extends Coffee {
public Latte(int price) {
super(price);
}
@Override
public String toString() {
return "라떼";
}
}
class Afogatou extends Coffee {
public Afogatou(int price) {
super(price);
}
@Override
public String toString() {
return "아포가토";
}
}
class Customer {
int money = 10000;
int sum=0;
String list = "";
// 커피 구매 하는 메서드
void buyCoffee(Coffee a) {
if(money < a.price) {
System.out.println("잔액이 부족합니다.");
return;
}
money -= a.price;
System.out.println(a+"를 구매하셨습니다.");
// 구매한 물픔 총 합
sum += a.price;
// 구매한 물품 이름
list += a+", ";
}
void summary() {
// int sum=0;
System.out.println("구매하신 물품은 "+list.lastIndexOf("메")+" 입니다.");
System.out.println("구매하신 물품의 총 금액은 "+sum+" 입니다.");
System.out.println("구매하신 물품은 "+list.substring(0, list.length()-2)+" 입니다.");
////라떼, 아메리카노,
}
}
public class Ex25_3_다형성예제 {
public static void main(String[] args) {
Customer c1 = new Customer();
c1.buyCoffee(new Latte(3900)); // 3900
c1.buyCoffee(new Americano(1900)); // 1900
c1.buyCoffee(new Afogatou(5000)); // 3900
c1.summary();
Customer c2 = new Customer();
1) 커피구매할 때 다형성활용
-> 아래는 메서드를 매개변수에 각각의 타입에 해당인스턴스를 만드는 코드이다.
이렇게 각각의 타입으로 관리하면 유지보수나, 재사용성이 좋지 못할 것이다.
void buyCoffee(Americano a) { // 아메리카노
money = money - a.price;
}
void buyCoffee(Latte a) { // 아메리카노
money = money - a.price;
}
void buyCoffee(Afogatou a) { // 아메리카노
money = money - a.price;
}
2) 커피구매할 때 다형성활용 - 업캐스팅
-> 이렇게 상속관계에서 하나의 부모로부터 상속받는다면 해당 인스턴스의 객체들을 부모클래스 타입으로 명시하게 되면
하나의 타입으로 여러 인스턴스를 참조할 수 있을 것이다.
그래서 메서드를 활용해 이 타입에 들어가는 자식인스턴스들을 생성해 한방에 모든 메뉴들을 구매할 수 있게 될 것이다.
(유지보수, 재사용성 이 용이하게 된다.)
void buyCoffee(Coffee a) {
if(money < a.price) {
System.out.println("잔액이 부족합니다.");
return;
}
money -= a.price;
System.out.println(a+"를 구매하셨습니다.");
}
3) 구매한 물품들의 총합, 구매한 물품이름 출력코드
void buyCoffee(Coffee a) {
if(money < a.price) {
System.out.println("잔액이 부족합니다.");
return;
}
money -= a.price;
System.out.println(a+"를 구매하셨습니다.");
// 구매한 물픔 총 합
sum += a.price;
// 구매한 물품 이름
list += a+", ";
}
void summary() {
// int sum=0;
System.out.println("구매하신 물품은 "+list.lastIndexOf("메")+" 입니다.");
System.out.println("구매하신 물품의 총 금액은 "+sum+" 입니다.");
System.out.println("구매하신 물품은 "+list.substring(0, list.length()-2)+" 입니다.");
////라떼, 아메리카노,
}
-> buyCoffee 메서드를 활용해 Coffee 타입에 자식클래스들을 인스턴스화해서 가격과, tostring으로 각자의 이름들을 반환하게 하고, 그 인스턴스의 가격을 sum이라는 변수에 합쳐놓고, 그 인스턴스의 return 한 반환이름들을 list에 문자형으로 저장하게 되면 , 이 sum과 list라는 변수들로 총금액과, 구매한 물품명을 출력하는 메서드를 만들 수 있을 것이다.
단, sum이나 list는 해당 클래스영역에 선언을 해놓고 써야지 2개의 메서드에 오고 가면서 사용할 수 있을 것이다.
'국비교육' 카테고리의 다른 글
국비지원 62일차(JAVA - 예외처리,내장클래스(내장메서드)) (2) | 2023.10.20 |
---|---|
국비지원 61일차(JAVA - 추상클래스, 인터페이스) (1) | 2023.10.19 |
국비지원 59일차 (JAVA - 접근제어자, 캡슐화) (1) | 2023.10.17 |
국비지원 58일차(JAVA - 오버로딩,생성자,상속) (2) | 2023.10.16 |
국비지원 57일차(JAVA - 변수, 메서드) (2) | 2023.10.14 |