본문 바로가기

JAVA

#5 인터페이스, final, 추상클래스, 배열, 2차원 배열

<interface> 인터페이스

형식)

interface 인터페이스명

{

//필드

[고정 public static final] int su=10;// final변수는 값을 초기화해서 유지할 값을 명시!!

//선언된 메소드

[고정 public abstract] void print();

}

------> 저장: 인터페이스명.java ---컴파일---> 인터페이스명.class

- 클래스에 다중 상속을 구현할 수 있다.

- interface의 구성멤버는 필드, 선언된 메소드로만 구성.

void print(){

} -----> 정의된 메소드, 구현된 메소드!!

void print(); ----> 선언된 메소드 (바디없는,영역괄호없는 메소드)

- 서로 다른 제품에 연결할 수 있는 공통연결 모듈을 의미.

- ★인터페이스는 어떻게 사용? 클래스에 구현해서 사용!!

키워드: implements

class 클래스명 implements 인터페이스명

{

구현의 약속

}


※ 오버라이딩(메소드 재정의)시 주의할 점

---> 접근제한자는 부모와 같거나 확장해야 함!!

부모클래스 자식클래스

디폴트 ----> 디폴트,protected,public

protected ----> protected,public

public ----> public


<클래스와 인터페이스 간의 상속문법>

class A{}

class B extends A{//extends 뒤에는 상속 받고자 하는 한 개의 클래스만 정의

//확장 (자식클래스를 확장클래스!!)

}


interface A{}

class B{}

class C implements A extends B {

//에러: 클래스와 인터페이스를 동시에 상속할 때는 클래스 먼저, 인터페이스 나중

//implements가 먼저 나오면 컴파일러가 extends Object를 추가해줌!!

} ---> (X)

class C extends B implements A{

} ---> (O)


<final>

1. final 자료형 변수명;

----> 마지막 변수 : 상수(constant)

----> 상수의 식별을 위해 전체 대문자로 표기.

예) final int MAX=100;

2. final 리턴형 메소드명(){}

---> 마지막 메소드 : 오버라이딩(메소드 재정의) 할 수 없는 메소드.

3. final class 클래스명{}

---> 마지막 클래스 : 자식클래스를 갖지 않는 클래스

---> 완벽한 클래스(자식통한 기능확장을 원치 않는다)

---> 보안

예) public final class String{}

public class My extends String{

//에러발생: final클래스는 extends 뒤에 사용 금지.

}

<추상클래스> abstract class

- 후손 class를 제어할 목적으로 사용.

- 객체화 될 수 없는 클래스.

- 구현(정의)된 메소드와 선언된 메소드로 구성.

- 스스로 객체생성 불가(new 사용X), 후손class 객체생성(자식은 부모다!!)해서 사용.

형식)

class A{

정의,구현된 메소드만

void hello(){}

}

abstract class B{

정의된 메소드

void hello(){}

선언된 메소드

abstract void print(); //abstract생략 불가

}

interface C{

선언된 메소드만!!

abstract void print(); //abstract생략 가능

}

※ 추상클래스의 사용? 자식클래스를 객체생성해서 사용!!

----> 자식은 부모다!!

추상클래스 Lime -추상메소드 print , 자식클래스 My

class My extends Lime{//부모가 갖는 print를 반드시 정의해라!!

public void print(){

}

}


Lime lime = new Lime(); ---->에러: 추상클래스는 new 키워드 사용 불가!!

Lime lime;

lime = new My();

My m = new My();

lime.print();//부모를 통한 자식호출

m.print();//직접호출


<배열> Array

- 데이터형이 동일한 자료에 같은(하나의) 변수명을 정의한 자료들의 집합.

- 데이터형이 동일한 자료 ===> 조건

같은(하나의) 변수명을 정의 ===> 특성

자료들의 집합. ===> 정의

- 데이터를 구분하기 위해서 번지를 사용.

