Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
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
Archives
Today
Total
관리 메뉴

기록

day 0521 추상클래스_추상메소드 본문

📖

day 0521 추상클래스_추상메소드

슈슈파나 2024. 5. 21. 17:07

~ㅇㅏ니글세~ 쌤 컴터가 요상해서 딩가딩가 노는중~

package com.kosta.exam01;

import java.util.Scanner;

public class EmployeeTest {

	public static void main(String[] args) {
		// 사용자 입력받아 월급제 사원, 시간제 사원 처리하는 프로그램으로 수정 해 봅니다
		Scanner sc = new Scanner(System.in);
		Employee[] data = new Employee[1000];
		int menu, level, base, hours;
		String no, name;
		int i = 0;
		
		while(true) {
			// do-while
			do {	
				System.out.print("선택하세요 ==> [1] 월급제 사원 [2]시간제 사원 [0] 종료");
				menu = sc.nextInt();
			// 메뉴가 0보다 작거나 2보다 크면
			}while(menu < 0 || menu > 2);
			
			if(menu == 0) {
				break;
			}
			
			System.out.print("사원 번호 ==>");
			no = sc.next();
			
			System.out.print("사원 이름 ==>");
			name = sc.next();
			
			switch(menu) {
			case 1: 
				System.out.print("호봉 입력 : " ); 
				level = sc.nextInt(); 
				data[i] = new SalariedEmployee(name, no, level);
				break; // 월급제 사원
			case 2: 
				System.out.print("시간당 임금 : " ); 
				base = sc.nextInt(); 
				System.out.print("일한 시간 : " ); 
				hours = sc.nextInt(); 
				data[i] = new HourlyEmployee(name, no, base, hours);
				break; // 시간제 사원
			} // end switch
			i++;
		} // end while
		int n = i;
		for(i = 0; i < n; i++) {
			data[i].computeSalary();
			System.out.println(data[i]);
		}
	}
}

 

** 추상 클래스와 추상 메소드

미래의 만들어진 후손들이 가져야 할 공통적인 속성과 동작을 뽑아 일반화(부모클래스)할 때에

어떠한 메소드가 반드시 자식클래스에 필요하고 자식클래스에게 맞도록 재정의 해야 하는 메소드가 있을 때

부모클래스를 만드는 시점에서는 그 메소드의 body를 구체화 할 수 없을 때 메소드 선언만 하게 됩니다

이와 같이 메소드 body가 없고 메소드 선언부만 있는 메소드를 "추상메소드"라고 하고

메소드 앞에 abstract 키워드를 붙여 줍니다

 

이와 같이 어떠한 클래스가 추상메소드를 하나라도 갖고 있다면

그 클래스 자신이 추상클래스가 되어야 하며 클래스 이름 앞에 abstract 키워드를 붙여야 합니다

 

따라서 어떠한 클래스가 추상클래스로부터 상속받았다면

반드시 그 추상클래스안에 있는 모든 추상메소드를 오버라이팅 해야 합니다

 

일반적으로 상속관계에 있을때에 자식클래스는 부모의 메소드가 마음에 들면 그대로 사용하고

자신에게 맞지 않으면 선택적으로 메소드를 재정의(오버라이딩) 할 수 있어요

그런데 만약 자식클래스들에게 어떤 메소드를 반드시(필수적으로) 오버라이딩 하고자 한다면

그 메소드를 추상메소드로 만들어 줍니다.

 

또, 추상클래스는 body가 구체화되지 않는 메소드를 갖고 있기 때문에 추상클래스의 객체는 생성할 수 없어요

그러나 추상클래스의 참조변수가 추상메소드를 오버라이딩 한 자식 클래스의 객체는 생성할 수 있어요(참조 할 수 있다)

 

/부모클래스를 만드는 시점에서 메소드의 body를 구체화 할 수 없을 경우/

package com.kosta.exam02;

//abstract class에도 써줘야한다
public abstract class Employee {
	protected String name; 	//이름
	protected String no;	//사번

	// abstract 추상적 메소드
	public abstract void computeSalary();
}

 


 

14:00 ~

 

/인터페이스와 다형성.pdf/ exam03 ~ 

package com.kosta.exam03;

public class Shape {
	protected int x;
	protected int y;

	@Override
	public String toString() {
		return "Shape [x=" + x + ", y=" + y + "]";
	}
		
	public Shape() {
		super();
		// TODO Auto-generated constructor stub
	}
	
	public Shape(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}
	
	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}
}
package com.kosta.exam03;

public abstract class TwoDimShape extends Shape {
	
	protected double area;

	// public void calcArea(); // 추상 메소드
	public abstract  void calcArea(); 
	
	public TwoDimShape() {
		super();
		// TODO Auto-generated constructor stub
	}

	public TwoDimShape(int x, int y) {
		super(x, y);
	}

	public double getArea() {
		return area;
	}
}
package com.kosta.exam03;

