- 자바의 다형성-상위 클래스를 통해 하위 클래스의 값을 다양한 형태로 돌려줌. 각 도형의 넓이의 합을 구할때. (Shape, ShapeMain, ShapeManager, Circle, Square)
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
|
package day07;
import java.util.Scanner;
public class ShapeMain {
static Scanner sc=new Scanner(System.in);
public static void showMenu() {
System.out.println("선택하세요...");
System.out.println("1.원 2.사각형 3.보기 4.종료");
System.out.print("선택:");
}
public static void main(String[] args) {
ShapeManager sm=new ShapeManager();
while(true) {
ShapeMain.showMenu();
//클래스 이름에 static 불였으니까 ShapeMain으로 부를 수 있음.
int num=sc.nextInt();
switch(num) {
case 1 : //원입력
case 2 : sm.inputData(num); break; //사각형입력
case 3 : sm.viewData(); break; //전체보기
case 4 : System.out.println("종료");
System.exit(0);
default : System.out.println("입력오류");
}
}
}
}
|
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
|
package day07;
public class ShapeManager {
//입력받은 좌표, 반지름, 너비, 높이 등을 저장하기 위해 배열 선언
//부모형으로 선언을 해야 Circle, Square 모두 적용가능
Shape[]arr=new Shape[50];
int cnt;
public void inputData(int num) { //원->x,y,r 사각형->x,y,w,h
System.out.println("도형입력....");
System.out.print("x 좌표>>");
int x=ShapeMain.sc.nextInt();
System.out.print("y 좌표>>");
int y=ShapeMain.sc.nextInt();
if(num==1) { //원
System.out.print("반지름>>");
int r=ShapeMain.sc.nextInt();
arr[cnt++]=new Circle(x,y,r);
}
else if(num==2) { //사각형
System.out.print("너비>>");
int w=ShapeMain.sc.nextInt();
System.out.print("높이>>");
int h=ShapeMain.sc.nextInt();
arr[cnt++]=new Square(x,y,w,h);
}
}
public void viewData() {
double sum=0;
for(Shape s: arr) {
if(s==null) break;
sum+=s.getArea();
s.print();
}
System.out.println("전체 넓이: "+sum);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
package day07;
public class Shape {
private int x;
private int y;
public Shape(int x, int y) {
this.x=x;
this.y=y;
}
public void print() {
System.out.println("좌표(x,y)=("+x+","+y+")");
}
public double getArea() {
return 0.0;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
package day07;
public class Circle extends Shape {
private int r;
final double PI=3.14;
public Circle(int x, int y, int r) {
super(x,y);
this.r=r;
}
//오버라이딩
public void print() {
super.print();
System.out.println("반지름: "+r);
}
//오버라이딩
public double getArea() {
return r*r*PI;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package day07;
public class Square extends Shape {
private int w,h;
public Square(int x, int y, int w, int h) {
super(x,y);
this.w=w;
this.h=h;
}
//오버라이딩
public void print() {
super.print();
System.out.println("너비: "+w);
System.out.println("높이: "+h);
}
//오버라이딩
public double getArea() { //리턴될 유형이 같아야 하므로 double로 맞춰줌.
return w*h;
//부모 getArea()에서 0.0을 리턴하긴 했지만 오버라이딩을 통해 w*h값을 돌려줌.
}
}
|
- 자바 Api중 toString은 Object이 가지는 메소드. toString()을 통해 오버라이딩하기. (ProductMain, Product, Buyer, TV, Computer, Audio)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
package inheritance;
public class ProductMain {
public static void main(String[] args) {
Buyer b=new Buyer(1000); //바이어가 가진 돈
TV tv=new TV(50); //tv의 가격
Computer com=new Computer(100); //computer의 가격
Audio audio=new Audio(70); //audio의 가격
b.buy(tv); //tv와 com을 아우를 수 있는 자료형은 Product
b.buy(com);
b.showInfo();
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package inheritance;
public class TV extends Product {
public TV(int price) {
super(price);
}
//toString은 Object이 가지는 메소드이기 때문에 오버라이딩 할 수 있다.
//오버라이딩을 함으로써 주소가 아니라 TV, Computer등 문자가 나오도록 함
@Override
public String toString() {
return "TV";
}
}
|
1
2
3
4
5
6
7
8
9
10
11
|
package inheritance;
public class Computer extends Product {
public Computer(int price) {
super(price);
}
public String toString() {
return "Computer";
}
}
|
1
2
3
4
5
6
7
8
9
10
11
|
package inheritance;
public class Audio extends Product {
public Audio(int price) {
super(price);
}
public String toString() {
return "Audio";
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package inheritance;
public class Product {
protected int price;
protected int bonusPoint;
/* 생성자를 만들면 항상 부모의 생성자로 먼저 간다.
* 부모의 생성자 Product에 인자가 있음.
* 자식 클래스에 인자가 없는 생성자들이 있었음.
* (Buyer클래스로 인해 하위 클래스가 인자가 있는 생성자로 바꾸면서 삭제)
* 그러면 똑같이 인자가 없는 Product를 만들어줘야함.
public Product() {
}
*/
public Product(int price) {
this.price=price;
bonusPoint=price/10;
}
}
|
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
|
package inheritance;
public class Buyer {
private int money;
private int point;
Product[] arr=new Product[10];
int cnt;
public Buyer(int money) { //생성자는 클래스 이름과 똑같이 만듦.
this.money=money;
}
//구매하기
public void buy(Product p) {
arr[cnt++]=p;
money-=p.price; //바이어가 가진 돈은 물건의 가격만큼 깎인다.
point+=p.bonusPoint;
}
//구매내역
public void showInfo() {
for(int i=0;i<cnt;i++) {
System.out.println("구매내역: "+arr[i]);
//그냥 배열만 출력하면 주소값이 나옴.
}
System.out.println("잔액: "+money);
System.out.println("포인트: "+point);
}
}
|
- 객체 따로 선언하지 않고 클래스 형태를 매개변수로 적기, instanceof (AnimalTest1)
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
|
package inheritance;
class Animal{
public void move() {
System.out.println("동물이 움직입니다.");
}
}
class Human extends Animal {
public void move() {
System.out.println("사람이 두 발로 걷습니다.");
}
}
class Tiger extends Animal {
public void move() {
System.out.println("호랑이가 네 발로 뜁니다.");
}
}
class Eagle extends Animal {
public void move() {
System.out.println("독수리가 하늘을 납니다.");
}
}
public class AnimalTest1 {
public static void main(String[] args) {
AnimalTest1 aTest=new AnimalTest1();
aTest.moveAnimal(new Human());
aTest.moveAnimal(new Tiger()); //한번만 쓰고 더이상 안만들 것은 객체를 따로 선언하지 않고 new Tiger()이런 식으로 매개변수로 적어줌
aTest.moveAnimal(new Eagle());
Human h=new Human();
if(h instanceof Animal) { //instanceof는 이 객체가 어느 소속인지 물어보는 키워드. Human보다 Animal이 상위 개념이므로 맞다라고 출력.
System.out.println("맞다");
}else {
System.out.println("틀리다");
}
Animal a=new Animal();
if(a instanceof Human) { //a는 Animal. Human보다 큰 개념이므로 틀리다11가 출력.
System.out.println("맞다11");
}else {
System.out.println("틀리다11");
}
}
public void moveAnimal(Animal animal) { //Animal에서 상속받은 클래스가 매개변수로 넘어오면 모두 Animal형으로 변환됨. animal에 휴먼, 타이거, 이글 등..올수 있음.
animal.move();
}
}
|
- 추상클래스-abstract (AbsShape, AbsShapeMain, AbsCircle, AbsSquare)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
package day07;
public class AbsShapeMain {
public static void main(String[] args) {
AbsCircle ac=new AbsCircle();
ac.draw();
ac.move();
AbsSquare as=new AbsSquare();
as.draw();
as.move();
as.print();
//AbsShape ah=new AbsShape(); //추상이라서 안된다.
//추상클래스엔 객체를 생성할 수 없다. 하위클래스에서 반드시 추상클래스의 추상 메소드 구현.
AbsShape ah=new AbsCircle(); //이런식으로 접근한다.
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package day07;
public abstract class AbsShape {
/*
*그리다. 원을 그리면 원을 그리다. 사각형을 그리면 사각형을 그리다.
*자식 클래스들에 따라 구현되도록.
*그러려면 추상 메소드를 만들어놓고 클래스도 추상클래스로 변하게.
*/
public abstract void draw();
//이동하다
public abstract void move();
public void print() {
System.out.println("도형그리다");
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package day07;
public class AbsCircle extends AbsShape {
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("원 그리기");
}
@Override
public void move() {
// TODO Auto-generated method stub
System.out.println("원 이동하기");
}
}
|
1
2
3
4
5
6
7
8
9
|
package day07;
public class AbsSquare extends AbsShape {
public void draw() { //반드시 선언해줘야함. 부모 클래스인 AbsShape은 추상클래스이기 때문에 그 안에 있는 추상메소드를 구현하도록 해야함.
System.out.println("사각형 그리기");
}
public void move() {
System.out.println("사각형 이동하기");
}
}
|
- 추상클래스 (Player, PlayerLevel, BeginnerLevel, AdvancedLevel, SuperLevel, MainBoard)
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 inheritance;
public class Player {
private PlayerLevel level; //PlayerLevel이 가지는 level변수 선언
public Player() {
level=new BeginnerLevel();
level.showLevelMessage();
}
public PlayerLevel getLevel() {
return level;
}
public void upgradeLevel(PlayerLevel level) { //매개변수 자료형은 모든 레벨로 변환 가능한 PlayerLevel
this.level=level; //현재 자신의 level을 매개변수로 받은 level로 변경하고 레벨 메시지 출력
level.showLevelMessage();
}
public void play(int count) { //PlayerLevel의 템플릿 메서드 go()호출
level.go(count);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package inheritance;
public abstract class PlayerLevel {
public abstract void run();
public abstract void jump();
public abstract void turn();
public abstract void showLevelMessage();
final public void go(int count) {
run();
for(int i=0;i<count;i++) {
jump();
}
turn();
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package inheritance;
public class BeginnerLevel extends PlayerLevel {
@Override
public void run() {
System.out.println("천천히 달립니다.");
}
@Override
public void jump() {
System.out.println("Jump할 줄 모르지롱.");
}
@Override
public void turn() {
System.out.println("Turn할 줄 모르지롱.");
}
@Override
public void showLevelMessage() {
System.out.println("******초보자 레벨입니다.******");
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package inheritance;
public class AdvancedLevel extends PlayerLevel{
@Override
public void run() {
System.out.println("빨리 달립니다.");
}
@Override
public void jump() {
System.out.println("높이 Jump합니다.");
}
@Override
public void turn() {
System.out.println("Turn할 줄 모르지롱.");
}
@Override
public void showLevelMessage() {
System.out.println("******중급자 레벨입니다.******");
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package inheritance;
public class SuperLevel extends PlayerLevel{
@Override
public void run() {
System.out.println("엄청 빨리 달립니다.");
}
@Override
public void jump() {
System.out.println("아주 높이 Jump합니다.");
}
@Override
public void turn() {
System.out.println("한 바퀴 돕니다.");
}
@Override
public void showLevelMessage() {
System.out.println("******고급자 레벨입니다.******");
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package inheritance;
public class MainBoard {
public static void main(String[] args) {
Player player=new Player(); //처음 생성하면 BeginnerLevel
player.play(1);
AdvancedLevel aLevel=new AdvancedLevel();
player.upgradeLevel(aLevel);
player.play(2);
SuperLevel sLevel=new SuperLevel();
player.upgradeLevel(sLevel);
player.play(3);
}
}
|
- 전부다 추상인걸로 이뤄진 것을 interface라 하고 extends가 아닌 implements를 사용. 추상과 마찬가지로 new라는 키워드로 생성불가능하지만 추상과 달리 여러개를 상속받을 수 있다. 자바의 불가능한 다중 상속을 가능하게 만들기 위해 extends와 implements를 함께 쓴다. (InterExam)
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
|
package inheritance;
interface InterTest{
public void test();
}
//전부다 추상이라면 추상클래스라 안붙이고 interface를 붙인다.
interface InterShape{
public void draw();
public void move();
public void print();
}
//interface는 extends가 아닌 implements를 사용.
class InterCircle implements InterShape, InterTest{
//하위 클래스가 상위 추상 클래스의 메소드를 부를때는 구현(중괄호 {})해야함.꼭.
//InterTest도 상속받았기 때문에 test(){}도 구현.
public void draw() {}
public void move() {}
public void print() {}
public void test() {}
}
class Inter {
public void interTest() {
}
}
//자바는 다중 상속이 안되게끔 되어있는데 다중 상속을 받아야할때는 이렇게 표현.
//상속을 받고 interface를 써줌.
class InterRectangle extends Inter implements InterShape,
InterTest{
public void draw() {}
public void move() {}
public void print() {}
public void test() {}
}
public class InterExam {
}
|
- interface-implements로 원 넓이, 둘레, 사각형 넓이, 둘레 구하기 (InterfaceMain, Shape)
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package interfaceTest;
public class InterfaceMain {
public static void main(String[] args) {
//앞에가 Rectangle, Circle형이 아니다. 부모클래스란 소리.
Shape rec=new Rectangle(5,7);
Shape circle=new Circle(5);
System.out.println("원 넓이: "+circle.area());
System.out.println("원 둘레: "+circle.circum());
System.out.println("사각형 넓이: "+rec.area());
System.out.println("사각형 둘레: "+rec.circum());
}
}
|
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
|
package interfaceTest;
public interface Shape {
double area(); //넓이
double circum(); //둘레
}
class Rectangle implements Shape{
private int w, h;
public Rectangle(int w, int h) {
this.w=w;
this.h=h;
}
public double area() {
return w*h;
}
public double circum() {
return (w+h)*2;
}
}
class Circle implements Shape{
private int r;
public Circle (int r) {
this.r=r;
}
public double area() {
//Math는 수학적 계산이 완료된 클래스.
//멤버변수로 PI가 그 중 하나.
return r*r*Math.PI;
}
public double circum() {
return 2*r*Math.PI;
}
}
|
- 원화를 달러로 변환, 키로미터를 마일로 변환하는 두 클래스는 상위의 추상클래스를 상속받는다. (ConverterMain, Converter, Won2Dollar, Km2Mile)
1
2
3
4
5
6
7
8
9
10
11
|
package interfaceTest;
public class ConverterMain {
public static void main(String[] args) {
//원화를 달러로
Won2Dollar toDollar=new Won2Dollar(1200);
toDollar.run();
//km를 마일로
Km2Mile toMile=new Km2Mile(1.6);
toMile.run();
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package interfaceTest;
import java.util.Scanner;
//추상인 메소드, 추상아닌 메소드가 섞여 있으므로 추상 클래스로 만든다. (모두 추상이면 interface)
public abstract class Converter {
abstract protected double convert(double src);
abstract String srcString();
abstract String destString();
protected double ratio;
Scanner scanner=new Scanner(System.in);
public void run() { //교환
//srcString, destString은 돈이 들어갈 수도, 길이 단위가 들어갈 수도 있다.
//따라서 현재 Convert 클래스로는 정의하지 못하고
//하위 클래스들이 정의를 해야하므로 추상메소드로 바꾸고 따라서 클래스도 추상으로 바꿔야한다.
System.out.println(srcString()+"을 "+destString()+"로 바꿉니다.");
System.out.print(srcString()+"을 입력하세요>>");
double val=scanner.nextDouble();
double res=convert(val); //스캐너가 입력한 값을 인수로 받는다.
System.out.println("변환 결과: "+res+destString()+"입니다.");
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package interfaceTest;
public class Won2Dollar extends Converter {
public Won2Dollar(int don) {
super.ratio=don;
}
@Override
protected double convert(double src) {
//src/don이라고 하면 don이 뭔지 모르니까 부모클래스에 ratio를 주고 그걸 나누는 것
return src/ratio;
}
@Override
String srcString() {
return "원";
}
@Override
String destString() {
return "달러";
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package interfaceTest;
public class Km2Mile extends Converter {
public Km2Mile (double ratio) {
super.ratio=ratio;
}
@Override
protected double convert(double src) {
// TODO Auto-generated method stub
return src/ratio;
}
@Override
String srcString() {
// TODO Auto-generated method stub
return "Km";
}
@Override
String destString() {
// TODO Auto-generated method stub
return "mile";
}
}
|
-
ArrayList를 사용하여 배열 선언하기. ArrayList에는 객체가 들어가며 추가할때는 add, 제거할때는 remove명령어 사용 (ArrayTest)
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 utilTest;
import java.util.ArrayList;
public class ArrayTest {
public static void main(String[] args) {
ArrayList arr=new ArrayList(); //ArrayList엔 객체가 들어간다. 메소드로 접근
arr.add(1); //ArrayList에 추가하는 명령어는 add
arr.add("안녕");
arr.add(3.2); //Double이라는 클래스가 들어감. Wrapper 클래스로 변환되었기 때문에 추가가되는 것.
System.out.println("마지막: " +arr.get(arr.size()-1)); //인덱스에 접근하는 메소드는 get()
System.out.println(arr.size()); //length가 아니라 size를 사용
arr.add(new Integer(3)); //add는 맨 끝에 붙임.
System.out.println("크기: "+arr.size());
System.out.println("마지막: " +arr.get(arr.size()-1));
arr.remove(1); //안녕이 지워짐.
arr.remove("안녕"); //안녕이 지워져있기 때문에 또 지울 수 없음.
System.out.println("크기: "+arr.size());
arr.add(1,"지금 자바");
System.out.println("크기: "+arr.size());
//ArrayList의 list엔 String형만 넣겠다. 제네릭 표시. 특정 개체로 유형을 정함.
//클래스에 객체 오브젝이 들어감. int는 기본 자료형이기 때문에 정수만 받고 싶다면 Integer라고 적어야함.
ArrayList<Integer>list=new ArrayList<Integer>();
list.add(1);
list.add(2);
ArrayList<String>alist=new ArrayList<String>();
alist.add("자바");
alist.add("Java");
for(int i=0;i<alist.size();i++) {
System.out.println(alist.get(i));
}
for(String s:alist) {
System.out.print(s+"\t");
}
System.out.println();
for(int i:list) { //컴파일러가 알아서 wrapper해줘서 int를 사용할 수 있다.
System.out.print(i+"\t");
}
}
}
|
cs |
+이전의 ShapeManager와 Buyer 클래스에 배열을 ArrayList형식으로 바꾼다면..
<ShapeManager>
Shape[]arr=new Shape[50];
->ArrayList <Shape> slist=new ArrayList <Shape>();
arr[cnt++]=new Circle(x,y,r);
->slist.add(new Circle(x,y,r));
arr[cnt++]=new Square(x,y,w,h);
->slist.add(new Square(x,y,w,h));
for(Shape s: slist){
sum+=s.getArea();
s.print();
}
<Buyer>
Product[] arr=new Product[10];
->ArrayList <Product>list=new ArrayList<Product>();
arr[cnt++]=p;
->list.add(p);
for(int i=0;i<cnt;i++) {
->for(int i=0;i<list.size();i++) {
System.out.println("구매내역: "+arr[i]);
->System.out.println("구매내역: "+list.get(i));
System.out.println("가격: "+list.get(i).price);
'Learning > JAVA' 카테고리의 다른 글
해쉬맵, Vector, Set, 자바의 예외처리(try-catch, finally), Thread (run-start), 자바의 입출력(InputStream-read, OutputStream-write) (0) | 2020.06.08 |
---|---|
String의 특징, Calendar함수, StringBuilder, 입력한 문장의 글자 배열 다르게 하여 출력하기, HashMap, Collections.sort() (0) | 2020.06.05 |
이차원배열, ArrayList활용, 자바의 상속성 (0) | 2020.06.03 |
private, static, 자바 클래스 분리해서 입력메뉴 만들고 데이터출력 (0) | 2020.06.02 |
배열안에 객체 만들기 (이차원 배열/입력 클래스, 출력클래스 분리) (0) | 2020.06.01 |