int su1; ----> 한 개의 정수를 저장할 준비.

int su2[]; ----> 여러개의 정수를 저장할 준비.

- 시작번지는 0번지

- 첫번째 데이터부터 인덱스(자동번호)가 부여.

인덱스는 0부터 시작해서 1씩 증가!!

- 배열의 크기가 정해지면 인덱스를 벗어나는 참조를 하면 안됨.

int su3[]={10,20,30};

번지 ===> 0 1 2

-----> 배열의 크기(요소 갯수) : 3 (인덱스 0~2)

int i=103;

//103데이터를 변수를 통해 출력

System.out.println(i); ---> 103

//20데이터를 변수를 통해 출력

System.out.println(su3[1]); ---> 20

System.out.println(su3[3]);

===> 에러발생: ArrayIndexOutOfBoundsException !!

- 배열의 크기(배열의 요소 갯수)를 구하는 속성: 배열명.length !!

- 배열선언시 []는 변수명 앞에 또는 뒤에 붙여도 상관이 없다.

int su[];

int []su;

int i;

int j;

int k;

===> int i,j,k;

차이점)

int su1[],su2; ---> su1은 배열, su2는 int변수

int [] su1,su2; ---> su1,su2 둘다 배열

배열 형식)

1. 자료형 배열명[] = { 데이터List(콤마로 구분되는 데이터) };

---> 배열선언과 동시에 데이터를 초기화.(이미 데이터가 확정되었을때 사용)

---> ※주의: 배열선언과 데이터 초기화하는 부분을 따로 작성할 수 없음!!

int [] su;//배열선언

su = {1,2,3,4,5};// 배열초기화 (X)

int i = 6;

int [] su = {1,2,3,4,5,6};//선언과 초기화 (O)

A a = new A();

A [] su2 = {new A(), new A(), a};

2. 자료형 배열명[] = new 자료형[배열크기]; //---> 1차원배열 객체생성식 : 암기

---> 프로그램 실행 도중 데이터 값을 변경할 때 주로 사용.

---> 배열선언과 데이터 초기화하는 부분을 따로 작성하는 것이 가능.

---> 배열크기[]는 반드시 자료형 뒤에 위치해야 함.

배열크기는 정수값이 입력되어야함.

int []su ; //배열선언

su = new int[5]; //배열초기화

===> int []su = new int[5];//앞으로 int데이터를 5개 받겠습니다.(5개의 빈방만들기!!)

su[0]=11;

su[1]=22;

su[2]=33;

su[3]=44;

su[4]=55;

※ 배열객체생성을 하게 되면 그 위치에 상관없이 각 방에는 초기값이 부여됨 (멤버변수처럼)!!

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.Reader;

public class AbstractTest {

public static void main(String[] args) throws IOException {

//추상클래스는 'new'키워드 사용X

//Shape s = new Shape();

Shape s;

s = new Circle();

s = new Rectangle();

s = new Triangle();

s.draw();

//BufferedReader in = new 생성자();

//BufferedReader(Reader in)

//BufferedReader(Reader in, int sz)

//InputStreamReader(InputStream in)

InputStream is=System.in;

Reader r = new InputStreamReader(is); //new Reader();

BufferedReader in = new BufferedReader(r);

String str = in.readLine();

}//main

}

class My{

int su;//멤버변수!! --> 기본값존재 ---> 0

String str;//멤버 ----> 기본값존재 ---> null

int suArry[] = new int[5];//suArry[0]~ suArry[4]생성

}

public class ArrayTest {

public static void main(String[] args) {

My m = new My();

System.out.println("su = "+ m.su);

System.out.println("str = "+ m.str);

System.out.println("suArry배열크기: "+ m.suArry.length); //5

for(int i=0; i< m.suArry.length; i++) {//suArry배열의 인덱스 표현: 0~4

System.out.println("suArry["+i+"]번지="+ m.suArry[i]);

}

System.out.println("===========================");

int suArry2[] = new int[5];//suArry2[0]~ suArry2[4]생성

for(int i=0; i< suArry2.length; i++) {//suArry2배열의 인덱스 표현: 0~4

System.out.println("suArry2["+i+"]번지="+ suArry2[i]);

}

}//main

}


