super()

부모 객체의 메소드 기능에 추가적으로 내 기능을
더하고 싶으면 super라는 지시어를 통해 부모 메소드를
호출할 수 있다. super.메소드명() 으로 호출하면 된다.

인터페이스(Interface)

  • 추상화보다 더 높은 추상화 개념을 적용한 것이다.
  • 멤버 변수는 가지지 못하며, 추상 메소드만 가진다.
  • 추상 클래스를 고도화시킨 문법이며, 반드시 추상메소드와 상수만 선언해야 한다.
  • 밑그림만 그려져 있는 기본 설계도라고 표현할 수 있다.
  • 다중 상속이 가능하다.
  • 다른 클래스를 작성하는데 도움 줄 목적으로 작성된다.

인터페이스는 상속, 부모 클래스, 추상 클래스, 추상 메소드, 다형성(오버라이드), 그리고 형변환의 개념을 모두 가지고 있는 종합선물세트다.

무조건 자식 클래스는 메소드를 정의(재정의)해야 한다.
구현도 해야한다.

인터페이스 제약 사항

  • 모든 멤버변수는 상수(public static final)만 가질 수 있다.
  • 모든 멤버메소드는 추상 메소드(public abstract)만 가질 수 있다.
    단, static 메소드와 디폴트 메소드는 예외(1.8 버전 이후)

인터페이스 문법

    	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 지시어를 사용하면 동일한 클래스로 만들어진 모든 객체들이
공유하는 공유 변수 또는 함수(메소드)가 된다.
멤버 변수 앞에 사용하면 변수를 클래스의 공용(공유) 변수로 만든다.
멤버 함수 앞에 사용하면 함수를 클래스의 공용(공유) 함수로 만든다.
일반적으로 static 변수는 영문 대문자만 사용한다.

final

  • final은 모든 변수, 클래스, 메소드 등의 앞에 사용가능하지만, 기본적인 개념은 최종이라는 큰 맥락을 가지고 있다.
  • 멤버 변수 또는 일반 변수에서 사용시 값을 변경할 수 없는 상수가 된다.
  • 클래스에서 사용시 변경될 수 없는 or 상속될 수 없는 클래스를 의미한다.
  • 메소드에서 사용시 변경될 수 없는 메소드로 오버라이딩을 할 수 없다.

HomeWork


  • 기존의 Human 클래스와 동일
	// 추상 클래스
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;
	}
}
  • Student 클래스
    총점 계산하는것과 평균 계산하는 메소드 추가
* 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;
	}
}
  • Teacher 클래스
	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("=====================================");
	}
}
  • ClassRoom 클래스
	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);
}
  • Teacher 클래스를 상속받고 SpecialJob 인터페이스를 상속받음
	// 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("=====================================");
	}
}
  • main
	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();
	}
}
  • 출력

profile
최선을 다하자!!

0개의 댓글

Powered by GraphCDN, the GraphQL CDN