U E D R , A S I H C RSS

Java Study2004/클래스상속

수업 내용

상속

상속은 객체 지향 프로그램에서 가장 중요한 개념 중의 하나이다. 이것은 자바클래스를 직접 디자인하는 문제에 영향을 미친다.상속은 다른 클래스의 정보를 동적으로 액세스하도록 해주기 위해서 그 클래스와 다른 클래스와의 차이를 명시해주면 된다.
각 클래스는 상위클래스(superclass)를가지며 하나 이상의 하위클래스(subclass)를 가진다.클래스들의 계층을 따라 내려가는 것을 상속된다고 한다.
하위클래스는 상위클래스로부터 모든 메소드와 변수들을 상속받는다.상위클래스가 필요한 행위를 정의했으면 재정의하거나 다른 클래스로부터 복사할 필요도 없다. 상속받은 클래스는 자동적으로 상위클래스의 행위를 자동적으로 가지게 된다.자바 클래스 계층의 제일 위에는 Object라는 클래스가 있다. 모든 클래스는 이 클래스로부터 상속을 받는다. 각 클래스들은 특별한 목적에 맞추어 특정 정보를 추가적으로 가지게 되는 것이다.
자바 클래스를 새로 작성할 때 대부분 다른 클래스가 가지는 정보와 몇 가지의 추가적인 정보를 가지게 할 것이다. 예를 들어 새로운 Button을 만들려고 한다면 클래스에 Button으로부터 상속받을 수 있도록 정의하기만 하면 된다. 따라서 Button과 다른 특징에 대해서만 신경 쓰면 된다.
이러한 메커니즘을 subclassing이라고부른다.

클래스 계층 만들기

많은 클래스를 만들기 위해서는 기존의 클래스 계층을 이용할 수도 있고, 자신만의 클래스 계층을 만들 필요도 있다. 이러한 계층을 만들기 위해서는 몇 가지 생각할 점이 있다.
  • 다른 클래스에 공통적인 정보를 추출해서 상위클래스에 넣고 하위클래스에서 다시 사용하도록 한다.
  • 한 클래스의 행위를 바꾸면 자동적으로 하위클래스의 행위를 바꾸게 한다. 따라서 재컴파일할 필요가 없다.
예를 들어 Motorcycle클래스와 같이 Car라는 클래스를 만드는 것을 생각하자. Car와 Motorcycle은비슷한 특징들이 있다. 이 둘은 엔진에 의해 움직인다. 또 변속기와 전조등과 속도계를 가지고 있다. 일반적으로 생각하면, Object라는클래스 아래에 Vehicle이라는 클래스를 만들고 엔진이 없는 것과 있는 방식으로 PersonPoweredVehicleEnginePoweredVehicle 클래스를 만들 수 있다. 이 EnginePoweredVehicle 클래스는 Motorcycle, Car, Truck등등의 여러 클래스를 가질 수 있다. 그렇다면 make와 color라는 속성은 Vehicle 클래스에 둘 수 있다.

상속의 동작

인스턴스 변수의 경우 클래스에 새로운 변수를 만들었다면, 현재 클래스의 변수와 상위클래스에서 정의된 모든 변수를 가질수 있다. 따라서 모든 클래스들의 조합으로 현재의 객체를 위한 템플릿을 형성하게되고 필요한 정보를 채우는 것이다.
메소드도 비슷하게 작동한다.새로운 객체는 상위클래스의 모든 메소드 이름을 액세스한다. 그러나 메소드가 호출될 때마다 동적으로 메소드 정의가 선택된다. 특정 객체에 대한 메소드를 호출하면 자바는 제일 먼저 그객체 클래스의 메소드 정의를 살펴본다. 그 객체 클래스에 정의되지 않았다면 그 메소드 정의를 발견할 때까지 상위클래스를 찾게될 것이다.
만일 하위클래스에서 상위클래스의 메소드의 이름과 인자의 타입을 똑같이 가진 메소드를 정의한다고 하면 어떻게 되는가? 이것은 계층적으로 아래에 있는 것이 먼저 실행되게 되어 있다. 이러한 방식으로 임의로 상의클래스의 메소드를 감추고 하위클래스에 필요한 메소드를 정의할 수 있다. 바로 중복(overriding)이라고 부르는 것이다.

