2024.03.05
추상클래스
- 추상화라는 것은 구체적인 개념으로부터 공통된 부분들만 추려내어 일반화 할 수 있도록 하는 것을 의미한다. 다시 말해서 일반적으로 사용할 수 있는 단계가 아닌 아직 미완성(未完成)적 개념인 것이다. 추상클래스는 일반클래스와 달리 미완성되어 있는 클래스이기 때문에 객체 생성이 불가능하고 상속관계를 맺은 자식 클래스가 객체 생성되어야 사용이 가능하다.
//추상클래스
//미완성된 개념으로 단독으로 객체 생성이 불가능하고 일반적으로 자식클래스에
//상속되어져 사용함
abstract class A{
private int x;
public void setX(int x) {
this.x = x;
}
public int getX() {
return x;
}
}
class B extends A{
int b = 200;
}
public class AbstractMain01 {
public static void main(String[] args) {
// A a = new A();
B b = new B();
b.setX(2);
System.out.println(b.getX());
}
}
추상메서드
- 추상클래스는 일반적으로 한 개이상의 추상메서드를 갖는다. 추상메서드는 일반메서드와 다르게 메서드가 수행할 코드를 갖고 있지 않다. 따라서 추상메서드는 상속시 자식 클래스에 반드시 구현되어야 자식클래스가 객체 생성될 수 있다.
//부모클래스
abstract class AbsEx{
int a = 100;// 변수
public int getA() {
return a;
}
//추상메서드
public abstract int getB();
abstract public int getC();
}
//추상클래스
abstract class AbsEx2 extends AbsEx{
//추상클래스를 추상클래스에 상속하면 추상메서드 구현의 의무가 없음
String msg = "신세계";
//추상메서드
public abstract String getMsg();
//부모클래스의 추상메서드 구현
@Override
public int getB() {
return 200;
}
}
public class AbstractMain04 extends AbsEx2{
//부모클래스의 추상메서드를 구현
@Override
public String getMsg() {
return msg;
}
@Override
public int getC() {
return 300;
}
public static void main(String[] args) {
AbstractMain04 am = new AbstractMain04();
System.out.println(am.getA());
System.out.println(am.getB());
System.out.println(am.getC());
System.out.println(am.getMsg());
}
}
추상 클래스의 상속관계
- 추상 클래스들간에도 상속이 가능하다. 일반 클래스들간의 상속과 유사하지만 추상 클래스들간의 상속에서는 상속 받은 추상 메서드들을 꼭 재정의할 필요는 없다. 그냥 상속만 받아두고 있다가 언제가 일반 클래스와 상속관계가 이루어 질 때가 있을 것이다. 이때 재정의 하지 못했던 상속 받은 추상 메서드들을 모두 일반 클래스 내에서 재정의해도 되기 때문이다.
인터페이스
- 클래스가 멤버필드(변수,상수)와 실행 가능한 메서드를 구성요소로 한다면 인터페이스는 상수와 추상메서드를 구성요소로 한다. 상수는 static한 상수이기 때문에 객체 생성 없이 호출이 가능하지만 추상메서드는 일반클래스에 구현되어야만 사용이 가능하다.
상수
// 인터페이스
interface A1{
//상수
public static final int w = 10; // 원형
int X = 20; // 상수
static int Y = 30; // 상수
final int Z = 40; // 상수
}
메서드
// 인터페이스
interface A2{
//추상메서드
public abstract void abc(); //원형
void def();
}
인터페이스의 장점
- 인터페이스를 이용하면 정의해야 하는 메소드(프로그램기능)을 표준화하고 강제할 수 있다. 또한 메소드화 시켜야 하는 기능을 분류해야 하는 고민 없이 구현만 하면 되므로 개발시간을 단축시킬 수있다. 일반 클래스 상속을 이용해서 자식 클래스들의 관계를 맺는 것보다 간편하게 관계 를 맺을 수 있다.
인터페이스 다중 상속
- 자바는 단일 상속만을 허용한다. 하지만 인터페이스는 클래스에 다중 구현 가능하다.
interface Inter1{
public int getA();
}
interface Inter2 {
public int getB();
}
//인터페이스를 인터페이스에 상속
interface Inter3 extends Inter1, Inter2{
public int getData();
}
interface Inter4{
public String getMsg();
}
//인터페이스를 클래스에 다중 구현 가능
//클래스 다중 상속 불가능(단일 상속만 인정)
public class InterfaceMain05 implements Inter3,Inter4{
@Override
public int getA() {
return 10;
}
@Override
public int getB() {
return 20;
}
@Override
public int getData() {
return 30;
}
@Override
public String getMsg() {
return "서울";
}
public static void main(String[] args) {
InterfaceMain05 im = new InterfaceMain05();
System.out.println(im.getA());
System.out.println(im.getB());
System.out.println(im.getData());
System.out.println(im.getMsg());
}
}
Enum
- 열거 형은 상수를 가지고 생성되는 객체들을 한 곳에 모아둔 하나의 묶음이다. 자바에서 열거 타입이 있기 전에는 코드화된 정수나 문자를 이용하여 해당 값을 표현했음
//열거형 객체
enum Lesson{
//열거형 상수
//문자열 상수
JAVA,XML,JSP
}
public class EnumMain02 {
public static void main(String[] args) {
System.out.println(Lesson.JAVA);
System.out.println(Lesson.XML);
System.out.println(Lesson.JSP);
System.out.println("---------------");
System.out.println(Lesson.JAVA.toString());
System.out.println(Lesson.XML.toString());
System.out.println(Lesson.JSP.toString());
System.out.println("---------------");
//열거 객체의 문자열을 반환
System.out.println(Lesson.JAVA.name());
System.out.println(Lesson.XML.name());
System.out.println(Lesson.JSP.name());
//열거 객체의 순번(0부터 시작)을 반환
System.out.println(Lesson.JAVA.ordinal());
System.out.println(Lesson.XML.ordinal());
System.out.println(Lesson.JSP.ordinal());
}
}
toString()을 오버라이딩하여 커스터마이징이 가능하다.
enum Gender {
MALE, FEMALE;//세미콜론 넣어도 되고 안넣어도 됨
@Override
public String toString() {
switch(this) {
case MALE:
return "남자";
// case FEMALE:
default:
return "여자";
}
}
}
public class EnumMain03 {
public static void main(String[] args) {
System.out.println(Gender.MALE);
System.out.println(Gender.FEMALE);
System.out.println("--------------------");
System.out.println(Gender.MALE.toString());
System.out.println(Gender.FEMALE.toString());
}
}
values()라는 함수로 enum을 Object[] 형식의 배열로 변환 가능하다. 또한 생성자를 통해 값을 지정하는 것 또한 가능하다. 단 자주 사용하는 방식은 아니다.
enum Item2{
ADD(5),DEL(11),SEARCH(2),CANCEL(22);
//위에 지정한 상수 값들을 저장하기 위한 공간
private final int var;
//생성자
Item2(int var){
this.var = var;
}
public int getVar() {
return var;
}
}
public class EnumMain05 {
public static void main(String[] args) {
for(Item2 i : Item2.values()) {
System.out.println(i+", "+i.getVar());
}
}
}
내부 클래스
- 특정 클래스 내에 또 다른 클래스가 정의되는 것을 의미한다. 이런 내부 클래스가 필요한 이유는 지금까지 작업해 왔던 클래스들과는 다르게 독립적이지는 않지만 하나의 멤버처럼 사용할 수 있는 특징이 있다.
class Outer{
//Outer의 멤버 변수
int x = 100;
//내부클래스 (멤버 내부클래스)
class Inner {
//Inner의 멤버 변수
int y = 200;
}
}
public class MemberMain01 {
public static void main(String[] args) {
Outer outer = new Outer();
//Outer 내부클래스인 Inner클래스를 객체 생성
Outer.Inner inner = outer.new Inner();
//Outer의 멤버변수 호출
System.out.println(outer.x);
System.out.println(inner.y);
}
}
내부 클래스의 종류
종류 | 설명 |
Member | 멤버 변수나 멤버 메서드들과 같이 클래스가 정의된 경우에 사용한다. |
Local | 특정한 메서드 내에 클래스가 정의된 경우에 사용 |
Static | static 변수(클래스 변수)와 같이 클래스가 static으로 선언된 경우에 사용 |
Anoymous | 참조할 수 있는 이름이 없는 경우에 사용 |
멤버 내부 클래스
- 객체를 생성해야만 사용할 수 있는 멤버들과 같은 위치에 정의되는 클래스를 말한다. 즉 내부 클래스를 생성하려면 외부 클래스의 객체를 생성한 후에 생성할 수 있다.
class Outer2 {
//Outer2의 멤버 변수
private int x = 100;
//내부클래스
class Inner2{
private int y = 200;
public void make() {
System.out.println(x);
System.out.println(y);
}
}
}
public class MemberMain02 {
public static void main(String[] args) {
Outer2 ot = new Outer2();
//내부클래스객체생성
Outer2.Inner2 oi = ot.new Inner2();
oi.make();
}
}
로컬 내부 클래스
- Local 내부 클래스는 특정 메서드 안에서 정의되는 클래스를 말한다. 다시 말해서 특정 메서드 안에서 선언되는 지역변수와 같은 것이다. 메서드가 호출될 때 생성할 수 있으며 메서드의 수행력이 끝나면 지역변수와 같이 자동 소멸된다.
public class LocalMain01 {
public void innerTest() {
//로컬 내부 클래스:메서드내에 클래스 정의
class Inner{
public void getData() {
System.out.println("Local 내부클래스");
}
}
//내부 클래스 객체 생성
Inner i = new Inner();
i.getData();
}
public static void main(String[] args) {
LocalMain01 lm = new LocalMain01();
lm.innerTest();
}
}
스태틱 내부 클래스
- static 내부 클래스로 어쩔 수 없이 정의하는 경우가 있는데 그것은 바로 내부 클래스 안에 static변수를 가지고 있다면 어쩔 수 없이 해당 내부 클래스는 static으로 선언하여야 한다.
public class StaticMain {
// static 내부클래스
// static 내부클래스를 포함한 클래스를 먼저 객체 생성하는것이 아니라
// static 내부클래스를 단독으로 객체 생성해서 사용
public static class Inner{
//인스턴스 변수
int iv = 100;
//static 변수
static int cv = 200;
//static 메서드
public static void make() {
System.out.println("하하");
}
}
public static void main(String[] args) {
// StaticMain st = new StaticMain();
// StaticMain.Inner si = st.new Inner();
//static 내부클래스 객체 생성
Inner inner = new Inner();
//인스턴스 변수 호출
System.out.println(inner.iv);
//static 변수 호출
System.out.println(Inner.cv);
//static 메서드 호출
inner.make();
}
}
익명 내부 클래스
- 익명이란? 이름이 없는 것을 의미한다. 이것을 자바의 프로그램적으로 해석하면 정의된 클래스의 이름이 없다는 것이 된다.
class Inner7{
public void disp() {
System.out.println("부모클래스의 disp");
}
}
public class AnoymousMain {
public void make() {
// //로컬 내부 클래스
// class Inner extends Inner7{
// @Override
// public void disp() {
// System.out.println("내부클래스의 disp");
// }
// }
// //내부클래스 객체 생성
// Inner i = new Inner();
//익명 내부 클래스: 클래스를 정의하는 부분과 객체를 생성하는 부분이
// 합쳐진 형태
//Inner7 클래스가 상속된 이름없는 클래스를 객체 생성
Inner7 i = new Inner7() {
@Override
public void disp() {
System.out.println("내부클래스의 disp");
}
};
i.disp();
}
public static void main(String[] args) {
AnoymousMain a = new AnoymousMain();
a.make();
}
}
'IT 국비 교육' 카테고리의 다른 글
쌍용교육센터 - 14일 (2) | 2024.03.07 |
---|---|
쌍용교육센터 - 13일 (1) | 2024.03.06 |
쌍용교육센터 - 11일 (0) | 2024.03.04 |
쌍용교육센터 - 10일 (0) | 2024.02.29 |
쌍용교육센터 - 9일 (0) | 2024.02.28 |