import java.util.Calendar;

import java.util.Date;

import java.util.GregorianCalendar;

public class CurrentTimeTest {

public static void main(String[] args) {

//2018년 5월 1일 3시 16분 30초 (화요일)

//날짜관련클래스: java.util패키지 ===> Date, Calendar ----> get(int field);

Date d = new Date();

int hours = d.getHours();

System.out.println("Date클래스 통한 시간정보: "+ hours);

Calendar c = new GregorianCalendar(); //new Calendar();

//c = Calendar.getInstance();

ㅊ//c ==> 현 시스템 날짜의 모든 정보가 저장!!

System.out.println("현재년도1: "+c.get(1));

System.out.println("현재년도2: "+c.get( Calendar.YEAR ));

int year = c.get(Calendar.YEAR);

int month = c.get(Calendar.MONTH) + 1; //1월~12월 ---> get() : 0~11

int date = c.get(Calendar.DATE);

//int h = c.get(Calendar.HOUR); //오후 4시 ---> 4리턴

int h = c.get(Calendar.HOUR_OF_DAY); //오후 4시 ---> 16리턴

int m = c.get(Calendar.MINUTE);

int s = c.get(Calendar.SECOND);

//요일구하기 day

int day = c.get(Calendar.DAY_OF_WEEK);

System.out.println("day="+day);//현재 수요일!!:4 일~토요일 일요일:1 , 토요일:7

// 1 ~ 7

String dayStr="";

switch(day) {

case 4: dayStr="수요일";

}

String []dayArray= {"일","월","화","수","목","금","토"};

// 0 1 2 3 4 5 6

System.out.println(year+"년 "+month+"월 "+date+"일 "+h+"시 "+m+"분 "+s

+"초 ("+ dayArray[day-1] +"요일)");

}//main

}


import java.io.IOException;

public class Gugudan {

//단입력

public int inputDan() throws IOException{

System.out.print("원하는 단? ");

int dan = System.in.read()-48;//입력시점

//입력: 3엔터 ==> 바이트값: 51, 13, 10

System.in.read();

System.in.read();

//return 정수데이터; ==> 생략불가능

return dan;

}//inputDan

//단출력(외부에서 받은 단에 대한 1~9까지 곱한 값 출력)

public void outputDan(int dan) {

for(int i=1; i<10; i++) {//1~9

System.out.println(dan + "*"+ i +"="+ (dan*i));

}

//return; ==> 생략가능

}//outputDan

//계속여부

public char continueDan() throws IOException {

System.out.print("계속(y/n)? ");

char ch = (char)System.in.read();// a엔터

//바이트 코드값: 97, 13, 10

// (char)97 ---> 'a'

System.in.read();

System.in.read();

//'a' > 20 ===> 97 > 20

//return '\u0000';

//return 문자데이터;

return ch;

}//continueDan

}


import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

public class Gugudan2 {

BufferedReader in;

public Gugudan2() {

//초기화 코드, 선행작업

in = new BufferedReader(new InputStreamReader(System.in));

}

//단입력

public int inputDan() throws IOException{

System.out.print("원하는 단? ");

int dan = Integer.parseInt(in.readLine()); //Integer.parseInt("3") ----> 3

//parseInt("숫자로 구성된 문자열") ----> 더블quot를 제거해서 숫자변환

해 주는 기능

//return 정수데이터; ==> 생략불가능

return dan;

}//inputDan

//단출력(외부에서 받은 단에 대한 1~9까지 곱한 값 출력)

public void outputDan(int dan) {

for(int i=1; i<10; i++) {//1~9

System.out.println(dan + "*"+ i +"="+ (dan*i));

}

//return; ==> 생략가능

}//outputDan

//계속여부

public char continueDan() throws IOException {

System.out.print("계속(y/n)? ");

char ch = in.readLine().charAt(0); //char ch = "y"; 에러 -----> char ch =

"y".charAt(0);

/*

char ch1='a';

char ch2='b';

//두 문자를 비교 ==> (ch1 == ch2)

String str1 = "a";

String str2 = "b";

//두 문자열을 비교 ==> str1.equals(str2)

*/

return ch;

}//continueDan

}