Point 클래스

  • x,y 값을 바로 입력받는 생성자
  • x,y 좌표
  • x값 얻는 메소드, 정하는 메소드
  • y값 얻는 메소드, 정하는 메소드
  • 클래스 이름 얻어오기
    ~cpp 
     
    import javax.swing.JOptionPane;
    
    public class Point {
    
    	private int x;
    
    	private int y;
    
    	public Point() {
    
    	}
    
    	public Point(int aX, int aY) { //생성자 입니다.
    		this.x = aX;
    		y = aY;		
    	}
    
    	public int getX() {
    		return x;
    	}
    
    	public int getY() {
    		return y;
    	}
    
    	public void setX(int Ax) {
    		x = Ax;
    	}
    
    	public void setY(int Ay) {
    		y = Ay;
    	}
    
    	public String getName() {
    		return "Point";
    	}
    
    	public void Say(String str) {
    		JOptionPane.showMessageDialog(null, str);
    	}
    
    	public void Say(int temp) {
    		String str = Integer.toString(temp);
    
    		JOptionPane.showMessageDialog(null, str);
    	}
    
    	public static void main(String[] args) {
    		Point P1 = new Point(20,20);
    		Point P2 = new Point(10,10);
    		//RECTANGLE
    		Rectangle p = new Rectangle(P1,P2);
    //		System.out.println(p.getArea());
    		//circle
    		Circle c = new Circle(P1,P2);
    		System.out.println(c.getArea());
    	}	
    }
     

Shape 클래스

  • 왼쪽위 x,y점, 오른쪽아래 x,y점
  • 넓이 구해오는 메소드
  • 클래스 이름 얻어오기

~cpp 
public class Shape {
	protected Point left_top;
	protected Point right_bottom;
	public String name;
	
	public Shape()
	{
		
	}
	public  Shape ( Point p1 , Point p2)
	{
		left_top =	p1;
		right_bottom = p2;
		name = "Shape";
	}
	public Shape ( int x1, int y1, int x2, int y2)
	{
		this.left_top = new Point(x1,y1);
		this.right_bottom = new Point( x2,y2 );
		name = "Shape";
	}
	
	public double getArea()
	{
		return 0;
	}
	public String getName()
	{
		return name;
	}
}

Circle 클래스

~cpp public class Circle extends Shape {

	private double radius;

	public Circle() {

	}

	public Circle(Point p1, Point p2) {
		super(p1, p2);
		name = "Circle";
	}

	public Circle(int x1, int y1, int x2, int y2) {
		super(x1, y1, x2, y2);
		name = "Circle";
	}

	public double getArea() {
		if(Math.abs(left_top.getX()-right_bottom.getX()) >= Math.abs(left_top.getY()-right_bottom.getY()))
			radius = Math.abs(left_top.getY()-right_bottom.getY());
		else
			radius = Math.abs(left_top.getX()-right_bottom.getX());
		return Math.PI * radius * radius;
	}

	public String getName() {
		return super.getName();
	}
}

Rectangle 클래스

~cpp public class Rectangle extends Shape {
	//right_bottom
	//Point left_top
	
	public Rectangle() {

	}

	public Rectangle(Point P1, Point P2) {
		super(P1, P2);
		name = "Rectangle";
	}

	public Rectangle(int x1, int y1, int x2, int y2) {
		super(x1, y1, x2, y2);
		name = "Rectangle";
	}

	public double getArea() {
		return Math.abs(right_bottom.getX()-left_top.getX()) * Math.abs(left_top.getY()-right_bottom.getY());		
	}

}

과제

스펙

클래스
  • Unit 클래스
    • HP, 공격력, 상태(공격, 홀드, 무브, 스탑), 공중공격가능여부
    • 공격한다, 홀드한다, 무브한다, 스탑한다(상태를 바꿔줌)
    • 공격받으면 HP가 깎인다(전달인자로 적의 공격력을 받음) (ex public void underattack(int aAttackPoint) )

  • 질롯(Unit 클래스를 상속)
    • HP 100, 공격력10, 공중공격 불가능함
    • 실드 100
  • 드라군(Unit 클래스를 상속)
    • HP 150, 공격력20, 공중공격 가능함
    • 실드 150
메인
  • 질롯한마리, 드라군한마리씩을 만든다.
  • 질롯으로 드라군을 공격시킨다.

질문하세요

  • java의 함수에서는 디폴트 전달인자는 없나요?? 디폴트 전달인자가 있다면 함수의 수를 상당히 줄일수 있을것 같은데. - 이승한
    • 디폴트 전달인자라는 것하고 질문이 무슨 뜻인지 잘 모르겠습니다 ; --iruril
      • 디폴트 전달인자 : type functionName( type A1, type A2, A3 = 0 );와 같이 값이 전달 되지 않을경우 자동을 전달되는 값을 가지는 함수의 기능을 말합니다.
  • 또 super()에의한 부모 클래스에 대한 값 전달은 생성자에서만 되는 건가요?? -- 이승한
    • 생성자나 메소드에 상관없이 사용가능해요
      예를들면 위 circle 클래스의 getName 메소드에서 사용한 것처럼요 super.getName() 이렇게 --iruril
      • 고맙습니다~^^
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:32
Processing time 0.0271 sec