super()
부모 객체의 메소드 기능에 추가적으로 내 기능을
더하고 싶으면 super라는 지시어를 통해 부모 메소드를
호출할 수 있다. super.메소드명() 으로 호출하면 된다.
인터페이스는 상속, 부모 클래스, 추상 클래스, 추상 메소드, 다형성(오버라이드), 그리고 형변환의 개념을 모두 가지고 있는 종합선물세트다.
무조건 자식 클래스는 메소드를 정의(재정의)해야 한다.
구현도 해야한다.
상수
(public static final)만 가질 수 있다.추상 메소드
(public abstract)만 가질 수 있다. interface 클래스먕 {
}
public class 클래스명 extends 상복받을 클래스명 implements 상속받을 인터페이스이름
// 2-1
public interface Remotecontrol2_1 {
// 상수(static final)
static final int MAX_VOLUMN = 10;
static final int MIN_VOLUMN = 0;
// 추상 메소드
public abstract void turnOn();
public abstract void turnOff();
public abstract void setVolume(int volume);
}
▶ Remotecontrol2_1을 상속받고 Remotecontrol2_1에 있는 추상 메소드를 재정의 해줌
// 2-2
public class Audio2_2 implements Remotecontrol2_1 {
private int volume;
@Override
public void turnOn() {
System.out.println("Audio를 켭니다.");
}
@Override
public void turnOff() {
System.out.println("Audio를 끕니다.");
}
@Override
public void setVolume(int volume) {
// 볼륨이 0~10사이에서만 움직일 것을 프로그램
if(volume > Remotecontrol2_1.MAX_VOLUMN) {
System.out.println("Audio 볼륨의 최대치 값은 10입니다.");
this.volume = Remotecontrol2_1.MAX_VOLUMN;
} else if(volume < Remotecontrol2_1.MIN_VOLUMN) {
System.out.println("Audio 볼륨의 최소치 값은 0입니다.");
this.volume = Remotecontrol2_1.MIN_VOLUMN;
} else {
this.volume = volume;
}
System.out.println("현재 Audio 볼륨: " + this.volume);
}
}
-----
// 2-3
public class Television2_3 implements Remotecontrol2_1 {
private int volume;
@Override
public void turnOn() {
System.out.println("TV를 켭니다.");
}
@Override
public void turnOff() {
System.out.println("TV를 끕니다.");
}
@Override
public void setVolume(int volume) {
if(volume > Remotecontrol2_1.MAX_VOLUMN) {
System.out.println("TV 볼륨의 최대치 값은 10입니다.");
this.volume = Remotecontrol2_1.MAX_VOLUMN;
} else if(volume < Remotecontrol2_1.MIN_VOLUMN) {
System.out.println("TV 볼륨의 최소치 값은 10입니다.");
this.volume = Remotecontrol2_1.MIN_VOLUMN;
} else {
this.volume = volume;
}
System.out.println("TV 현재 볼륨: " + this.volume);
}
}
// 2-4
public class RemoteTest2_4 {
public static void main(String[] args) {
Remotecontrol2_1 c = new Television2_3();
c.turnOn();
c.setVolume(15);
c.setVolume(-100);
c.turnOff();
c = new Audio2_2();
c.turnOn();
c.setVolume(15);
c.setVolume(-50);
c.turnOff();
c.setVolume(5);
c.setVolume(7);
}
}
인터페이스는 다중 상속이 가능한데 받아온 클래스에서 오버라이드한 메소드를 사용하려면 f라는 메소드가 있는데, A라는 클래스에서 가져온것인지 B에서 가져온것인지 모르는데 A, B를 다중상속으로 받아오면 f라는 메소드가 같은 이름이라 충돌을 일으키는데, 그것을 방지하기 위해서 받은 클래스에서 f라는 메소드를 오버라이드를 해줘야 한다.
// 1-1 인터페이스 1
public interface WashingMachine1_1 {
public abstract void startButtonPressed();
public abstract void pauseButtonPressed();
public abstract void stopButtonPressed();
public abstract int changeSpeed(int speed);
}
public interface DryCouse1_2 {
public void dry();
}
// 1-3 인터페이스 1,2 을 사용 (인터페이스 다중상속)
public class LGWashingMachine1_3 implements WashingMachine1_1, DryCouse1_2 {
@Override
public void startButtonPressed() {
System.out.println("세탁기가 빨래를 시작하였습니다.");
}
@Override
public void pauseButtonPressed() {
System.out.println("세탁기가 빨래를 중지하였습니다.");
}
@Override
public void stopButtonPressed() {
System.out.println("세탁기가 빨래를 일시 중지하였습니다.");
}
@Override
public int changeSpeed(int speed) {
int rtnSpeed = 0;
switch (speed) {
case 1:
rtnSpeed = 20;
break;
case 2:
rtnSpeed = 50;
break;
case 3:
rtnSpeed = 100;
break;
}
return rtnSpeed;
}
@Override
public void dry() {
System.out.println("세탁기 완료되어 건조하기 시작하였습니다.");
}
}
// 1-4
public class WashingMachineTest1_4 {
public static void main(String[] args) {
LGWashingMachine1_3 ws = new LGWashingMachine1_3();
ws.startButtonPressed();
System.out.println("세탁기의 속도는 " + ws.changeSpeed(3));
}
}
static이 붙은 변수, 메소드, 구역 등은 프로그램 실행시 가장 먼저 메모리에 올라간다. static이 붙은 메소드는 내부에서 객체의 필드에 올라오는 일반 전역변수와 일반 메소드는 아직 존재하지 않기 때문에 프로그램 실행시 해석이 불가하여 사용할 수 없다. 따라서 static이 붙은 전역변수, static이 붙은 메소드, 자기 자신안에 선언된 지역변수만 사용할 수 있다. static이 붙은 전역변수, 메소드는 모든 객체가 공유한다. 따라서 static 필드는 클래스 이름으로 직접 접근이 가능하다.
실제로 객체들이 유해야 하는 값, 메소드, 필드를 사용하지 않는 메소드에는 static을 붙여서 선언!!
(공유하지 않아야 하는 필드는 무조건 static을 붙이면 안된다.)
static 지시어를 사용하면 동일한 클래스로 만들어진 모든 객체들이
공유하는 공유 변수 또는 함수(메소드)가 된다.
멤버 변수 앞에 사용하면 변수를 클래스의 공용(공유) 변수로 만든다.
멤버 함수 앞에 사용하면 함수를 클래스의 공용(공유) 함수로 만든다.
일반적으로 static 변수는 영문 대문자만 사용한다.
상수
가 된다.
// 추상 클래스
public abstract class Human {
private char type;
// 이름과 나이를 여기로 일반화 하자
// 모든 인간은 이름과 나이가 있다고 가정한다.
private String name;
private int age;
public Human() {
this.type = 0;
// 초기화
this.name = "";
this.age = 0;
}
public Human(char type, String name, int age) {
this.type = type;
// 초기화
this.name = name;
this.age = age;
}
// 추상 메소드
public abstract void print();
// getter
public char getType() {
return type;
}
// getName, getAge 메소드 추가
public String getName() {
return name;
}
public int getAge() {
return age;
}
// setter
public void setType(char type) {
this.type = type;
}
// setName, setAge 메소드 추가
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
* import java.util.Arrays;
import project.Human;
public class Student extends Human {
// final 키워드는 상수로 만들기 위한 키워드이다.
// static 키워드는 공용 변수로 만들기 위한 키워드이다.
// 즉, 아래는 공용 상수로 JOB 상수를 선언 및 초기화 한 것이다.
final static String JOB = "학생";
// 멤버 변수
private String className;
private int[] score;
public Student() {
super();
className = "";
score = new int[5];
}
// 생성자
public Student(String className, char type, String name, int age, int[] score) {
super(type, name, age);
this.className = className;
this.score = score;
}
public void setClassName(String className) {
this.className = className;
}
// setter
public void setScore(int index, int score) {
this.score[index] = score;
}
public String getClassName() {
return this.className;
}
// getter
public int getScore(int index) {
return this.score[index];
}
// print 메소드(추상 메소드 오버라이드)
@Override
public void print() {
System.out.println("============ 나의 학생 정보 =============");
System.out.println(className + "입니다.");
System.out.println("이름은 " + this.getName() + "입니다.");
System.out.println("나이는 " + this.getAge() + "입니다.");
// Arrays.toString을 이용하여 배열의 값을 문자열로 표시
System.out.println("점수는 " + Arrays.toString(score) + "점 입니다.");
System.out.println("총점은 " + this.getTotal() + "점입니다.");
System.out.println("평점은 " + this.getAverage() + "점입니다.");
System.out.println("=====================================");
}
// 총점 계산하기 메소드
public int getTotal() {
int total = 0;
for (int i = 0; i < score.length; i++) {
total += score[i];
}
return total;
}
// 평균 계산하기 메소드
public double getAverage() {
return getTotal() / this.score.length;
}
}
public class Teacher extends Human {
// final 키워드는 상수로 만들기 위한 키워드이다.
// static 키워드는 공용 변수로 만들기 위한 키워드이다.
// 즉, 아래는 공용 상수로 JOB 상수를 선언 및 초기화 한 것이다.
final static String JOB = "선생님";
// 멤버 변수
private String className;
// 생성자
public Teacher() {
super();
this.className = "";
}
public Teacher(String className, char type, String name, int age) {
super(type, name, age);
this.className = className;
}
// setter
public void setClassName(String className) {
this.className = className;
}
// getter
public String getClassName() {
return className;
}
// print 메소드(추상 메소드 오버라이드)
@Override
public void print() {
System.out.println("============ 나의 선생님 정보 =============");
System.out.println(className + "입니다.");
System.out.println("이름은 " + this.getName() + "입니다.");
System.out.println("나이는 " + this.getAge() + "입니다.");
System.out.println("성별은 " + this.getType() + "입니다.");
System.out.println("=====================================");
}
}
import review.Student;
import review.Teacher;
//학급 클래스로 선생님 객체와 학생 객체들을 가지고 있는 클래스이다.
public class ClassRoom {
// 멤버 변수
private String className;
private Teacher teacher;
private Student[] students;
// 생성자
ClassRoom() {
className = "";
teacher = new Teacher();
students = new Student[10];
for(int i = 0; i < students.length; i++) {
students[i] = new Student();
}
}
ClassRoom(String className) {
this();
this.className = className;
}
// setter
public void setClassName(String className) {
this.className = className;
this.teacher.setClassName(className);
for(int i = 0; i < students.length; i++ ) {
students[i].setClassName(className);
}
}
public void setStudent(int index, Student student) {
this.students[index] = student;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
// getter
public String getClassName() {
return this.className;
}
public Student getStudent(int index) {
return this.students[index];
}
public Teacher getTeacher() {
return teacher;
}
// print 메소드
public void printClassName() {
System.out.println(className + "입니다.");
}
public void printTeacher() {
this.teacher.print();
}
public void printStudents() {
for(int i = 0; i < students.length; i++) {
System.out.println(i+1 + "번 학생정보.");
students[i].print();
}
}
}
public interface SpecialJob {
public abstract int getJobLevel();
public abstract String getJobName();
public abstract void setJobLevel(int level);
public abstract void setJobName(String jobname);
}
// Boss 클래스의 부모는 Teacher
// 인터페이스를 상속(구현)하는 방법 implements SpecialJob
public class Boss extends Teacher implements SpecialJob {
final static String JOB = "교장선생님";
final static String SCHOOL = "코리아IT학교";
private int joblevel;
private String jobname;
private int roomno;
public Boss() {
this('남', "", 0);
}
public Boss(char type, String name, int age) {
// 교장선생님은 맡은 반이 없다.
// 그래서 className을 학교이름으로 설정
super(SCHOOL, type, name, age);
jobname = JOB;
joblevel = 10;
roomno = 101;
}
@Override
public int getJobLevel() {
return joblevel;
}
@Override
public String getJobName() {
return jobname;
}
public int getRoomNo() {
return roomno;
}
public String getSchool() {
return this.getClassName();
}
@Override
public void setJobLevel(int joblevel) {
this.joblevel = joblevel;
}
@Override
public void setJobName(String jobname) {
this.jobname = jobname;
}
public void setRoomNo(int roomno) {
this.roomno = roomno;
}
public void setSchool(String school) {
this.setClassName(school);
}
@Override
public void print() {
System.out.println("============ 나의 직업 정보 =============");
System.out.println( this.getClassName() + "의 " + jobname + "입니다.");
System.out.println("이름은 " + this.getName() + "입니다.");
System.out.println("나이는 " + this.getAge() + "입니다.");
System.out.println("방번호는 " + roomno + "호 입니다.");
System.out.println("직급으로는 " + joblevel + "레벨 입니다.");
System.out.println("=====================================");
}
}
import review.Boss;
import review.Student;
import review.Teacher;
public class Aschool {
public static void main(String[] args) {
// 교실 클래스와는 무관하므로 독립적으로 클래스 객체 생성 및 테스트
Boss boss = new Boss('남', "강감찬", 40);
boss.print();
// ClassRoom 클래스 객체 생성 및 테스트
ClassRoom room = new ClassRoom("컴퓨터 공학과");
// 선생님 클래스를 생성하여 클래스 room에 설정한다.
room.setTeacher(new Teacher(room.getClassName(), '남', "이성계", 50));
// 학생 클래스 객체의 생성과 설정을 동시에 간단하게.
String clsname = room.getClassName();
room.setStudent(0, new Student(clsname, '남', "이순신", 22, new int[]{10, 80, 80, 90, 70}));
room.setStudent(1, new Student(clsname, '남', "홍길동", 22, new int[]{20, 80, 80, 90, 70}));
room.setStudent(2, new Student(clsname, '남', "김유신", 22, new int[]{30, 80, 80, 90, 70}));
room.setStudent(3, new Student(clsname, '남', "김영철", 22, new int[]{40, 80, 80, 90, 70}));
room.setStudent(4, new Student(clsname, '남', "김대한", 22, new int[]{50, 80, 80, 90, 70}));
room.setStudent(5, new Student(clsname, '남', "김민국", 22, new int[]{60, 80, 80, 90, 70}));
room.setStudent(6, new Student(clsname, '여', "안녕히", 22, new int[]{70, 80, 80, 90, 70}));
room.setStudent(7, new Student(clsname, '여', "김말순", 22, new int[]{80, 80, 80, 90, 70}));
room.setStudent(8, new Student(clsname, '여', "이복길", 22, new int[]{90, 80, 80, 90, 70}));
room.setStudent(9, new Student(clsname, '여', "한강희", 22, new int[]{100, 80, 80, 90, 70}));
// 프린트 메소드 테스트
room.printClassName();
room.printTeacher();
room.printStudents();
}
}