public abstract  class ThreeDimShape extends Shape {
	
	protected double volume;
	
	public abstract void calcVolume();
	public void pro() {
		System.out.println("ThereDimShape의 pro입니다");
	}
	
	public ThreeDimShape() {
		super();
		// TODO Auto-generated constructor stub
	}
	
	public ThreeDimShape(int x, int y) {
		super(x, y);
	}
	
	public double getVolume() {
		return volume;
	}
}

 

/2차원 도형 만들기/

package com.kosta.exam03;

public class Rectangle extends TwoDimShape {
	private double width;
	private double height;

	@Override
	public void calcArea() {
		area = width * height;
	}

	@Override
	public String toString() {
		return "Rectangle [width=" + width + ", height=" + height + ", area=" + area + ", x=" + x + ", y=" + y + "]";
	}

	public Rectangle() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Rectangle(double width, double height) {
		super();
		this.width = width;
		this.height = height;
	}

	public double getWidth() {
		return width;
	}

	public void setWidth(double width) {
		this.width = width;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}
}
package com.kosta.exam03;

public class Triangle extends TwoDimShape {
	private double width;
	private double height;

	@Override
	public void calcArea() {
		area = width * height / 2;	
	}

	@Override
	public String toString() {
		return "Triangle [width=" + width + ", height=" + height + ", area=" + area + ", x=" + x + ", y=" + y + "]";
	}

	public Triangle() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Triangle(int x, int y, double width, double height) {
		super(x, y);
		this.width = width;
		this.height = height;
	}

	public double getWidth() {
		return width;
	}

	public void setWidth(double width) {
		this.width = width;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}
}

 

/3차원 도형 만들기/

package com.kosta.exam03;

public class Cube extends ThreeDimShape {
	private double width;
	private double length;
	private double height;
	
	@Override
	public void calcVolume() {
		volume = width * length * height;
	}

	@Override
	public String toString() {
		return "Cube [width=" + width + ", length=" + length + ", height=" + height + ", volume=" + volume + ", x=" + x
				+ ", y=" + y + "]";
	}

	public Cube() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Cube(double width, double length, double height) {
		super();
		this.width = width;
		this.length = length;
		this.height = height;
	}

	public double getWidth() {
		return width;
	}

	public void setWidth(double width) {
		this.width = width;
	}

	public double getLength() {
		return length;
	}

	public void setLength(double length) {
		this.length = length;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}
}

 

package com.kosta.exam03;

public class Cylinder extends ThreeDimShape {
	public static final double PI = 3.141592;
	private double radius; 
	private double height;

	@Override
	public void calcVolume() {
		volume = Cylinder.PI * radius * radius * height;
	}

	@Override
	public String toString() {
		return "Cylinder [radius=" + radius + ", height=" + height + ", volume=" + volume + ", x=" + x + ", y=" + y
				+ "]";
	}

	public Cylinder() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Cylinder(double radius, double height) {
		super();
		this.radius = radius;
		this.height = height;
	}

	public double getRadius() {
		return radius;
	}

	public void setRadius(double radius) {
		this.radius = radius;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}
}
package com.kosta.exam03;

import java.util.Scanner;

public class ShapeTest {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		double width, length, height, radius;
		int menu, x, y;
		int n = 0;
		
		Shape[] data = new Shape[1000];
		
		while(true) {
			
			do {
				System.out.println("[1] 사각형 [2] 삼각형 [3] 직육면체 [4] 원기둥 [0] 종료");
				System.err.println("도형의 종류를 선택하시오. ");
				menu = sc.nextInt();
				// 0보다 작거나 4보다 크다면
			}while(menu < 0 || menu > 4);
			
			if(menu == 0) {
				break;
			}
			
			System.out.println("도형의 x 위치 : ");
			x = sc.nextInt();
			System.out.println("도형의 y 위치 : ");
			y = sc.nextInt();
			
			switch(menu) {
			case 1:
				System.out.println("사각형의 가로 : ");
				width = sc.nextDouble();
				System.out.println("사각형의 세로 : ");
				length = sc.nextDouble();
				// Shape의 변수, 아들 Two Three, 손자 도형들
				data[n] = new Rectangle(x, y, width, length);
				break;
			case 2:
				System.out.println("삼각형의 밑변 : ");
				width = sc.nextDouble();
				System.out.println("삼각형의 높이 : ");
				height = sc.nextDouble();
				data[n] = new Triangle(x, y, width, height);
				break;
			case 3:
				System.out.println("직육면체의 가로 : ");
				width = sc.nextDouble();
				System.out.println("직육면체의 세로 : ");
				length = sc.nextDouble();
				System.out.println("직육면체의 높이 : ");
				height = sc.nextDouble();
				data[n] = new Cube(x, y, width,length, height);
				break;
			case 4:
				System.out.println("원기둥의 반지름 : ");
				radius = sc.nextDouble();
				System.out.println("원기둥의 높이 : ");
				height = sc.nextDouble();
				data[n] = new Cylinder(x, y, radius, height);
				break;
			}
			n++;
		} // end while
		for(int i = 0; i < n; i++) {
			Shape s = data[i];
			// 만약에 2차원 도형이면 면적을 계산시키고 3차원 도형이면 부피를 계산시키도록 합니다
			if(s instanceof TwoDimShape) {
				((TwoDimShape) s).calcArea();
			}else if(s instanceof ThreeDimShape) {
				((ThreeDimShape) s).calcVolume();
			}
			System.out.println(s);
		}
	}
}

 