import java.io.IOException;

public class GugudanTest {

public static void main(String[] args) throws IOException {

//Gugudan g = new Gugudan();

Gugudan2 g = new Gugudan2();

//호출하는메소드의 리턴형 변수명 = g.inputDan();

//int dan = g.inputDan();

//g.outputDan(dan);

System.out.println("<<구구단>>");

while(true) {

g.outputDan(g.inputDan());

boolean flag=true;

char yn;

do {

yn= g.continueDan();

//yn : 'y', 'n'

if( !(yn=='y' || yn=='Y'|| yn=='n' || yn=='N') ) {

//yn!='y' && yn!='Y'&& yn!='n' && yn!='N'

System.out.println("#잘못된 문자입력입니다!!\n 'y'또는'n'을 입

력하세요~!!");

}else {

flag=false;

}

}

while(flag);//반복문 ---> 잘못된 문자가 입력되었을때

if(yn == 'n' || yn=='N') break;

System.out.println();

}

System.out.println("-- END --");

//int su=13;

//A a = new A();

//a.hello(); new A().hello();

}//main

}



public class Hongkong implements MenuPan {//홍콩반점의 주방을 표현

//구현의 약속

@Override //어노테이션 JDK5버전 이후

public void 짬뽕() {//오버라이딩 메소드는 부모와 같은 '접근제한자'를 같거나 확장을 해야 함!!

System.out.println("매콤한 짬뽕");

}

public void 짜장면() {

System.out.println("달달한 짜장면");

}

@Override

public void 볶음밥() {}

public void 초밥() {

System.out.println("한입에 쏘~옥");

}

}


public class InterfaceTest {

public static void main(String[] args) {

//MenuPan m = new MenuPan();

//자식은 부모다!! ==> 부모가 위치할 곳에 자식이 대신 대입될수 있다.

/*MenuPan m;

m = new Hongkong();*/

MenuPan m = new Hongkong();

//부모 //자식

m.짜장면();

m.짬뽕();

//m.초밥();//부모에 정의되지 않은 자식메소드는 호출불가!!

System.out.println("coin="+ MenuPan.COIN);

}

}



abstract class GrandParent{

public GrandParent() {

System.out.println("조부모생성자");

}

public void print() {System.out.println("프린트");}//정의된 메소드

public abstract void abc();

}

abstract class Parent extends GrandParent{

public Parent(String name) {

//super();

System.out.println("부모생성자");

}

public void hello() {System.out.println("안녕");}

public abstract void def();

}


class Child extends Parent{

public Child() {

//super();

super("이름");

System.out.println("자식생성자");

}

public void good() {System.out.println("좋아~!!");}

@Override

public void def() { }

@Override

public void abc() { }

}

public class MemoryAllocateTest {

public static void main(String[] args) {

Child c = new Child();

System.out.println("==================");

c.good();

c.hello();

c.print();

}

}


public interface MenuPan {

/*public static final*/ int COIN=100;

void 짜장면();

abstract void 짬뽕();

public abstract void 볶음밥();

}


public abstract class Shape {

abstract void draw();//선언된 메소드

void hello() {//정의된 메소드

System.out.println("추상 안녕~!!");

}

}

class Circle extends Shape{

void draw() { System.out.println("원그리기"); }

}

class Rectangle extends Shape{

@Override

void draw() {

System.out.println("사각형그리기");

}

}

class Triangle extends Shape{

@Override

void draw() {

System.out.println("삼각형그리기");

}

}


<2차원 배열>

- 실제 저장은 1차원 배열과 같으나 논리적으로 데이터를 행과 열의 형태로 저장한다고 생각.

- 행사이즈는 반드시 기술해야함.

열사이즈는 생략하는 것이 가능.

int su[][];

int [][]su;

int []su[];

int su[][] = new int[행크기][열크기];

int su[][] = new int[3][];

//3*2=6 : 6개의 데이터를 3행 2열의 형태로 저장.

0 1 열

0 0 0

1 0 0

2 0 0

값 저장

==> su[1][0] = 10;

su[2][1] = 20;

su[0][1] = 30;

0 1 열

0 0 30

1 10 0

2 0 20


<가변길이 열사용> - 각 행마다 서로 다른 열을 갖는 것이 가능

int su[][] = new int[3][]; //열 사이즈를 생략

su[0] = new int[2]; //첫번째 행의 열사이즈를 지정

su[1] = new int[3]; //두번째 행의 열사이즈를 지정

su[2] = new int[4]; //세번째 행의 열사이즈를 지정

0 방 2개생성

1 방 3개생성

2 방 4개생성

행 0 1 2

int su[][] = { {1,2}, {3,4}, {5,6} };

열 0 1 0 1 0 1

su.length --->? 3 (행의 갯수와 일치)

데이터 3을 출력하고 싶다? System.out.println(su[1][0]);

int su2[][] = { {1}, {2, 3}, {4, 5, 6} };

su2[0][0] [1][0] [1][1] [2][0] [2][1] [2][2]

su2.length ----> 3 (전체행의 갯수)

각 행의 데이터 수를 출력)

