1. 추상 클래스
상속을 위해 만든 부모 클래스의 메소드는 상속을 목적으로 했을 뿐 해당 클래스에서 별다른 기능을 하진 않음.
=> 굳이 부모 클래스에 있을 필요가 없음. 메서드 구현 없이 메서드 선언만 하면 됨.
----- 구현은 하위클래스에서 맘대로 해~
추상 클래스: 추상 메서드를 1개라도 포함한 클래스. abstract 키워드 사용. -- 모든 메서드가 다 추상일 필요 X
추상 메서드: 구현하지 않고 선언만 한 메서드. abstract 키워드 사용.
=> 완성이 안 됐기 때문에 객체 생성 불가
==> 하위 클래스에 상속을 목적으로 함. ==> 하위 클래스에 아웃라인(틀) 제공
-- 하위 클래스에 추상 메서드를 제공하여 각 하위 클래스마다 적합하게 재정의해 사용할 수 있도록 함.
//추상 클래스
abstract class Parent {
// 추상 메서드. (구현 X). 상속 목적. 하위클래스가 자기한테 맞게 구현해서 사용.
public abstract void f1();
// 구현 메서드 포함 가능
public void f2() {
System.out.println("Parent f2()");
}
}
// Child가 객체를 만들려면 상속받은 추상메서드를 모두 구현해야 함.
class Child extends Parent {
@Override
public void f1() {
// TODO Auto-generated method stub
System.out.println("Child에서 추상메서드 구현");
}
public void f3() {
System.out.println("Child f3()");
}
}
public class ParentMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
//Parent p = new Parent(); //추상클래스는 객체 생성 불가.
Child c = new Child();
c.f1();
c.f2();
c.f3();
//주로 업캐스팅으로 사용.
Parent pc = new Child();
pc.f1(); // 재정의된 메서드로 실행됨.
pc.f2();
((Child)pc).f3(); //다운캐스팅으로 자식클래 메서드 실행.
}
}
예1. 도형 그리기
- 파라메터 값에 배열 넣어 호출.
Point[] arr = new Point[] {new Point (6,9)} ; // 초기화 해서 생성. 방 값 안넣음
(=)
new Point[] {new Point(6,9)}
package oop2;
//한 개의 좌표
class Point {
int x;
int y;
public Point() {
}
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "Point [x=" + x + ", y=" + y + "]";
}
}
//도형 그리기 클래스
abstract class Shape {
Point[] points; // 포함관계: 멤버변수로 다른 타입의 클래스
public abstract void draw(); // 하위 클래스에서 각 클래스에 적합하게 구현
}
class Circle extends Shape {
int r; // 반지름 변수
public Circle() {
points = new Point[1]; // 배열 생성
points[0] = new Point(5, 5); // 중심점 좌표
r = 10; // 반지름
}
// 파라메터로 받은 값으로 멤버변수 초기화
public Circle(Point[] arr, int r) {
points = arr;
this.r = r;
}
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("원을 그림");
System.out.println("중심점: " + points[0]);
System.out.println("반지름: " + r);
}
}
class Rectangle extends Shape {
public Rectangle() {
points = new Point[] { new Point(1, 2), new Point(3, 4) };
}
public Rectangle(Point[] points) {
this.points = points;
}
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("사각형을 그림\n점 2개의 좌표");
for (int i = 0; i < points.length; i++) {
System.out.println(points[i]);
}
}
}
class Triangle extends Shape {
public Triangle() {
points = new Point[] { new Point(1, 2), new Point(3, 4), new Point(5, 6) };
}
public Triangle(Point[] points) {
this.points = points;
}
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("삼각형을 그림\n점 3개의 좌표");
for (int i = 0; i < points.length; i++) {
System.out.println(points[i]);
}
}
}
public class ShapeMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
Shape[] arr = { new Circle(), new Triangle(), new Rectangle(),
new Circle(new Point[] { new Point(4, 5) }, 8),
new Triangle(new Point[] { new Point(7, 9), new Point(3, 4), new Point(1, 9) }),
new Rectangle(new Point[] { new Point(3, 8), new Point(9, 1) }) };
for (int i = 0; i < arr.length; i++) {
arr[i].draw();
}
}
}
2. 인터페이스
(회사에서는 다 인터페이스 기반으로 구성한다.)
: 완전추상클래스
: 상수와 추상 메서드로만 구성
=> 객체 못 만듦. 상속 목적. (클래스 생성 창에서 add.. 선택)
=> 잭 역할... (변신로봇의 무기 교체 잭..)
- (동일한 인터페이스를 상속받아서 다양한 형태로 구현한) 객체들을 교체해서 사용하도록 연결하는 이음매 역할.
- DB 종류가 다양해서 종류에 따라 다르게 구현해줘야 함.
- 이 때 interface로 구현해 놓으면 필요에 따라 교체할 때 빠르고 편함. (유지보수 쉬움. 한 번만 바꾸면 싹 다 바뀜.)
interface A {
int MAX = 100; // public final static 없어도 자동으로 상수 됨.
void f1(); // public abstract 없어도 자동으로 추상 메서드 됨.
}
A 변수명 = new 사용할객체명();
- 상속 키워드: implements
---- 다중 상속 가능
API를 여러개 상속받을 필요가 있을 때 우회적으로 인터페이스 사용.
예1) 인터페이스 다중 상속
interface A {
public void f1();
}
interface B {
public void f2();
}
//인터페이스는 다중 상속 가능
class InterTest2 implements A, B {
@Override
public void f2() {
// TODO Auto-generated method stub
System.out.println("f2()");
}
@Override
public void f1() {
// TODO Auto-generated method stub
System.out.println("f1()");
}
}
public class InterTest2Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
InterTest2 t = new InterTest2();
t.f1();
t.f2();
}
}
예2) 부모클래스와 인터페이스 동시 상속
package oop2;
import java.awt.Frame;
// Thread 의 인터페이스 버전이 Runnable
class Test extends Frame implements Runnable {
@Override
public void run() { //쓰레드 실행코드 작성
// TODO Auto-generated method stub
for (int i = 1; i <= 10; i++) {
this.setTitle(i + "번째 타이틀");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class InterTest3Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test t = new Test();
t.setSize(300, 200);
t.setVisible(true);
Thread th = new Thread(t);
th.start();
}
}