상속관계에 있을 때 부모의 참조변수가 자식클래스의 객체를 참조할 수 있어요

그러나 자식클래스에 새로 추가된 메소드를 바로 호출 할 수는 없고

자식클래스로 형변환 한 후에 호출 할 수 있습니다

Class A{
}

Class B extends A{
    public void pro(){
    }
}

A ob = new B();

위의 코드에서 부모의 참조변수가 자식클래스인 B의 객체를 참조 할 수 있어요

그러나 다음과 같이 자식에서 부모에는 없는 자식에서 새로 추가된 메소드 pro를 바로 호출 할 수 없어요

X ==> ob.pro();

 

호출하려면 자식클래스로 형변환 한 후에 호출해야 합니다

O ==> ((B)ob).pro();

Class A{
}

Class B extends A{
    public void pro(){
    }
}

Class C extends A{
    puublic void hello{
    }
}

A[] data = new A[];

 

이번에는 다음과 같이 A의 자식클래스가 B, C가 있다고 합시다

배열의 자료형이 A이기 때문에 배열에는 A의 후손인 B, C의 자료형을 모두 담을 수 있어요

배열의 요소만큼 반복실행하여 만약 그 배열의 요소가 B의 자료형이라면 B 클래스에 추가된 pro를 동작시키고

그렇지 않으면 C 클래스 추가된 hello를 동작시켜야 한다면

해당 클래스의 객체인지 물어봐서 해당 클래스로 형변환 해야 합니다

이때 해탕클래스의 객체인지 판별하기 위한 연산자가 instanceof 입니다

for(A ob : data){
    if(ob instanceof B){
        ((B)ob).pro();
    }else{
        ((C)ob).hello();
    }
}

 

instanceof

: 상속관계에 있을 때 부모의 참조변수가 자식의 객체를 참조 할 수 있어요

  많은 양의 데이터를 처리하기 위하여 배열을 이용하는데

  부모의 참조자료형으로 배열을 만들면 온갖 종류의 자식클래스 객체를 담을 수 있어요

  그러나 해당 자식클래스에서 추가된 메소드를 바로 호출 할 수는 없어서

  해당 자식클래스로 형변환해야 하는데

  이때 어떤 자식클래스인지 판별할 때 instanceof 연산자를 사용합니다

 

/instanceof 형변환하기 ((형변환)a).bc();/

 

2차원 도형도 담고, 3차원 도형도 담기 위하여 data 배열의 자료형을

2차원 도형과 3차원 도형 클래스의 부모클래스인 Shape으로 만들었어요

배열의 요소를 꺼집어 내어 오면 Shape입니다

만약에 그것이 2차원 도형 클래스라면 2차원 도형 클래스로 변환한 후 면적을 계산시키는 메소드를 호출하고

3차원 도형이라면 3차원 도형클래스로 변환한 후에 부피를 계산시키는 메소드를 호출 할 수 있어요

// 만약에 2차원 도형이면 면적을 계산시키고 3차원 도형이면 부피를 계산시키도록 합니다
for(int i = 0; i < n; i++) {
    Shape s = data[i];
    // 만약에 2차원 도형이면 면적을 계산시키고 3차원 도형이면 부피를 계산시키도록 합니다
    if(s instanceof TwoDimShape) {
        ((TwoDimShape) s).calcArea();
    }else if(s instanceof ThreeDimShape) {
        ((ThreeDimShape) s).calcVolume();
    }
    System.out.println(s);
   }

 

zoom이 30분마다 꺼져성 필기를 한번엫 ㅎㅎ ...

- 이번주 학습내용 객체와 클래스와 관련하여 개념정리를 잘 하도록 합니다.

- 개념정리 다 된 사람들은 다음을 프로그래밍 해 봅니다.

   "인터페이스와 다형성.pdf" LAB 1번을 풀어봅니다.

'📖' 카테고리의 다른 글

day 0523 컬렉션  (0) 2024.05.23
day 0522 인터페이스  (0) 2024.05.22
day 0520 상속_메소드 오버라이딩_객체의 배열  (0) 2024.05.20
day 0517 객체와 클래스_생성자_this  (0) 2024.05.17
day 0516 정렬_객체와 클래스  (0) 2024.05.16