su2[0] == su2첫번째 행을 표현!!

su2[0].length ----> 0행의 열(데이터)갯수 ----> 1

su2[1].length ----> 1행의 열(데이터)갯수 ----> 2

su2[2].length ----> 2행의 열(데이터)갯수 ----> 3

2차원 배열내에 전체 데이터를 출력)

for(int i=0; i<su2.length; i++){//기준!! ---> 행!! i = 0, 1, 2

for(int j=0; j<su2[i].length; j++){//열 표현

System.out.println(su[i][j]);

}

}


<Test>

import java.util.Arrays;

public class ArraysTest {

public static void main(String[] args) {

int su[]= {303, 208, 100, 578, 150};

//오름차순 정렬

Arrays.sort(su);

for (int i = 0; i < su.length; i++) {

System.out.println("su["+i+"]="+su[i]);

}

System.out.println("---------------------");

char ch[]= {'v','a','C','z','A','x','d'};

Arrays.sort(ch);

for (int i = 0; i < ch.length; i++) {

System.out.println("ch["+i+"]="+ch[i]);

}

System.out.println("---------------------");

Object names[]={"홍길동","길라임",new Boolean(true),"a김주원",new Integer(11),"정철","이순신","이성계"};

/*

int su;//속성변수!!

su=100;

su.~ (X)

Integer su2;//참조변수!!

su2 = new Integer(100);

su2.~ (O)

-------------JDK5버전 이후-----------------

===> 오토박싱,언박싱 지원!!

int su3 = new Integer(200);

Integer su4 = 200;

※ Wrapper클래스

기본자료형 래퍼클래스

byte ---> Byte

short ---> Short

int ---> Integer (정수와 관련된 속성,메소드를 감싸는 클래스!!)

long ---> Long

float ---> Float

double ---> Double

char ---> Character

boolean ---> Boolean

*/

Arrays.sort(names);

for (int i = 0; i < names.length; i++) {

System.out.println("names["+i+"]="+names[i]);

}

}//main

}


<Test2>

