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 |