어제 상속 , 생성자 부분 문제 하나만 풀고 시작
=
* 원(Circle) 클래스 구현하기
* 1. 멤버변수
* 반지름(r),x좌표(x),y좌표(y), 원의번호(no)
* 원의번호 생성 변수 count
* 2. 생성자 : 구동 클래스에 맞도록 설정하기
* 3. 멤버메서드
* (1) double area() : 원의 넓이 리턴. Math.PI 상수 사용
* (2) double length(): 원의 둘레 리턴. Math.PI 상수 사용
* (3) void move(int a, int b): x,y좌표를 x+a, y+b로 이동.
* (4) void scale(double m): 반지름을 m배 확대/축소. r=r*m
* (5) String toString() :
* 1번원 : 반지름:10, 좌표:(10,10), 넓이:314.xxx, 둘레:xxx.xxx
=
package test;
public class Test4 {
public static void main(String[] args) {
Circle[] carr=new Circle[3];
carr[0] = new Circle(10,10,10); //r x y
carr[1] = new Circle(20,20); // x y 반지름:1
carr[2] = new Circle(100); //r (x,y)==0,0
for(Circle c : carr) {
System.out.println(c);
c.move(10,10);
System.out.println(c);
c.scale(3);
System.out.println(c);
}
}
}
class Circle{
int r,x,y,no;
static int count;
public Circle(int r,int x , int y) {
this.r = r;
this.x = x;
this.y =y;
no+= ++count;
//모든 생성자는 이 생성자를 다 호출하므로
//객체 생성할때 마다 원의개수를 하나늘려준다
}
double area() {
return Math.PI*r*r; }
double length() {
return 2*Math.PI*r;}
public Circle(int x, int y) {
this(1, x, y);}
public Circle(int r) {
this(r,0,0);}
void move(int a , int b) {
this.x=this.x+a;
this.y=this.y+b;}
void scale(int a) {
r = r*a;}
public String toString() {
return String.format("%3d번 원 반지름 : %3d , 좌표 : (%3d,%3d), \n"
+ " 넓이 : %10.3f , 둘레 : %10.3f \n", no,r,x,y,area(),length());
}
// public String toString() {
// return no+"번 원 :"+
// "반지름 : "+r+" 좌표:("+x+","+y+")"+
// "\n넓이 : "+String.format("%.3f", area())+
// " 둘레 : "+String.format("%.3f", length());
// }
}
toString 부분에 주목하자 저런식으로
String.format을 사용해
소수점자리를 제한해 출력이가능하다
super
public String toString() {
return type+": 이름 = "+name+", 주소 = "+address;}
자식
public String toString() {
return super.toString()+
",부서 : "+dept+" 계약만료일 : "+week+","+date;}
이런식으로 부모에 toString을 구현했다면
자식이 부모의 toString방식을 그대로 받아서 더해줄 수 있음.
1) 상속
1-1) super
1-2) 오버라이딩
1-3 ) 다형성
1-4) 상속활용 예제
1-5) 추상클래스
1-6) final 제어자
1- 7) 예제
@@@ 1) 상속 @@@
1-1) super
* super 예약어
* super() 생성자
* --부모클래스의 생성자 호출 . 코드 첫줄에 구현해야함(this와 같음)
* -- 부모클래스의 생성자 중 매개변수 없는 생성자가 있다면(기본생성자)
* super(); 생략가능
* -- 부모클래스의 생성자 중 매개변수 없는 생성자가 없으면 super(부모클래스의 매개변수타입)
* 으로 호출해야함 . @@생략불가!!
*
*super 참조변수 : 부모클래스의 객체를 참조하는 참조변수
예시
package ex2_super;
public class Parent {
int x=10;
public Parent(int x) {
this.x=x;
}}
package ex2_super;
public class Child extends Parent {
int x = 20;
public Child() {
super(100);
//부모의 생성자는 무조건 호출해야함
//기본생성자일 경우는 선언 생략해도 자동출력
//super(); 자동호출
}
void method() {
int x = 30;
System.out.println("x = "+x);
System.out.println("this.x : "+this.x);
System.out.println("super.x : "+ super.x);
}}
여기서 super(100) 과 같이 부모의 생성자를 호출하고싶지않다면
꼭!!!! 부모에 생성자 중 하나라도 매개변수가 없는 생성자(기본생성자)가 존재해야함
or 생성자가 없어야함
실행코드
package ex2_super;
public class SuperEx1 {
public static void main(String[] args) {
Child child = new Child();
child.method();
}}
x = 30
this.x : 20
super.x : 100
( 자식은 부모를 통쨰로 상속받음)
1) Child의 method안의 지역변수인 int x=30;을
주석처리해본다면 x = 20(this.x)가 출력될것이고
자식의 멤버변수 x=20을 주석처리하고
실행해보면
this.x = 100 이 출력될거다
1- 2) 오버라이딩
* -상속관계에서 나타남
* - 부모클래스의 메서드를 자손클래스에서 재정의 . (메서드의재정의)
* -부모클래스의 메서드의 선언부와 자손클래스의 메서드의선언부가 같아야함.
(아예 똑같은 메서드여야 한단 뜻) 매개변수가다르거나 타입이 다르면 안됨
단, 접근제어자는 넓은 범위로가능 . 예외처리는 좁은범위로 가능
예시
public class Bike {
int wheel;
Bike(int wheel){
this.wheel = wheel;
}
String drive() {
return "패달을 밟아";
}
String stop() {
return "브레이크를 잡아";
}
}
class AutoBike extends Bike{
private boolean power;
AutoBike(int wheel) {
super(wheel);
}
@Override
//부모의기능을 자식이 쓸 수 없을 떄 사용함(오버라이딩)
String drive() {
if(power==true) {
return "출발버튼 on";}
else {return "시동켜줘";}
}
void power() {
power = !power;
if(power == true)
System.out.println("시동을 켭니다");
else {System.out.println("시동을끕니다");}
}
}
AutoBike는 페달이없기때문에
부모의 drive 메서드를 재정의해
자신만의 메서드로 다시 만들었다 (override)
이 때 매개변수라던지 타입이 바뀌어선 안된다
메인코드
public class OverrdingEx1 {
public static void main(String[] args) {
AutoBike autoBike = new AutoBike(10);
autoBike.power();
System.out.println(autoBike.drive());
System.out.println(autoBike.stop());
System.out.println();
Bike bike = new Bike(2);
System.out.println(bike.drive());
System.out.println(bike.stop());
}}
시동을 켭니다
출발버튼 on
브레이크를 잡아
패달을 밟아
브레이크를 잡아
오버라이딩과 오버로딩의 차이
1-3) 다형성
* 1 . 자손타입의 객체를 부모타입의 참조변수로 참조가 가능 : 다형성 (반대는 성립X)
* 2 . 부모타입의 참조변수로 자손타입의 객체를 참조하는경우
같은 멤버인경우
변수 : 참조변수 타입을 따라감
메서드 : 객체의 최종 오버라이딩 된 메서드
*3. 모든클래스의 객체는 Object 의 참조변수로 형변환 가능함!! Object o = xx;
*4. 모든클래스의 객체는 Object 참조변수로 참조가 가능.
부모와 자식의 멤버변수가 같은 경우
package ex4_binding;
class Parent{
int x = 10;
void method() {
System.out.println("Parent 쿨래스의 method");
}
}
class Child extends Parent{
int x = 20;
@Override
void method() {
super.method();
System.out.println("Child클래스의 method");
System.out.println("x = "+x);
System.out.println("this.x : "+this.x);
System.out.println("super.x : "+super.x);
}
}
public class BindingEx1 {
public static void main(String[] args) {
Parent p = new Child(); // 부모는 자식객체 참조가 가능(부모는 자식을 담을 수 있음)
System.out.println(p.x);//참조변수 타입을 따라감 p == Parent 참조변수
p.method(); //객체의 오버라이딩 된 메서드를 호출함
System.out.println();
Child c = (Child)p;//자식 <- 부모 (강제형변환 필요)
System.out.println(c.x);// c == child
c.method();
Object o = p;//부모 <- 자식 : 자동형변환
}
}
10
Parent 쿨래스의 method
Child클래스의 method
x = 20
this.x : 20
super.x : 10
20
Parent 쿨래스의 method
Child클래스의 method
x = 20
this.x : 20
super.x : 10
부모와 자식 간의 멤버변수가 다른 경우
* 1. 부모타입의 참조변수로 자손타입의 객체는 참조 가능
* 2. 부모타입의 멤버와 자손타입의 멤버가 다를경우
- 부모타입의 참조변수로 자식타입의 객체를 참조 시 , 부모타입의 멤버만호출가능
ex) Parent p = new Child()
- 자식타입의 참조변수로 자식타입의 객체를 참조 시(부모객체를 참조 하진 못함) , 부모의 멤버도 호출이가능
ex) Child c = new Child()
* 3. 모든클래스의 객체는 Object 타입의 참조변수로 참조가 가능.
Object 타입으로 참조된 객체는 Object 멤버만 호출이가능함 ex) toString, equals 등
package ex4_binding;
class Bike{
int wheel;
Bike(int wheel){
this.wheel = wheel;}
String drive() {
return "패달을 밟아";}
String stop() {
return "브레이크를 잡아";}
}
class AutoBike extends Bike{
boolean power;
AutoBike(int wheel) {
super(wheel);}
void power() {
power = !power;}
}
public class BindingEx2 {
public static void main(String[] args) {
AutoBike ab = new AutoBike(2);
System.out.println("바퀴 수 : "+ab.wheel);
ab.power();
ab.drive();
ab.stop();
Bike b = ab; // 부모 <- 자식 : 자동형변환
System.out.println("바퀴 수 : "+b.wheel);
// b.power();
b.drive();
b.stop();
Object o =b;
// o.power();
// o.drive();
// o.stop();
}
}
부모는 자식을 가지고있지않기 때문에
b(부모타입의 참조변수) 는 자식의 메서드인 power를 사용할 수 없다;
ab (AutoBike) |
b (Bike) |
o(object) | object [ Object 의 멤버 ] |
x | 2 ( wheel), drive() , stop() [ 부모의 멤버] |
||
x | power, power() [자식의 멤버 (부모엔없음)] |
Bike b = new Bike(2);
AutoBike ab = (AutoBike)b;
//ClassCastException 참조할수없는 참조 변수로 객체를 참조하려할 때 발생
미리 알수있는 방법이 없을까 ?
Insatnceof 연산자
package ex4_binding;
public class BindingEx3 {
public static void main(String[] args) {
Bike b = new Bike(2);
// Bike b = new AutoBike(2);
AutoBike ab = null;
Object o =null;
//ClassCastException 참조할수없는 참조 변수로 객체를 참조하려할 때 발생
if(b instanceof AutoBike) {
ab = (AutoBike)b;
System.out.println("ab 참조변수가 참조하는 객체는 AutoBike객체");}
if(b instanceof Bike) {
System.out.println("b 참조변수가 참조하는 객체는 Bike객체");}
if(b instanceof Object) {
o = b;
System.out.println("o 참조변수가 참조하는 객체는 Object객체임");}
}
}
b 참조변수가 참조하는 객체는 Bike객체
o 참조변수가 참조하는 객체는 Object객체임
이렇게 instanceof 연산자로 확인이 가능함
if(b instanceof AutoBike) ===> b가 참조하는 객체에 AutoBike 가 존재하는가??(형변환이가능한지?)
Bike b = new Bike(); 여기에는 AutoBike(자식)이 존재하지않음 : false
Bike b = new AutoBike()로변경 시 : true
if(b instanceof Bike) ==> b 가 참조하는 객체에 Bike 가 존재하는가?? 자신의 타입이므로true
b instanceof Object ==> b가 참조하는 객체에 Object 가 존재하는가? Object는 모두의부모! true
1-4) 상속활용 예제
부모 클래스 product
class Product{
int price,point;
Product(int price){
this.price = price;
this.point=price/10;
}}
Product의 하위클래스들
class Tv extends Product{
Tv() {
super(100);}
@Override
public String toString() {
return "Tv";}
}
class Computer extends Product{
Computer() {
super(200);}
@Override
public String toString() {
return "Computer";}
}
class HandPhone extends Product{
HandPhone() {
super(150); }
@Override
public String toString() {
return "HandPhone";}
}
문제 내용
* Buyer클래스
* 멤버변수 : money : 500 ,point
* product[] items = new Product[5]; 구매물품목록
* int cnt; 구매물품 갯수
*멤버메서드
* void buy(Product p)
* 1.p 상품의 가격을 money에서 차감
* 2.p 상품의 point만큼 Buyer의 point 증가
* 3. 물건을 items에 추가 ,cnt값 증가
* 4. p 제품의 이름 출력 후 메서드종료 ex) Tv구입
*
* void summary()
* 1.구매제품 전체금액합계 , 포인트합계 계산
* 2. 잔액출력
* 3. 구매물품의 이름 출력
Buyer 클래스와 구동클래스
class Buyer{
int money=500,point,cnt;
Product [] items = new Product[5];//구매물품은 최대5개
//Product가 참조할 수있는 객체는 모두 들어올 수 있다.
//Product p = new 자식();
//(new Tv() instanceof Product) : tv가 참조하는 객체에는 Product가 존재함
void buy(Product p) {
money -= p.price; //p의 가격만큼 Buyer의 money 차감
point += p.point; // p의 point를 Buyer의 point에 누적
items[cnt++] = p;
System.out.println(p+"구입 ["+p.price+"만원]");
}
void summary() {
int sum=0;
int point = 0; //지역변수 (메서드가종료되면 사라짐 , 멤버변수의 point는 this.point로 접근가능)
System.out.print("구매물품 : ");
for (int i = 0; i < cnt; i++) {
sum+= items[i].price;
point += items[i].point;
System.out.print(items[i]+",");
}
System.out.println("\n구매제품 전체금액 : "+sum+"만원 , 포인트합계 : ["+point+"]P");
System.out.println("잔액 : "+this.money+"만원");
}
}
public class Exam1 {
public static void main(String[] args) {
Tv tv = new Tv();
Computer cp = new Computer();
HandPhone hp = new HandPhone();
Buyer buyer = new Buyer();
buyer.buy(tv); //매개변수 자동형변환
//Product를 상속받았으므로 들어갈 수 있음 또한 출력도 오버라이딩된 메서드가 나오게되므로 나의 toString출력가능
buyer.buy(cp);
buyer.buy(hp);
buyer.summary();
System.out.println();
if(new Tv() instanceof Product) {
System.out.println("Tv는 Product가 존재(Product의 자식)");
}
if(new Computer() instanceof Product) {
System.out.println("Computer는 Product가 존재(Product의 자식)");
}
}
}
Tv구입 [100만원]
Computer구입 [200만원]
HandPhone구입 [150만원]
구매물품 : Tv,Computer,HandPhone,
구매제품 전체금액 : 450만원 , 포인트합계 : [45]P
잔액 : 50만원
Tv는 Product가 존재(Product의 자식)
Computer는 Product가 존재(Product의 자식)
//이코드는 그냥 intanceof 의 기능을 한번 더 보여주려 써본것
new Tv() insatnce of Product == tv객체에 Product 가 있니???
1. parent instanceof Parent : 부모가 본인 집을 찾았으니 true
2. child instanceof Parent : 자식이 상속받은 부모 집을 찾았으니 true (상속을 받았으니 자기 집이라 해도 무방하다?)
3. parent instanceof Child : 부모가 자식 집을 찾았으니 false (자식 집은 자식 집이지 부모 집은 아니니까)
4. child instanceof Child : 자식이 본인 집을 찾았으니 true
t : tv c : computer , h = HandPhone : 생성한 객체의 참조변수
b = buyer
itme : 참조변수의 참조값을 가지고있는 Product 형 배열
임을 인지하고 잘 보고 이해해보자
1-5) 추상클래스
메소드가 바디를 가지고 있지 않고 메소드의 인터페이스 부분 (선언부)만 갖고 있는
메소드가 하나라도 있으면 이 클래스를 추상클래스라 부른다.
바디없이 메소드의 선언부만 갖고 있는 메소드를 추상메소드라 한다.
ex) void plus();
추상클래스 : 미완성 클래스
추상 메서드를 가질 수 있는 클래스. abstract 예약어로 표현됨
객체화 불가. 객체화하려면, 반드시 상속을 통한 자손클래스의 객체화 통해서 객체화 가능.
그외는 일반클래스와 동일. 즉 생성자, 멤버변수, 멤버메서드를 멤버로 소유 가능함.
추상 메서드
선언부만 존재하는 메서드. 구현부가 없음.
자손클래스에서 반드시 오버라이딩 해야 함.
( 자손클래스 == 추상클래스 인경우는 오버라이딩 하지않아도됨)
예시
package ex5_abstract;
/*
* 추상클래스
* 1. 추상메서드를 멤버로 가질 수 있는 클래스(abstract)
* 2. 객체화 X --> 상속을 통해 자손클래스의 객체화로 객체화가능
* 3. 그 외는 일반클래스와 동일 ( 멤버변수 , 생성자 , 멤버메서드,초기화블럭 , 다른클래스를 상속받을 수 있음)
*
*
* 추상메서드
* 1.메서드의 선언부만 존재함(구현부 {} 가 없음). abstract 예약어사용
* 2. 하위클래스에서 반드시 오버라이딩해야함
* 3.
*/
public abstract class Shape { //도형클래스--> 추상클래스
String type;//멤버변수
Shape(String type){//생성자 (매개변수 o)
this.type = type;}
abstract double area(); //추상메서드 바디({})X
abstract double length();// 하위클래스에서 오버라이딩은 필수임
@Override
public String toString() {
return "Shape [type=" + type + ", area()=" + area() + ", length()=" + length() + "]";
}
}
//Circle클래스
class Circle extends Shape{
int r;
Circle(int r) {
super("원");//부모의생성자 호출해야함
this.r = r;}
@Override
double area() {//추상메서드는 반드시 오버라이딩해야함
return Math.PI*r*r;}
@Override
double length() {
return 2*Math.PI*r;}
@Override
public String toString() {
return type+": "+r +"-> 면적 : "+area()+", 둘레 : "+length();
}
}
/*
* Rectangle클래스구현
* 멤버변수 : width , height
*/
class Rectangle extends Shape{
int width,height;
Rectangle(int width,int height) {
super("사각형");
this.width = width;
this.height = height;}
@Override
double area() {
return width * height;}
@Override
double length() {
return 2*(width+height);}
@Override
public String toString() {
return type+": ("+width+","+height+") -> 면적 : "+area()+", 둘레 : "+length();
}
}
구동클래스
package ex5_abstract;
public class ShapeEx1 {
public static void main(String[] args) {
// Shape s = new Shape("도형"); 추상클래스는객체화불가
Shape []arr = new Shape[2]; //Shape 객체를 참조할수있는 참조변수(객체가 아님)
arr[0] = new Circle(10);
arr[1] = new Rectangle(10, 10);
double totalArea=0,totalLength=0;
for (Shape s : arr) {
System.out.println(s);
totalArea += s.area();
totalLength += s.length();
}System.out.printf("면적 합 : %.4f 둘레 합 : %.4f",totalArea,totalLength);
}
}
원: 10-> 면적 : 314.1592653589793, 둘레 : 62.83185307179586
사각형: (10,10) -> 면적 : 100.0, 둘레 : 40.0
면적 합 : 414.1593 둘레 합 : 102.8319
추상클래스의 상속
package ex5_abstract;
abstract class Abs1{ //추상클래스(추상메서드를 포함할수있는클래스)
int a = 10;
abstract int getA(); //추상메서드(하위클래스에서 반드시오버라이딩해야함)
}
//------------------------------------------------------------------------------------
abstract class Abs2 extends Abs1{ //추상클래스는 추상메서드를 오버라이딩 안해도 됨
int b = 20;
abstract int getB();
//abstract int getA();을가지고 있음
}
//---------------------------------------------------------------------------------------------------
class Normal extends Abs2{
@Override
int getB() {
return b;
}
@Override
int getA() {
return a;
}
}
//------------------------------------------------------------------------------------
public class AbstractEx1 {
public static void main(String[] args) {
Normal n = new Normal();
System.out.println("Normal 멤버 ==========");
System.out.println(n.a);
System.out.println(n.getA());
System.out.println(n.b);
System.out.println(n.getB());
Abs2 a2 = n;
System.out.println("Abs2 멤버 =============");
System.out.println(a2.a);
System.out.println(a2.getA());
System.out.println(a2.b);
System.out.println(a2.getB());
Abs1 a1 = a2;
System.out.println("Abs1 멤버 =============");
System.out.println(a1.a);
System.out.println(a1.getA());
// System.out.println(a1.b); Abs1은 멤버 b를 가지고있지않음 .
// System.out.println(a1.getB());
Object o1 = a1;
System.out.println("Object 멤버 =============");
/*
* System.out.println(o1.a);
* System.out.println(o1.getA());
* System.out.println(o1.b);
* System.out.println(o1.getB());
* 전부 Object의 멤버가 아님
*/
}
}
1-6 ) final 제어자
* final제어자 : 변경불가의 의미
* fianl 클래스 (종단클래스) : 상속불가 클래스 , 다른클래스의 부모가 될 수 없음
* String , Math 클래스 : final 클래스(불변클래스)
package ex6_final;
class A{
}
//------------------------------------------------------------------------
public final class FinalClass extends A{
}
/*
* class SubClass extends FinalClass{};
*
* class MyString extends String{};
*
* class MyMath extends Math{};
*/
final 메서드
* final 변경불가
* final method : 재정의불가
package ex6_final;
public class FinalMethod {
final void method() {//재정의(오버라이딩)불가 메서드
System.out.println("finalMethod클래스의 method");}
}
//---------------------------------------------------------------------------------------
class SubMethod extends FinalMethod{
// void method() {
// System.out.println("SubMethod클래스의 method");
// }
}
final 변수
* final 변수 : 변경불가능 변수 => 상수 , const 예약어 사용안함
* final변수도 생성자에서 한번은 초기화가 가능함 ( 객체별로 다른 상수값 가능)
* 단 명시적초기화를 하면 안됨 ex)final int NUM=0; XXX
package ex6_final;
public class FinalValue {
final int NUM;
FinalValue(int num) {
NUM = num; //상수값 초기화 (한번만 초기화가능)
// NUM = 10;
}
//---------------------------------------------------------------
public static void main(String[] args) {
FinalValue a = new FinalValue(123);
// a.NUM = 194; 이미 생성자에서 한번 초기화해버렸기때문에 변경불가
System.out.println(a.NUM);
FinalValue b = new FinalValue(678);
System.out.println(b.NUM);
//final 배열
final int[] arr = {10,20,30,40,50};
arr[0] = 100;
arr[1] = 200;
// arr = new int[]{100,200,300}; 참조변경불가 ( 즉 크기바뀌지않음)
System.out.println(Arrays.toString(arr));
int[] arr2 = {10 , 20};
arr2 = new int[] {100,2200,500,600};
}
}
1-7) 예제
문제가 굉장히 길다
잘 읽어보자
1. Food 클래스
멤버 변수 : 가격(price)과 포인트(point)
생성자 : 식품의 객체 생성시 가격을 입력받아야 하고, 가격의 10%를 포인트로 저장한다.
식품의 종류는 과일(Fruit),음료(Drink),과자(Snack)로 나눠 진다.
Fruit 클래스 : Food 클래스의 하위 클래스
Drink 클래스 : Food 클래스의 하위 클래스
Snack 클래스 : Food 클래스의 하위 클래스
과일 클래스는 당도(brix)를, 음료는 용량(ml), 과자는 무게(gram)을 멤버로 가진다
과일의 종류로는 사과(Apple),복숭아(Peach),
음료의 종류로는 콜라(Cock) 와 사이다(Sidar)
과자의 종류로는 비스킷(Biscuit)과 쿠키(Cookie) 가 있다.
사과,복숭아, 콜라, 사이다,비스킷,쿠키 클래스에 toString() 메서드를 구현하고
각각의 이름을 리턴한다.
* 2. Buyer 클래스
* 멤버변수 : 돈(money)=10000, 포인트(point), 구매건수(cnt)
* 장바구니(cart)
* 멤버메서드
* buy(Food) :
* 소유 금액보다 물품값이 큰경우 "잔액부족"메세지 출력하고 메서드 종료
* 물건 구매시 보유금액에서 물품가격만큼 차감
* 물품의 포인트 만큼 포인트 증가.
* 물품의 물품명과 가격을 화면에 출력.
* 해당 물품은 장바구니에 추가. 구매건수 1 증가
* summary() :
* 장바구니를 조회하여 구매한 물품의 목록과 총 가격과 현재 포인트를 출력하기.
* 과일의 갯수,과일 구매 금액,과일 구매 목록
* 음료의 갯수,음료 구매 금액,음료 구매 목록
* 과자의 갯수,과자 구매 금액,과자 구매 목록 출력하기
[결과]
사과를(을) 1000가격에 구입
10.5당도 상품 구매
복숭아를(을) 1000가격에 구입
13.5당도 상품 구매
콜라를(을) 500가격에 구입
500ml 상품 구매
사이다를(을) 1500가격에 구입
1000ml 상품 구매
비스킷구매시 잔액부족
쿠키를(을) 500가격에 구입
5000g 상품 구매
고객 잔액:5500
고객 포인트:450
총 구매금액 : 4500
총 구매목록 : 사과,복숭아,콜라,사이다,쿠키,
과일 구매금액 : 2000, 과일 구매목록 : 사과,복숭아,
음료 구매금액 : 2000, 음료 구매목록 : 콜라,사이다,
음료 구매금액 : 2000, 음료 구매목록 : 콜라,사이다,
과자 구매금액 : 500, 과자 구매목록 : 쿠키,
구동클래스
public class Test1 {
public static void main(String ... args) {
Apple apple = new Apple(1000,10.5);//가격, 당도(brix)
Peach peach = new Peach(1000,13.5);//가격, 당도(brix)
Cock cock = new Cock(500,500); //가격, 용량(ml)
Sidar sidar = new Sidar(1500,1000);//가격, 용량(ml)
Biscuit bis = new Biscuit(10000,500);//가격, 무게(gram)
Cookie cookie = new Cookie(500,5000);//가격, 무게(gram)
Buyer b = new Buyer();
b.buy(apple); b.buy(peach);
b.buy(cock); b.buy(sidar);
b.buy(bis); b.buy(cookie);
System.out.println("고객 잔액:" + b.money);
System.out.println("고객 포인트:" + b.point);
b.summary();
}
}
Food 클래스 와 그 하위클래스 (Fruit , Drink , Snack)
class Food{
int price;
int point;
Food(int price){
this.price = price;
this.point = price/10;
}
}
//-----------------------------------------------------------------------------
class Fruit extends Food{
double brix;
Fruit(int price,double brix) {
super(price);
this.brix = brix;
}
}
class Apple extends Fruit{
Apple(int price, double brix) {
super(price, brix);
}
public String toString() {
return "사과";
}
}
class Peach extends Fruit{
Peach(int price, double brix) {
super(price, brix);
}
public String toString() {
return "복숭아";
}
}
//-----------------------------------------------------------------------------
class Drink extends Food{
int ml;
Drink(int price,int ml) {
super(price);
this.ml = ml;
}
}
class Cock extends Drink{
Cock(int price, int ml) {
super(price, ml);
}
public String toString() {
return "콜라";
}
}
//-----------------------------------------------------------------------------
class Sidar extends Drink{
Sidar(int price, int ml) {
super(price, ml);
}
public String toString() {
return "사이다";
}
}
//-----------------------------------------------------------------------------
class Snack extends Food{
int gram;
Snack(int price, int gram) {
super(price);
this.gram = gram;
}
}
class Biscuit extends Snack{
Biscuit(int price, int gram) {
super(price, gram);
}
public String toString() {
return "비스킷";
}
}
//-----------------------------------------------------------------------------
class Cookie extends Snack{
Cookie(int price, int gram) {
super(price, gram);
}
public String toString() {
return "쿠키";
}
}
여기까지는 문제가 많이없다
Buyer 클래스 여기를 집중해서보자
배열의 이해와 객체 , isntanceof 에 대해 잘 알아야함
class Buyer{
int money=10000;
int point;
int cnt;
Food[] cart = new Food[10];
void buy(Food f) {
if(f.price>this.money) {
System.out.println("잔액부족");
return;
}
else {
this.money -= f.price;
this.point += f.point;
System.out.println(f+"를(을) ["+f.price+"원] 구입");
if(f instanceof Fruit) {System.out.println(((Fruit) f).brix+"당도 상품구매");}
else if(f instanceof Drink){System.out.println(((Drink) f).ml+"ml 상품 구매");}
else if(f instanceof Snack) {System.out.println(((Snack)f).gram+"g 상품 구매");}
cart[cnt++]= f; //카트에넣었다면 cnt(갯수)증가시켜주자
}
}
void summary() {
int fCount=0,dCount=0,sCount=0; //각 음식별의 갯수를 저장 할 변수
for (int i = 0; i < cnt; i++) {
if(cart[i] instanceof Fruit) { //Fruit를 포함한다면 fCount++;
fCount++;
}
else if(cart[i] instanceof Drink) {//Drink를 포함한다면 dCount++;
dCount++;
}
else if (cart[i] instanceof Snack){//Snack를 포함한다면 sCount++;
sCount++;
}
}
//굳이 배열별로 크기를 따로나눌필요가 있을까 생각이 들지만
//그렇지않으면 null값이 들어가게 됨 ( 즉 배열을 넣을 수 없음)
//배열은 순서대로들어가야함
Fruit [] f = new Fruit[fCount];//Fruit를 참조하는 배열
Drink [] d = new Drink[dCount];
Snack [] s = new Snack[sCount]; // 카운트 한 갯수만큼 배열생성
int totalPrice=0;//총 금액
int fruitPrice=0,drinkPrice=0,snackPrice=0;//음식별 금액
int fIndex =0, dIndex=0, sIndex=0; //인덱스
System.out.print("상품목록 : ");
for (int i = 0; i < cnt; i++) {
totalPrice += cart[i].price;
System.out.print(cart[i]+",");
if(cart[i] instanceof Fruit) {
f[fIndex] = (Fruit)cart[i];
fruitPrice += f[fIndex].price;
fIndex++;
}
else if(cart[i] instanceof Drink) {
d[dIndex] = (Drink)cart[i];
drinkPrice += d[dIndex].price;
dIndex++;
}
else if (cart[i] instanceof Snack){
s[sIndex] = (Snack)cart[i];
snackPrice += s[sIndex].price;
sIndex++;
}
}System.out.println();
System.out.println(" 총 금액 : "+totalPrice);
System.out.println("과일 목록 : "+Arrays.toString(f)+" 가격 : "+fruitPrice);
System.out.println("음료 목록 : "+Arrays.toString(d)+" 가격 : "+drinkPrice);
System.out.println("과자 목록 : "+Arrays.toString(s)+" 가격 : "+snackPrice);
}
}
이거말고 분명히 다른방법이 존재할꺼다
내일 9일차에한번 써 보겠다!!!!
'부트캠프(Java)' 카테고리의 다른 글
자바 / 스프링 부트캠프 10일차 ( 람다식 , 내부클래스, 예외처리) (0) | 2025.02.13 |
---|---|
자바/스프링 부트캠프 9일차(상속 , 인터페이스 ) (0) | 2025.02.12 |
자바/스프링 개발 부트캠프 7일차 (생성자 , 상속) (1) | 2025.02.10 |
자바/스프링 개발 부트캠프 6일차(클래스) (1) | 2025.02.07 |
자바/스프링 개발 부트캠프 5일차 (2차원배열 , 객체) (1) | 2025.02.06 |