public class ArrayTest {

public static void main(String[] args) {

//배열선언과 초기화

//int []su;

// su={1, 2, 3, 4, 5};

//에러발생: 반드시 선언과 초기화를 함께 기술!! (X)

int []su = {1, 2, 3, 4, 5, 6,7,8,9};

//su[0] su[1] su[2] su[3] su[4]

System.out.println("su[0]번지="+su[0]);//첫번째데이터 출력

System.out.println("su[1]번지="+su[1]);//두번째데이터 출력

System.out.println("su[2]번지="+su[2]);//세번째데이터 출력

System.out.println("su[3]번지="+su[3]);//네번째데이터 출력

System.out.println("su[4]번지="+su[4]);//다섯번째데이터 출력

System.out.println("==============================");

System.out.println("배열의 크기(요소갯수): "+ su.length);

//for(int i=0; i<5; i++) {//0~4까지 표현, 배열의 인덱스를 표현

for(int i=0; i< su.length; i++) {//0~4까지 표현, 배열의 인덱스를 표현

System.out.println("su["+i+"]번지="+su[i]);

}

System.out.println("# 2차원배열 테스트");

//행 인덱스 0 1 2

int su2[][]= { {11}, {22,33}, {44,55,66} };

//열 인덱스 0 0 1 0 1 2

//1차원배열명.length ---> 배열크기, 요소갯수

//2차원배열명.length ---> 행의 크기!! su2.legth ---> 3

System.out.println("su2의 행크기: "+ su2.length); //3

for(int i=0; i< su2.length; i++) {//행 인덱스 표현 0 1 2

for(int j=0; j< su2[i].length; j++) {//열 인덱스 표현

System.out.println("su2["+i+"]["+j+"]="+ su2[i][j]);

}

}

}//main

}//ArrayTest


<Random>

import java.util.Random;

public class RandArrayTest {

int []su;

Random r;

public RandArrayTest() {

//생성자: (멤버필드에 대한)초기화메소드, 선행작업

//배열객체생성: 자료형 변수명[]=new 자료형[배열의크기];

su = new int[5];

r = new Random();

}//생성자

public void inputArray() {

/*su[0] = 10;

su[1] = 20;

su[2] = 30;

su[3] = 40;

su[4] = 50; */

//임의의 수(난수) 발생 ==> java.lang.Math: random(), java.util.Random: next()

for(int i=0; i<su.length; i++) {

//su[i]= (int) Math.random(); //캐스팅: (자료형)데이터;

// (int)(0.0~ 0.99999 *1000)

//su[i]= (int) (Math.random()*1000); //캐스팅: (자료형)데이터;

// 0 ~ 999

//Math.random() == r.nextDouble()

su[i] = r.nextInt(1000); //0~999

}

}

public void printArray() {//배열의 전체 데이터값을 출력.

for(int i=0; i<su.length; i++) {

System.out.println("su["+i+"]번지="+ su[i]);

}

}

public void sortArray() {//배열내의 데이터를 오름차순(1,2,3,4) 또는 내림차순(10,9,8,7)

정렬

//데이터 교환식

//su.length ---> 5

int temp;

for(int i=0; i<su.length-1; i++) {//기준!! 왼쪽데이터 (인덱스 0~3)

for(int j=i+1; j<su.length; j++) {//비교할 오른쪽데이터 (인덱스 1~4)

/*

i=0 , j=1,2,3,4

i=1 , j=2,3,4

i=2 , j=3,4

i=3 , j=4

*/

//su[i] 데이터 <----> su[j] 데이터

if(su[i] > su[j]) {//왼쪽데이터가 오른쪽데이터보다 크다면

temp = su[i];

su[i] = su[j];

su[j] = temp;

}

}//안 for

}//바깥 for

}

public static void main(String[] args) {

RandArrayTest rat = new RandArrayTest();

rat.inputArray();

rat.printArray();

System.out.println("----- 오름차순정렬 -----");

rat.sortArray();

rat.printArray();

}//main

}