본문 바로가기

Java

[Chapter08]객체지향 프로그래밍2

01. 캐스팅


  • 업캐스팅

- 자식 클래스가 부모 클래스 타입으로 변환되는 것

- 명시적으로 타입 변환을 하지 않아도 된다

- 부모타입으로 자동변환된다

Person p1 = new Student();

(예시)

//Upcasting: 참조 자료형에 설계된 멤버에만 접근 가능
		Animal dog2 = new Dog("아지"); 
		dog2.eat();
		dog2.walk();
		//dog2.bark(); // 불가
  • 다운캐스팅

- 업캐스팅된 것을 원래대로 되돌리는 것

- 명시적으로 타입 변환을 해야 한다

- 다운캐스팅시 어떤 클래스를 객체화한 것인지 알고자 한다면 instanceof를 사용한다

if(obj instance of Student) 
 
 true이면 걱정하지 말고 
 (Student)obj으로 다운캐스팅 가능

(예시)

//Animal 참조에서 Dog 참조로 바꾸기 -> 다운 캐스팅
		((Dog)dog2).bark(); //일시적으로 가능

 

 

  • 다형성

- 같은 타입이지만 실행 결과가 다른 객체를 이용할 수 있는 성질

- 자바는 부모 클래스로의 타입변환을 허용한다

 

(예시)

//Dog[] pets = new Dog[3];
		Animal[] pets = new Animal[3];
		pets[0] = dog1;
		pets[1] = (Dog)dog2;
		pets[2] = new Dog("멍멍이");
		pets[2] = new Cat("아즈라엘");
		
		for(Animal pet: pets) {
			pet.eat();
			pet.walk();
			
			if(pet instanceof Dog) {
				((Dog)pet).bark();
			}else if(pet instanceof Cat) {
				((Cat)pet).meow();
			}
		}

 

 

02. 추상클래스


  • 추상화란?

- 객체의 속성과 기능 중 중요한 것들은 남기고 필요없는 것은 없애는 것

- 객체들간의 공통되는 특성을 추출하는 것

 

  • 추상 클래스란?

- 실제 클래스의 공통적인 특성을 추출해서 만든 클래스

- 실제 클래스를 만들기 위한 부모 클래스로만 사용

     * 스스로 객체가 될 수 없다

- 확장을 위한 용도로만 사용(실체화 하지 않음)

- 하나 이상의 추상 메서드를 가짐

- 속성(필드)와 기능(메서드)를 정의할 수 있다

 

  • 추상 메서드

- 구현이 불가능한 메서드로 선언만 한다

- 추상 클래스를 상속하는 실제 자식 클래스는 추상 메서드를 반드시 구현해야 한다

- 추상 메서드는 추상 클래스에만 존재한다

 

 

  • 추상 클래스의 선언

- 클래스 선언에 abstract 키워드

public abstract class 클래스명{
    //필드
    //생성자
    //메소드
}

 

  • 추상 클래스의 상속

- extends 키워드 사용

- 추상 클래스를 상속하는 클래스는 반드시 추상 클래스 내의 추상 메서드를 구현해야 함

- 특정 기능 구현을 강요하는 측면도 있음(ex. 스포츠카의 브레이크 기능은 꼭 구현되어야 함)

- 자식 클래스에서 부모클래스의 기능을 반드시 오버라이드해서 기능 구현 재정의 필수

 

  • 추상클래스의 활용

- 여러 클래스들이 상당수 공통점을 가지고 있으나 부분적으로 그 처리 방식이 다른경우,

부모클래스를 추상클래스로 정의하여 자식 클래스들이 각각 해당 메서드를 구현하게 강제하는 경우

 

 

(예제)

package com.javaex.oop.shape.v1;

//추상 클래스
public abstract class Shape {
	protected int x;
	protected int y;
	
	public Shape(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
	//추상 클래스는 내부에 반드시 하나 이상의 추상메서드가 있어야
	public abstract void draw();
	public abstract double area();
	
	
}
package com.javaex.oop.shape.v1;

public class Rectangle extends Shape {
	protected int width;
	protected int height;
	
