학습목표
상속에 대하여 이해하고 관련 기본 문법을 프로그래밍에 적용할 수 있다.
일관성과 다형성에 관련된 기본 문법을 프로그래밍에 적용할 수 있다.
패키지(package)
- 관련된 클래스 및 인터페이스 등을 모아 놓은 폴더
- 패키지에는 클래스들이 존재함
- 패키지 이름은 소문자로 시작
- 점(.)으로 패키지를 구분
java.lang.System
모듈(module)
- 관련 패키지들을 모아 놓은 것
- 프로그램 실행 시 필요한 모듈만 사용하여 메모리를 효율적으로 사용
- 모듈 이름은 소문자로 시작하고, 점(.)으로 구분
모듈 분류
- Java SE : 기본 모듈들
- JDK : 확장 모듈들
- Other Modules : 기타 모듈들
import 문
- 패키지에 있는 클래스들을 참조하기 위해 사용
- 소스의 제일 위에 정의
- import 문을 사용하지 않을 경우 패키지명을 지정해야 함
// import 문을 지정하지 않았을 경우
java.lang.String a = "JAVA";
// import 문 사용 시
import java.lang.String;
String a = "JAVA";
- 참조하고자 하는 클래스만 지정 : import 패키지명.클래스명;
- 참조하고자 하는 패키지의 전체 클래스를 지정(해당 패키지 안에 또 다른 패키지가 존재하면 또 다른 패키지는 참조되지 않음) : import 패키지명.*;
// 참조하고자 하는 클래스만 지정
import java.lang.String;
// 참조하고자 하는 패키지 전체 지정
import java.util.*;
// 또 다른 패키지가 있는 경우 별도로 import 문 지정
import java.util.zip.*;
package 문
프로그래머가 작성한 프로그램의 패키지를 지정
import와 package문 실습
package packRobot;
import java.lang.*; // 기본 자바 패키지
import java.util.*;
public class PackRobot {
public static void main(String[] args) {
java.lang.String a = "자바";
String b = "프로그래밍";
System.out.println(a+" : "+b);
java.util.Date d1 = new java.util.Date();
Date d2 = new Date();
System.out.println(d1);
System.out.println(d2);
}
}
자바 : 프로그래밍
Mon Jul 10 15:57:01 KST 2023
Mon Jul 10 15:57:01 KST 2023
상속(inheritance)
- 기존 클래스의 멤버 변수(필드)와 멤버 메소드(메소드)를 모두 가짐
- 추가적인 멤버 변수와 멤버 메소드를 정의
- 기존의 멤버 변수와 멤버 메소드를 재정의
class Robot {
int x;
int y;
int angle;
boolean gotoxy();
void armAngle();
void pickup();
void putdown();
}
// 상업용 로봇
class IndustrialRobot extends Robot {
// Robot 클래스의 멤버 변수와 멤버 메소드 사용 가능
int x;
int y;
int angle;
String name;
int direction;
boolean gotoxy();
void armAngle();
void pickup();
void putdown();
boolean changeName();
void changeDirection();
}
상속의 구현
- 상속해 주는 클래스 : 부모 클래스, 슈퍼(super) 클래스, 상위 클래스
- 상속받는 클래스 : 자식 클래스, 서브(sub) 클래스, 하위 클래스
- 단일 상속 : 부모 클래스는 반드시 하나이고, 자식 클래스는 여러 개일 수 있음
- 다중 상속 : 자식 클래스는 2개 이상의 부모 클래스를 상속받을 수 있음
class Robot {...}
class IndutrialRobot extends Robot {...}
class DisalbledRobot extends Robot {...}
class PetRobot extends Robot {...}
상속 기본 실습(같은 패키지에 있음)
Robot.java
package inheritance;
public class Robot {
int x;
int y;
int angle;
static int job;
public Robot() {
}
public Robot(int x, int y, int angle) {
this.x = x;
this.y = y;
this.angle = angle;
}
public Robot(int x, int y, int angle, int job) {
this(x, y, angle);
this.job = job;
}
void gotoxy(int x, int y) { // 로봇 좌표 이동
this.x = this.x + x;
this.y = this.y + y;
}
void moveAngle(int angle) { // 로봇팔 각도 조정
this.angle = this.angle + angle;
}
void pickup() {
System.out.println("xy["+x+","+y+"], angle["+angle+"] Pick up!!!");
}
void putdown() {
System.out.println("xy["+x+","+y+"], angle["+angle+"] Put down!!!");
this.job++;
}
public static void main(String[] args) {
}
}
IndustrialRobot.java
package inheritance;
public class IndustrialRobot extends Robot {
String name;
public IndustrialRobot(int x, int y, int angle) {
this.x = x;
this.y = y;
this.angle = angle;
}
public IndustrialRobot(int x, int y, int angle, int job) {
this(x, y, angle);
this.job = job;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
IndustrialRobot a = new IndustrialRobot(10, 10, 10);
IndustrialRobot b = new IndustrialRobot(20, 20, 10, 100);
a.setName("Computer");
System.out.println(a.name);
a.gotoxy(15, 15);
a.moveAngle(150);
a.pickup();
a.putdown();
b.setName("SmartPhone");
System.out.println(b.name);
b.gotoxy(95, 80);
b.moveAngle(355);
b.pickup();
b.putdown();
System.out.println("Job Count = "+Robot.job);
}
}
Computer
xy[25,25], angle[160] Pick up!!!
xy[25,25], angle[160] Put down!!!
SmartPhone
xy[115,100], angle[365] Pick up!!!
xy[115,100], angle[365] Put down!!!
Job Count = 102
접근 제한자(access modifier)
- 클래스 또는 클래스의 멤버에 대한 접근을 제한하는 키워드
- 클래스, 멤버 변수(필드), 멤버 메소드(메소드), 생성자 메소드에 사용
접근 제한자 | 설명 |
private | 클래스 내부에서만 접근 가능 |
default (friendly) |
클래스 내부, 같은 패키지안의 클래스에서 접근 가능 접근 제한자 기본값 |
protected | 클래스 내부, 같은 패키지, 상속 관계 있는 클래스에서 접근 가능 |
public | 모든 클래스에서 접근 가능 생성자 메소드는 public을 지정해야 다른 클래스에서 사용할 수 있음 |
졉근 제한자 실습
Robot.java
package modifierA;
public class Robot {
private int x;
private int y;
int job; // friendly 접근 제한
public Robot() {
}
void sexX(int x) {
this.x = x;
}
int getX() {
return x;
}
void setY(int y) {
this.y = y;
}
int getY() {
return y;
}
public static void main(String[] args) {
}
}
private 접근 제한 멤버 변수는 setter, getter 메소드가 필요함
IndustrialRobot.java
package modifierA;
public class IndustrialRobot extends Robot {
public static void main(String[] args) {
IndustrialRobot a = new IndustrialRobot();
// a.x = 10; private 접근제한
// a.y = 20; private 접근제한
a.setX(10);
a.setY(20);
System.out.println("[IndustrialRobot Class]");
// System.out.println("X="+a.x); private 접근제한
// System.out.println("Y="+a.y); private 접근제한
System.out.println("X="+a.getX());
System.out.println("Y="+a.getY());
a.job = 100;
System.out.println("JOB="+a.job);
}
}
[IndustrialRobot Class]
X=10
Y=20
JOB=100
다른 패키지에서 접근하려고 하면 setX, setY 둘 다 오류가 난다. (별도로 import 필요)
메소드 오버라이딩(method overriding)
- 하위 클래스에서 상위 클래스의 멤버 메소드를 동일하게 재정의 하는 것
- 하위 클래스에서 메소드 이름, 매개 변수, 반환 자료형은 동일하게 재정의
- 접근 제한자의 범위 : 하위 클래스 >= 상위 클래스 (넓거나 같아야 한다.)
- 메소드의 내용은 상위클래스와 다르게 프로그래밍함
- 오버라이딩 된 메소드도 오버로딩 될 수 있음
// 상위 클래스
class Robot {
int gotoxy(int x, int y) {
}
}
// 하위 클래스
class IndustrialRobot extends Robot {
public int gotoxy(int x, int y) {
}
public int gotoxy(int x){
}
}
super 키워드
- 상위 클래스의 객체를 참조하는 참조변수
- 하위 클래스에서 상위 클래스의 멤버 변수 또는 멤버 메소드를 참조할 때 사용
// 상위 클래스
class Robot {
int x, y;
int gotoxy(int x, int y) {
}
}
// 하위 클래스
class IndustrialRobot extends Robot {
int x, y;
public int setxy(int a, int b) {
gotoxy(10, 20); // 하위 클래스의 gotoxy() 호출
super.gotoxy(x, y); // 상위 클래스의 gotoxy() 호출
super.x = 10; // 상위 클래스의 멤버 변수에 지정
super.y = 10;
this.x = 20; // 하위 클래스의 멤버 변수에 지정
this.y = 20;
}
public int gotoxy(int x, int y) {
}
}
super() 메소드
- 상위 클래스의 생성자 메소드를 명시적으로 호출
- 하위 클래스의 생성자 메소드에서 첫 줄에 한번만 사용 가능
- 소스 코드의 중복을 줄이기 위함
- 하위 클래스 객체 생성 시
- 상위 클래스의 디폴트 생성자(매개 변수 없는 생성자)가 자동으로 호출됨
- 자동 호출을 하지 않고 명시적으로 상위 클래스의 생성자를 호출할 경우 super() 메소드를 활용함
- 생성자 메소드 정의 유무에 따른 실행 결과
상위 클래스 | 하위 클래스 | 실행 결과 |
생성자 메소드를 정의하지 않거나, 디폴트 생성자 메소드를 정의한 경우 | 생성자 메소드를 정의한 경우 생성자 메소드를 정의하지 않은 경우 |
오류 없음 |
디폴트 생성자 메소드를 정의하지 않고, 매개 변수가 있는 생성자 메소드만 정의된 경우 | 생성자 메소드를 정의하지 않은 경우 | 오류 발생 |
디폴트 생성자 메소드만 정의한 경우 | super() 메소드를 이용하여 명시적으로 호출해야 함 | |
매개 변수 있는 생성자 메소드만 정의한 경우 |
오버라이딩 실습
Robot.java
package overriding;
public class Robot {
int x;
int y;
int angle;
int job;
public Robot() {
}
public Robot(int x, int y, int angle) {
this.x = x;
this.y = y;
this.angle = angle;
}
public Robot(int x, int y, int angle, int job) {
this(x, y, angle);
this.job = job;
}
void gotoxy(int x, int y) {
this.x = x;
this.y = y;
}
void moveAngle(int angle) {
this.angle = this.angle + angle;
}
void pickup() {
System.out.println("xy ["+x+", "+y+"], angle["+angle+"] pick up!!!");
}
void putdown() {
System.out.println("xy ["+x+", "+y+"], angle["+angle+"] put down!!!");
this.job++;
}
void printOut() {
System.out.println("[Robot Class]");
System.out.println("[X="+this.x+"]");
System.out.println("[Y="+this.y+"]");
System.out.println("[ANGLE="+this.angle+"]");
System.out.println("[JOB="+this.job+"]");
}
}
IndustrialRobot.java
package overriding;
public class IndustrialRobot extends Robot {
int x, y, angle; // 상위 클래스와 동일한 멤버 변수 존
String name;
public IndustrialRobot() {
}
public IndustrialRobot(int x, int y, int angle) {
super(x, y, angle);
}
public IndustrialRobot(int x, int y, int angle, int job) {
this(x, y, angle);
super.job = job;
}
void gotoxy(int x, int y) { // 오버라이딩, 접근제어 private 안
this.x = this.x + x + 10;
this.y = this.y + y + 10;
}
void gotoxy(int x, int y, int angle) { // 오버라이딩 된 메소드의 오버로딩
super.x = this.x + x;
super.y = this.y + y;
super.angle = angle;
}
void printOut() { // 오버라이딩
super.printOut();
System.out.println("[IndustrialRobot Class]"+this.name);
System.out.println("[X="+this.x+"]");
System.out.println("[Y="+this.y+"]");
}
public static void main(String[] args) {
IndustrialRobot a = new IndustrialRobot(10, 10, 10);
a.name = "computer";
a.gotoxy(15, 15); // 하위 클래스 x, y 좌표 이동
a.gotoxy(20, 20, 100); // 상위 클래스 x, y 좌표 이동
a.printOut();
}
}
[Robot Class]
[X=45]
[Y=45]
[ANGLE=100]
[JOB=0]
[IndustrialRobot Class]computer
[X=25]
[Y=25]
객체 형변환
업 캐스팅(up casting)
- 상위 클래스의 참조 변수가 하위 클래스의 객체를 참조하는 것
- 묵시적 형변환이라고도 함
- 하위 클래스에서 추가된 멤버는 참조하지 못함
// 하위 클래스의 객체 a와 b 생성
IndustrialRobot a = new IndurtrialRobot();
PetRobot b = new PetRobot();
// 상위클래스의 참조 변수 c와 d는 하위 클래스의 객체 a와 b를 참조 가능
Robot c = a;
Robot d = b;
다운 캐스팅(down casting)
- 하위 클래스의 참조 변수가 상위 클래스의 객체를 참조하는 것
- 명시적 형변환이라고도 함
- 형변환 연산자 사용하여야 함
- 상위 클래스의 참조 변수가 실제로 하위 클래스의 객체를 참조하는 경우에만 가능
// 상위 클래스의 참조 변수가 하위 클래스의 객체를 참조(업 캐스팅)
Robot a = new IndurtrialRobot();
Robot b = new PetRobot();
// 형변환 연산자를 사용해서 상위클래스의 참조 변수 c와 d는 하위 클래스의 객체 a와 b를 참조 가능
IndustrialRobot c = (IndustrialRobot)a;
PetRobot d = (PetRobot)b;
객체 형변환 실습
Robot.java
package casting;
public class Robot {
int x;
int y;
int angle;
int job;
public Robot() {
}
public Robot(int x, int y, int angle) {
this.x = x;
this.y = y;
this.angle = angle;
}
public Robot(int x, int y, int angle, int job) {
this(x, y, angle);
this.job = job;
}
void gotoxy(int x, int y) {
this.x = x;
this.y = y;
}
void moveAngle(int angle) {
this.angle = this.angle + angle;
}
void pickup() {
System.out.println("xy ["+x+", "+y+"], angle["+angle+"] pick up!!!");
}
void putdown() {
System.out.println("xy ["+x+", "+y+"], angle["+angle+"] put down!!!");
this.job++;
}
void printOut() {
System.out.println("[Robot]");
System.out.println("[X="+this.x+"]");
System.out.println("[Y="+this.y+"]");
System.out.println("[ANGLE="+this.angle+"]");
System.out.println("[JOB="+this.job+"]");
System.out.println();
}
public static void main(String[] args) {
IndustrialRobot ir = new IndustrialRobot(10, 10, 10, "computer");
PetRobot pr = new PetRobot(10, 10, 10, "KING");
Robot ru = ir; // 업캐스팅
ru.gotoxy(10, 10);
ru.printOut();
ru = pr; // 업캐스팅
ru.gotoxy(10, 10);
ru.printOut();
PetRobot prd = (PetRobot) ru; // 다운 캐스팅
prd.gotoxy(5, 5);
prd.printOut();
}
}
IndustrialRobot.java
package casting;
public class IndustrialRobot extends Robot {
String name;
public IndustrialRobot() {
}
public IndustrialRobot(int x, int y, int angle) {
super(x, y, angle);
}
public IndustrialRobot(int x, int y, int angle, String name) {
this(x, y, angle);
this.name = name;
}
void gotoxy(int x, int y) { // 오버라이딩, 접근제어 private 안
this.x = this.x + x + 10;
this.y = this.y + y + 10;
}
void gotoxy(int x, int y, int angle) { // 오버라이딩 된 메소드의 오버로딩
super.x = this.x + x;
super.y = this.y + y;
super.angle = angle;
}
void printOut() { // 오버라이딩
super.printOut();
System.out.println("[IndustrialRobot]");
System.out.println(this.name);
System.out.println();
}
public static void main(String[] args) {
IndustrialRobot a = new IndustrialRobot(10, 10, 10, "computer");
a.gotoxy(15, 15); // 하위 클래스 x, y 좌표 이동
a.printOut();
}
}
PetRobot.java
package casting;
public class PetRobot extends Robot {
String master;
public PetRobot() {
}
public PetRobot(int x, int y, int angle, String master) {
super(x, y, angle);
this.master = master;
}
void gotoxy(int x, int y) { // 오버라이딩, 접근제어 private 안됨
this.x = this.x + x + 20;
this.y = this.y + y + 20;
}
void printOut() {
super.printOut();
System.out.println("[PetRobot]");
System.out.println(this.master);
System.out.println();
}
public static void main(String[] args) {
PetRobot a = new PetRobot(10, 10, 10, "KING");
a.gotoxy(15, 15);
a.printOut();
}
}
[Robot]
[X=30]
[Y=30]
[ANGLE=10]
[JOB=0]
[IndustrialRobot]
computer
[Robot]
[X=40]
[Y=40]
[ANGLE=10]
[JOB=0]
[PetRobot]
KING
[Robot]
[X=65]
[Y=65]
[ANGLE=10]
[JOB=0]
[PetRobot]
KING
마지막에 왜 [PetRobot] KING이 한번 더 나오는...?
강의에서 호록 지나가버려서 모르겠음 ㅠ
추상클래스(abstract class)
- 추상 메소드를 가지는 클래스
- 추상 메소드 : 메소드의 이름만 정의하고 내용은 구현되어 있지 않는 메소드
- abstract 키워드를 지정하여 클래스와 메소드를 정의
- 추상 메소드 뿐만 아니라 정상적인 메소드도 정의할 수 있음
- 추상 클래스를 상속받은 하위 클래스들은 반드시 추상 메소드를 오버라이딩 해야 함
- 같은 상위 클래스를 가지는 하위 클래스들은 일관성을 가짐
- 오버라이딩 한 메소드는 프로그램의 내용에 따라 다양하게 실행될 수 있음
- 동일한 이름의 메소드들이 다양하게 실행됨(다형성)
- 추상 클래스를 상속하여 또다른 추상 클래스를 만들 수 있음
- 추상 클래스들이 가지고 있는 모든 추상 메소드들을 오버라이딩 해야 함
- 추상 클래스의 참조 변수는 하위 클래스의 객체를 참조할 수 있음
- 객체 형변환 가능
abstract class Hardware {
abstract void powerOn();
}
class Robot extends Hardware {
void porwerOn() { // 추상클래스를 상속 시 추상 메소드를 반드시 오버라이딩
...
}
}
class Phone extends Hardware {
void powerOn() { // 추상클래스를 상속 시 추상 메소드를 반드시 오버라이딩
...
}
}
// 상위 클래스(추상 클래스)의 참조 변수가 하위 클래스의 객체 참조(업 캐스팅)
Hardware a = new Robot();
Hardware b = new Phone();
// 하위 클래스의 참조 변수가 상위 클래스의 객체를 참조(다운 캐스팅)
Robot c = (Robot)a;
Phone d = (Phone)b;
abstract class Hardware {
abstract void powerOn();
}
abstract class Network extends Hardware {
abstract void connectOn();
}
class Phone extends Network {
void powerOn() {...} // Hardware 클래스의 메소드 반드시 오버라이딩
void connectOn() {...} // Network 클래스의 메소드 반드시 오버라이딩
}
추상 클래스 실습
package abstractclass;
public class Phone extends Network {
public void powerOn() { // Hardware 추상 메소드 반드시 오버라이딩
power = true;
}
public void connectOn() { // Network 추상 메소드 반드시 오버라이딩
connect = true;
}
public static void main(String[] args) {
Hardware[] h = new Hardware[2];
h[0] = new Robot();
h[1] = new Phone();
System.out.println("[Robot Class]");
for(int i=0; i<h.length; i++) {
h[i].powerOn();
System.out.println("Hardware["+i+"].power = "+h[1].power);
}
}
}
[Robot Class]
Hardware[0].power = false
Hardware[1].power = true
인터페이스(interface)
- 자바는 단일 상속만 허용, 다중 상속의 대안으로 사용
- interface 키워드를 사용하여 정의
- 상수와 메소드만 정의 가능
- 접근 제어자는 일반적으로 public으로 지정
interface Toggle {
public static final int ON = 1;
public abstract void on_off();
}
인터페이스 구현
- implements 키워드를 사용
- 여러 개의 인터페이스를 구현할 수 있음(콤마로 구분)
- 인터페이스를 구현한 클래스에서 인터페이스의 추상 메소드들을 반드시 모두 재정의해야 함
interface Toggle {
public static final int ON = 1;
public abstract void on_off();
}
interface PushButton {
public abstract void press();
}
class Robot implements Toggle, PushButton {
public void on_off() {...}
public void press() {...}
}
인터페이스 상속
- 인터페이스를 상속하여 또 다른 인터페이스를 정의할 수 있음
- 인터페이스들이 가지고 있는 모든 추상 메소드를 재정의하여야 함
interface Switch {
public abstract void powerOn();
}
interface Toggle extends Switch {
public abstract void on_off();
}
class Robot implements Toggle {
public void powerOn() {...}
public void on_off() {...}
}
인터페이스 참조 변수
- 인터페이스를 구현한 클래스의 객체는 인터페이스 참조 변수로 참조 가능
interface Switch {...}
class Robot implements Switch {...}
class Phone implements Switch {...}
Switch a = new Robot();
Switch b = new Phone();
인터페이스 실습
package interfacesrc;
import interfaces.PushButton;
import interfaces.Toggle;
public class Robot implements Toggle, PushButton {
public void on_off() { // Toggle 인터페이스
System.out.println("["+Toggle.name+"]");
}
public void press() { // PushButton 인터페이스
System.out.println("["+PushButton.name+"]");
}
public static void main(String[] agrs) {
System.out.println("[Robot Class]");
Robot r = new Robot();
r.on_off();
r.press();
Toggle[] t = new Toggle[2];
t[0] = r;
t[1] = new Phone();
for(int i=0; i<t.length; i++) {
System.out.print("Toggle["+i+"] : ");
t[i].on_off();
}
}
}
[Robot Class]
[Toggle]
[PushButton]
Toggle[0] : [Toggle]
Toggle[1] : [Toggle]
내부 클래스(inner class)
- 중첩된 클래스(nested class)로 클래스 내부에 또다시 선언된 클래스
- 외부 클래스에서 내부 클래스의 객체를 생성해서 사용
- 내부 클래스에서는 외부 클래스의 멤버에 public 접근
// 외부 클래스 (Robot.class)
class Robot {
// 내부 클래스 (Robot$Arm.class)
class Arm {
...
}
}
내부 클래스 종류
(1) 내부 멤버 클래스
- 클래스의 멤버와 동일한 레벨로 내부 클래스 정의
- 외부 클래스의 생성자 메소드에서 내부 멤버 클래스의 객체 생성
class Robot {
// 외부 클래스의 멤버 변수로 내부 멤버 클래스의 객체 선언
Arm left;
// 외부 클래스의 생성자 메소드에서 내부 멤버 클래스의 객체 생성
public Robot() {
left = new Arm();
}
class Arm {
...
}
}
(2) 메소드 안에 선언된 내부 클래스
- 외부 클래스의 멤버 메소드 안에 선언된 내부 클래스
- 외부 클래스의 멤버 메소드 내부에서만 사용 가능
class Robot {
public int gotoxy() {
// 외부 클래스의 멤버 메소드에서 내부 클래스의 객체 생성
Arm left = new Arm();
class Arm {
...
}
}
}
(3) 내부 무명 클래스
- 클래스의 이름이 없는 내부 클래스 : 내부 익명(Anonymous) 클래스
- 상속받는 클래스의 선언과 동시에 객체를 생성하여 사용
- 주로 메서드의 인수로 객체를 지정할 때 사용
class Robot {
public int gotoxy() {
call(
// call() 메소드의 인수로 내부 무명 클래스의 객체 지정
new Object() {
public String toString() {
...
}
}
);
}
}
final 키워드
(1) 클래스 선언 시 지정
- 해당 클래스는 더 이상 상속을 허락하지 않음
- public final class Robot {...}
(2) 메소드 선언 시 지정
- 해당 메소드는 더 이상 오버라이딩을 허락하지 않음
- public final int gotoxy() {...}
(3) 변수 선언 시 지정
- 해당 변수는 더 이상 값의 변경을 허락하지 않음
- static 키워드와 함께 정의하여 상수를 정의함
- public static final int RED = 1;
중첩 클래스와 final 실습
package inner;
public class Robot {
// public final class Robot { // 상속 금지
Arm left; // 내부 멤버 클래스 선언
int armLength;
public Robot() {
}
public Robot(int armLength) {
this.armLength = armLength;
left = new Arm();
left.armPower = 100;
}
class Arm { // 내부 멤버 클래스
int armPower;
int getPower() {
int result = armLength / armPower;
return result;
}
}
// final void gotoxy(int x, int y) { // 오버라이딩 금지
void gotoxy(int x, int y) {
class MoveXY { // 메소드 안에 내부 클래스 정의
int x, y;
public MoveXY(int x, int y) {
this.x = x + 10;
this.y = y + 10;
}
public void printOut() {
System.out.println("[MOVE][X] = "+x);
System.out.println("[MOVE][Y] = "+y);
}
}
MoveXY m = new MoveXY(x, y); // 내부 클래스 객체 생성
m.printOut();
}
void call(Object o) {
System.out.println(o.toString());
}
public static void main(String[] args) {
Robot r = new Robot(500);
System.out.println("[내부 멤버 클래스]");
int power = r.left.getPower(); // 내부 멤버 클래스 호출
System.out.println("[Robot.Arm.getPower()] = "+power);
System.out.println("[메소드안에 정의된 내부 클래스]");
r.gotoxy(10, 10);
System.out.println("[내부 무명 클래스]");
r.call(new Object() {
public String toString() {
return "{내부 무명 클래스}";
}
});
}
}
[내부 멤버 클래스]
[Robot.Arm.getPower()] = 5
[메소드안에 정의된 내부 클래스]
[MOVE][X] = 20
[MOVE][Y] = 20
[내부 무명 클래스]
{내부 무명 클래스}
package inner;
public class PetRobot extends Robot {
final static int RED = 1;
void gotoxy(int x, int y) {
// RED = 3;
}
public static void main(String[] args) {
}
}
적용하기
1) Hardware 추상 클래스 정의
2) Switch 인터페이스 정의
3) Hardware를 상속하고, Switch를 구현한 Robot 클래스 구현
4) 필요에 따라 특성 및 기능을 추가하시오.
Hardware.java
package stop;
public abstract class Hardware {
public boolean power = false;
abstract public void powerOn(); // 추상 메소드
public void powerOff() {
power = false;
}
}
Switch.java
package stop;
public interface Switch {
public static final String NAME = "[SWITCH]";
public void switchOn();
public void switchOff();
}
Robot.java
package stop;
public class Robot extends Hardware implements Switch{
public void powerOn() { // Hardware 추상 클래스로부터 정의 (필수)
if(power == false) {
power = true;
System.out.println("[Power ON]");
} else {
System.out.println("Already Power ON!!");
}
}
public void powerOff() { // Hardware 추상 클래스로부터 오버라이딩
if (power == true) {
power = false;
System.out.println("[Power OFF]");
} else {
System.out.println("Already Power OFF!!");
}
}
public void switchOn() { // switch 인터페이스로부터 정의 (필수)
System.out.println(Switch.NAME+" Trying.. Power ON!!");
powerOn();
}
public void switchOff() { // switch 인터페이스로부터 정의 (필수)
System.out.println(Switch.NAME+" Trying.. Power OFF!!");
powerOff();
}
public static void main(String[] args) {
Robot r = new Robot();
r.switchOn();
r.switchOn();
r.switchOff();
r.switchOff();
r.switchOn();
}
}
[SWITCH] Trying.. Power ON!!
[Power ON]
[SWITCH] Trying.. Power ON!!
Already Power ON!!
[SWITCH] Trying.. Power OFF!!
[Power OFF]
[SWITCH] Trying.. Power OFF!!
Already Power OFF!!
[SWITCH] Trying.. Power ON!!
[Power ON]
뭔소리여. . 뭔소리여 하면서 실습 전까지 진행했는데
실습한 코드 보니 어느정도 이해 완

쉽지않네....
'온라인 강좌 > 안드로이드 프로그래밍을 위한 자바기초' 카테고리의 다른 글
9차시 컬렉션 프레임워크 활용 (0) | 2023.07.12 |
---|---|
8차시 자바 기본 라이브러리 활용하기 (0) | 2023.07.12 |
6차시 클래스를 이용한 객체지향 프로그래밍 기본 문법 이해하기 (0) | 2023.07.10 |
5차시 배열의 기본 문법 이해하기 (0) | 2023.07.09 |
4차시 조건문과 반복문의 기본 문법 이해하기 (0) | 2023.07.08 |