객체지향 프로그래밍의 연장선으로 추상클래스와 인터페이스에 대해 배웠다.
먼저 추상클래스가 무엇인지 오전시간에 정리하고 넘어갔다.
package com.sist.main;
// page 375
/*
* 추상 클래스
* 1. 형식
* 접근지정어 타입 class className{}
* ======== ====(final|abstract)
* public|default
*
* public abstract class className
* {
* ==============
* 변수
* = 멤버변수 (instance)
* = 공통변수 (static)
* ==============
* 메소드
* =========== 먹는다 (개,소,돼지,사람...)
* = 구현된 메소드
* 컴퓨터 / 노트북 / 핸드폰 ==> 파워기 클릭 (필요하면 오버라이딩)
* public 리턴형 메소드(매개변수..) => 선언부
* {
* 구현부
* }
* = 선언된 메소드 ==> 구현이 안된 내용
* 기능은 동일 => 구현이 다르다
* public (abstract) 리턴형 메소드(매개변수); => 완성이 안됨 => 상속을 받아서 완성
* ==============
* ==============
*
* }
* 특징
* ====
* 1) 자신이 메모리할당을 할 수 없다 (미완성된 클래스) => new를 사용할 수 없다
* abstract class A
* A a=new A(); (X)
* 2) 상속을 받은 클래스에서 미완성 메소드를 구현해서 사용
* 3) 추상 클래스는 설계
* ========= 문제,숙제 , 아이템
* 4) 공통적으로 적용이 되는 기능만 설정
* 게시판 (글쓰기,수정,삭제,내용보기,찾기)
* = 일반게시판
* = 댓글형 게시판
* = 갤러리게시판
* = 묻고답하기
* = 자료실
* 2. 사용처
* = 요구사항 분석 (마킹) => 위에서 지시
* 의뢰 => 요구사항 분석 => 필요한 데이터 수집 => UI => 구현 => 테스팅
* ========== ============== === ==== =====
* 아키텍쳐 DBA 퍼블리셔 웹프로그래머 테스터
* = 기능은 동일 => 구현형태가 여러가지
* ========= 프로그램에 맞게 구현해서 사용
* ========= 여러개의 관련 클래스를 모아서 처리 (클래스를 모아서 한개의 이름으로 제어)
* ========= 표준화가 된다 (라이브러리)
*/
// 추상클래스의 상속 => 단일 상속만 가능
abstract class Print{
public abstract void list();
public abstract void detail();
//public abstract void menuClick();
/////////////////////// 무조건 구현해서 사용한다
public void reserve() {
System.out.println("예약이 가능합니다"); // 필요한 클래스에서만 변경해서 사용이 가능
}
public void end()
{
System.out.println("사이트 이동");
}
}
class 영화 extends Print{
@Override
public void list() {
// TODO Auto-generated method stub
System.out.println("영화 포스터 출력");
}
@Override
public void detail() {
// TODO Auto-generated method stub
System.out.println("영화 관련 데이터 출력");
}
/*
* public void reserve() {
System.out.println("예약이 가능합니다"); // 필요한 클래스에서만 변경해서 사용이 가능
}
*/
}
class 맛집 extends Print{
@Override
public void list() {
// TODO Auto-generated method stub
System.out.println("맛집을 테이블 형식으로 출력");
}
@Override
public void detail() {
// TODO Auto-generated method stub
System.out.println("맛집 지도와 메뉴를 출력");
}
/*
* public void reserve() {
System.out.println("예약이 가능합니다"); // 필요한 클래스에서만 변경해서 사용이 가능
}
*/
}
class 항공사 extends Print{
@Override
public void list() {
// TODO Auto-generated method stub
System.out.println("포스터 없이 테이블형태로 출력");
}
@Override
public void detail() {
// TODO Auto-generated method stub
System.out.println("시간을 출력한다");
/*
* class final System
* {
* static OutputStream out;
* static InputStream in;
* }
*/
}
public void reserve() {
System.out.println("항공 시간 예약을 합니다"); // 필요한 클래스에서만 변경해서 사용이 가능
}
/*
* 메소드는 {} => 구현
*/
}
public class 추상클래스 {
/*
* 프로그램 => 모아서 한개로 제어
* 데이터가 여러개 => 배열
* 클래스가 여러개 => 추상클래스 , 인터페이스
*
* 영화 int
* 맛집 double
* 항공사 String
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// 서로 다른 클래스를 연결해서 사용이 가능
Print p=new 영화();
p.list();
p.detail();
p.reserve();
p=new 맛집();
p.list();
p.detail();
p.reserve();
p=new 항공사();
p.list();
p.detail();
p.reserve();
}
접근지정어 타입 abstract class className{ } 으로 형식이 갖춰져 있고,
들어갈 수 있는 변수는 멤버변수, 공통변수 static이 있다.
메소드는 구현된 메소드, 선언된 메소드가 있다
선언된 메소드는 abstract 안에서 선언만 되었고 구현이 되지 않았기 때문에, 상속받은 클래스에서 반드시 구현을 해줘야 한다.
-> 이 작업을 오버라이딩이라고 볼 수 있다.
맨날 그냥 보고 넘어가서 이해가 제대로 안되는거 같아서 연습을 해봤다.
package com.sist.main;
abstract class NCT {
private int birthday;
private String name;
public int getBirthday() {
return birthday;
}
public void setBirthday(int birthday) {
this.birthday = birthday;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void dance();
public void sing(String name) {
System.out.println(name+"가 노래를 합니다.");
}
}
class 천러 extends NCT{
public void dance() {
System.out.println("천러가 춤을 춥니다.");
}
}
class 제노 extends NCT{
public void dance() {
System.out.println("제노가 춤을 추다 복근을 공개합니다.");
}
}
public class 추상클래스연습 {
public static void main(String[] args) {
NCT c=new 천러();
c.dance();
c.sing("천러");
c=new 제노();
c.dance();
c.sing("제노");
}
}
거의 똑같은 구조지만 나의 눈높이에 맞춘 예제를 써봤다.
NCT라는 추상클래스에 dance, sing 이라는 각각의 선언메소드, 구현 메소드를 설정해뒀다.
sing 메소드는 똑같이 사용되기 때문에 고정으로 구현해두었고,
dance는 각자 다르게 추기 때문에 선언만 해놓고 상속받은 멤버 클래스에서 각자 다르게 정의해준다 (오버라이딩)
그렇게 해주고 난 뒤에
main 에서 NCT c = 상속받은 클래스(); 로 객체를 만들어주고,
c 주소값을 통해서 여러 메소드들을 구현할 수 있다.
dance의 경우 매개변수가 없지만, sing 메소드의 경우 String 매개변수가 존재한다.
또 c라는 같은 주소값으로 여러 클래스를 제어 할 수 있어 중복을 줄여줄 수 있다.
이처럼 추상 클래스는 어떤 클래스를 완성 시키기 위한 '미완성 설계도'이다.
인터페이스는 추상클래스보다 더 추상화 정도가 강하다.
역시 미완성이지만
일반 메소드, 멤버변수들도 받을 수 없다. 오직 추상메소드와 상수만을 멤버로 가질 수 있고 그 외 다른 요소는 허용하지 않는다.
추상 클래스가 미완성 설계도라고 한다면 인터페이스는 '기본 설계도'이다. 클래스를 만들기 위한 기본적인 사항들만 모여있다고 생각하면 된다.
package com.sist.main;
/*
* 인터페이스 (interface)
* 1) 추상클래스의 일종 => 추상클래스의 단점을 보완
* # 자바의 클래스는 무조건 단일 상속만 가능
* # 인터페이스도 클래스 (but 다중상속이 가능함)
*
* 2) 형식
* 접근지정어 interface 인터페이스명{
* ==================
* 변수 (멤버변수(x)) : 상수형 변수
* ==================
* 추상메소드 (선언된 메소드)
* ==================
* 구현된 메소드 (JDK 1.8 이상)
* default
* ==================
* static
* ==================
*
* }
* =======
* public | default
* 3) 추상클래스와 동일 => 공통적인 속성을 모아서 저장 => 구현해서 사용
* ** 서로 다른 클래스를 연결할 때 사용
* ** 표준화가 가능하다
*
* *** 인터페이스에서 모든 변수, 메소드는 public만 가능하다
* public interface Common
* {
* ***** int a; // 상수형 변수 ==> int a=10; ==> public static final int a;
* ==================== (생략되어있음)
* void display(); // public abstract void display();
* =============== 생략되어 있음
* =====================
* default void aaa(){} default public void aaa(){}
* ======
* static void bbb(){} static public void bbb() {}
* }
*
*
*/
public class MainClass {
interface Common{
int x=10; // public static final (생략되어 있음)
void display(); // public abstract
default void aaa() {
}
static void bbb() {
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
인터페이스 역시 그 자체로 완성된 클래스가 아니기 때문에 몸통을 완성해주는 다른 클래스를 작성한 후에 인스턴스를 생성할 수 있다.
상속이나 추상클래스는 extends 라는 용어를 사용해서 만들어줬는데, interface는 implements 를 사용해서 받아온다.
package com.sist.main;
interface 가수 {
public static final String name = "가수";
// 앞의 접근 지정어를 생략할 수 있음 (모든 변수가 public static final 을 가지고 있기 때문에)
String group ="그룹";
// 메소드 정의
public abstract void 노래();
// 선언메소드만 사용가능 했음 - 지금은 구현메소드도 사용 가능하긴함
// 역시 앞의 접근 지정어를 생략할 수 있음 (모든 메소드가 public abstract를 가지고 있기 때문에)
void 춤();
}
// 구현 방법
class NCT implements 가수{
@Override
public void 노래() {
System.out.println("노래를 부릅니다.");
}
@Override
public void 춤() {
System.out.println("춤을 춥니다.");
}
}
public class 인터페이스연습 {
public static void main(String[] args) {
가수 a = new NCT();
a.노래();
a.춤();
}
}
이런식으로 활용해주면 된다. 또 interface는 다중상속이 가능하기 때문에 여러개의 인터페이스로부터 상속을 받는것이 가능하다.
(* interface가 다른 interface를 상속받는것 - interface 가수 extends 노래, 춤 이런 식으로)
interface를 받아오는 class를 생성할때는 implements 임!!
우선 여기까지만 하고
어차피 인터페이스는 다시 복습하게 될 것 같아서.. 오늘 풀었던 연습문제들을 복습해야겠다.
package com.sist.question;
class TV{
private String com;
private int i;
private int j;
// 생성자를 통한 초기화 작업
public TV(String com, int i, int j) {
this.com=com;
this.i=i;
this.j=j;
}
public void show()
{
System.out.println(com+"에서 만든 "+i+"년 "+j+"인치 TV");
}
}
// 생성자 : 여러개 (오버로딩이 가능), 생성자에서 사용하는 매개변수는 지역변수
public class 문제5 {
public static void main(String[] args) {
TV myTV =new TV("LG", 2017, 32);
myTV.show();
}
}
사실상 이 문제에서 핵심은 생성자를 만들 수 있냐 & 활용 하는 방법을 아냐
변수는 클래스 안에서 private으로 선언하고, 생성자를 통해 초기화 시켜줄수 있느냐를 물어보는 문제였다.
package com.sist.question;
import java.util.Scanner;
class Grade
{
private int math;
private int science;
private int eng;
public Grade(int math, int science, int eng) {
this.math=math;
this.science=science;
this.eng=eng;
}
public double average() {
return (math+science+eng)/3.0;
}
}
public class 문제6 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("수학, 과학, 영어 순으로 3개의 정수 입력>>");
int math=scan.nextInt();
int science=scan.nextInt();
int eng=scan.nextInt();
Grade me = new Grade(math, science, eng);
System.out.println("평균은:"+me.average());
}
}
이문제 역시 마찬가지로 생성자를 사용할 수 있는지, 변수를 어떻게 설정해 줄 것인지, 메소드는 어떻게 쓸 것인지를 활용해보는 문제였다.
처음에는 스캐너가 합쳐져 있는 문제라서 그러면 생성자에 입력하는 초기값들은 대체 어떻게 하는거지 라고
헷갈렸는데, 그냥 스캐너로 입력을 먼저 받아주고 그 다음에 생성자로 인스턴스를 만들어주면 해결될 문제였다.
평균 메소드 만들때 3.0으로 나눠주기 때문에 return형이 double 인것도 한번 더 체크해줘야 한다.
package com.sist.question;
interface Device{
void on();
void off();
}
class TV2 implements Device
{
public void on() {};
public void off() {};
public void watch() {};
}
public class 문제12 {
public static void main(String[] args) {
TV2 myTV = new TV2();
myTV.on();
myTV.off();
myTV.watch();
}
}
이거 계속 오류나서 대체 뭐가 문제일까 정말 짜증이 났었는데 그냥 알고보니 단순하게 TV 클래스가 이미 폴더 안에 있어서 안되는거 였다.
TV2로 바꿔주니까 바로 되는거봐라....
여튼 다 복습했으니 오늘은 여기까지....
'programming > Gukbi' 카테고리의 다른 글
국비 교육 21일차 - 예외처리 (1) | 2021.01.24 |
---|---|
국비 교육 19일차 - 예외처리 (0) | 2021.01.20 |
국비 교육 17일차 - 상속, 포함 (0) | 2021.01.19 |
국비 교육 16일차 (0) | 2021.01.15 |
국비 교육 15일차 - 객체지향프로그램 (0) | 2021.01.14 |