	public Rectangle(int x, int y, int width, int height ) {
		super(x, y);
		this.width = width;
		this.height = height;
	}

	@Override
	public void draw() {
		System.out.printf("사각형[x=%d, y=%d, w=%d, h=%d, area=%f]을 그렸어요 %n"
				, x,y,width, height, area());
	}

	@Override
	public double area() {
		return width * height;
	}
}
package com.javaex.oop.shape.v1;

public class Circle extends Shape {
	protected double r;	//반지름
	
	public Circle(int x, int y, double r) {
		super(x, y);
		this.r = r;
	}
	
	@Override
	public void draw() {
		System.out.printf(
				"원[x=%d, y=%d, r=%f, area=%f]을 그렸어요 %n", x,y,r,area());
	}

	@Override
	public double area() {
		
		return Math.PI * Math.pow(r, 2);
	}

}
package com.javaex.oop.shape.v1;

public class ShapeApp {

	public static void main(String[] args) {
		//Shape s = new Shape();	// 추상클래스는 객체화 할 수 없다
		Rectangle r = new Rectangle(10,20,100,50);
		r.draw();
		
		Circle c = new Circle(10,10,30);
		c.draw();
		
	}
}​

 

 

  • 추상 클래스 특징

1. 오직 상속을 목적으로 사용

2. 추상 클래스를 상속받는 sub Class는 무조건 추상메소드를 오버라이드를 해야만 한다. 

  하지 않을 경우 추상클래스화 되서 객체를 생성할 수 없다. 

3. 추상메소드는 강제성을 발휘하기 때문에 꼭 오버라이드를 해야만 한다. 

4. 추상클래스 보다 더 추상화 된 것은 interface이다

5. 추상메소드, 상수를 갖는게 원칙(+ default 메소드)

6. 인터페이스는 다중상속을 허용한다 (모호성이 발생하지 않는다. 이름만 있을뿐, 내용이 없으니까)

7. 다중상속을 대체하기 위해 만들어졌다. 

 

 

 

03. 인터페이스


  • 인터페이스란?

- 서로 관계가 없는 물체들이 상호작용을 하기 위해 사용하는 장치나 시스템

- 클래스 구조상 관계와 상관없이 클래스들에 의해 구현될 수 있는 규약

 

  • 인터페이스 사용 목적

- 클래스들 사이의 유사한 특성을 부자연스러운 상속 관계를 설정하지 않고 얻어냄

- 개발 코드를 수정하지 않고, 가용하는 객체를 변경할 수 있도록 하기 위함(다형성) (부품처럼 손쉽게 업그레이드)

 

- Point는 굳이 부자연스럽게 면적 구하는 메소드를 상속받을 필요 없음, 그러나 그리는 부분은 필요! --> 인터페이스 사용 이유!!!

 

  • 인터페이스 활용

- 하나 혹은 그 이상의 클래스들에서 똑같이 구현되어질 법한 메서드를 선언하는 경우

- 클래스 자체를 드러내지 않고 객체의 프로그래밍 인터페이스를 제공하는 경우

 

  • 추상클래스와 인터페이스 차이점

- 추상클래스: 상속관계에서 "확장"

                  //부모클래스로 자식객체를 참조 할 수 있다

- 인터페이스: 상속관계 상관없이 비슷한 규약

                  //인터페이스로 구현한 객체를 참조할 수 있다

 

 

  • 특정 객체가 특정인터페이스의 구현체인지 알아볼 때 instance of 사용( 구현체 확인 여부)
Point p = new Point(100, 100);
		
	System.out.println("p는 Drawale을 구현했는가?" + (p instanceof Drawable ? "Drawable" : "Drawable이 아니다"));

 

 

  • 인터페이스 선언
public interface 인터페이스명{
    //추상메소드(abstract 키워드를 지정하지 않아도 됨)
    //당연히 인터페이스명은 추상메소드 밖에 없어서 abstract따로 안써줘도 알아먹음
}

 

  • 인터페이스 구현
public class Point implements 인터페이스 명{

}

 

  • 다중 상속을 지원하지 않는 자바에서 다중 상속의 장점을 활용할 수 있음
public class Point extends 부모클래스 implements 인터페이스1, 인터페이스2.. {

}
  • 인터페이스 예시
interface ss{
	//상수, 추상메소드
	final static int num = 100; //final staic 안붙여도 인식
	abstract void disp();	//abstract 안써도 있다고 인식
}
interface sss extends ss{
	final static int num = 100; //final staic 안붙여도 인식
	abstract void disp();	//abstract 안써도 있다고 인식
}

interface ssss extends ss, sss{ // 클래스 - 인터페이스: implements , 인터페이스- 인터페이스: extends 쓴다
	final static int num = 100; //final staic 안붙여도 인식
	abstract void disp();	//abstract 안써도 있다고 인식
}
class First implements ssss{	//오버라이드해서 인스턴스로 쓰던가, abstract 써서 추상클래스로 쓰던가

	@Override
	public void disp() {
		
	}
}
  • 인터페이스 명명 

- 자바 기준 주로 ~able이라고 명명한다

 

 

  • 그림판에서의 추상클래스 vs 인터페이스 

- 추상클래스는 실선

- 인터페이스는 점선

 

 

  • 일반클래스 vs 추상클래스 vs 인터페이스
  일반클래스 추상클래스 인터페이스
메소드 모두 실체 메소드 실체메소드
추상메소드
모두 추상 메소드
필드 가질 수 있음 가질 수 있음 가질 수 없음
상수필드는 가능
(상수필드: final, static)
객체화 가능 불가 불가

 

  • 실체 메서드 (Concrete Method)

- 메서드의 구현을 포함한 일반적인 메서드를 Concrete Method라 함

- 추상 메서드의 반대 개념

- 반드시 default를 앞에 써줘야 함

 

  • 정리

- 추상 클래스와 인터페이스 모두 규약으로서의 의미가 강하지만

추상 클래스는 객체를 일반화한 공통 필드와 메서드의 정의에 집중 (종적 확장)

인터페이스는 자연스러운 상속 관계를 해치지 않으면서도 추가 내용을 규정할 수 있음(횡적 확장)

 

 

 

04. 예외처리


  • 예외

- 프로그램이 실행되는 동안 발생할 수 있는 비정상적인 상태 

- 컴파일시의 에러가 아닌 실행시의 에러를 예외라 함

 

  • 자바의 예외처리

- Exception 클래스 정의 

- 기본적인 예외는 자바에 미리 정의된 예외를 통해 처리 가능 

- 사용자가 필요한 예외를 직접 정의할 수 있음 

- 예상되는 예외는 미리 처리해주면 비정상적인 프로그램의 종료를 피할 수 있음

- 예외처리는 프로그램의 신뢰도를 높여줌

 

  • try catch finally

 

  • 주요 예외 클래스

* Exception: 모든 예외 처리 가능( 모든 예외의 조상)

* 구체적 예외 --> 일반적 예외 순서로 코드 짜기

 

(예시)

		try {
			//예외 발생 가능 영역
			num = scanner.nextInt();
			result = 100/num;
		}catch(InputMismatchException e) {
			System.err.println("정수로 해 주세요");
		}
		catch(ArithmeticException e) {
			System.err.println("0으로는 나눌 수 없어요");
		}
		catch(Exception e){
			e.printStackTrace();
		}finally {
			System.out.println("예외처리 종료");
			// 예외 유무 관계 없이 가장 마지막에
			// 자원 정리 작업에 많이 활용
		}

 

 

  • 강제 예외 발생

- 메서드 정의 시 예외 처리

- 해당 메서드를 호출하는

 

 

'Java' 카테고리의 다른 글

[JAVA]Date와 SimpleDateFormat으로 간단하게 시간 표시하기  (0) 2022.01.03
[Chapter 10] Object클래스  (0) 2021.12.15
[chapter04] 제어문  (0) 2021.12.10
[chapter 05 ] 배열  (0) 2021.12.09
[Chapter11] 제네릭과 컬렉션  (0) 2021.12.08