메소드 오버로딩(method overloading)
1. 동일한 명칭을 가진 메소드가 두개 이상인 경우를 메소드 오버로딩 상태라고 함. 같은 클래스에 있는 두개 이상의 같은 메소드명의 메소드를 말함.
2. 메소드가 중복 정의된 상태를 말함.
3. 오버로딩된 상태가 되려면 메소드 이름은 같지만 매개변수 리스트가 달라야 한다. 자료형, 갯수, 순서등이 틀린 경우만 허용.
//Class39.java
package com.test;
public class Class39 {
public int add() { //메소드 원본
int result = 0;
return result;
}
// private int add() { //접근 지정자를 바꾼 경우 -> 오버로딩 상태가 아님
// int result = 0;
// return result;
// }
// public void add() { //반환 자료형을 바꾼 경우 -> 오버로딩 상태가 아님
// int result = 0;
// return result;
// }
public int add(int a) { //매개변수 리스트를 변경한 경우 -> 오버로딩 상태임.
int result = 0;
return result;
}
public int add(int a, double b) { //매개변수 리스트를 변경한 경우 -> 오버로딩 상태임.
int result = 0;
return result;
}
public int add(double a, int b) { //매개변수 리스트를 변경한 경우 -> 오버로딩 상태임.
int result = 0;
return result;
}
//main() 메소드는 유일하게 존재해야 하는 메소드임.
public static void main(String[] args) {
//println()메소드의 오버로딩 상태 확인
System.out.println();
System.out.println("");
//add() 메소드의 오버로딩 상태 확인
Class39 obj = new Class39();
obj.add();
obj.add(10);
obj.add(10.0, 20);
}
}
문제) 덧셈 결과를 출력하는 메소드 만들기. 오버로딩 메소드로 구현.
1. 1부터 10까지의 합을 출력
-> public int add()
2. 1부터 n까지의 합을 출력
-> public int add(int n)
3. n부터 m까지의 합을 출력
-> public int add(int n, int m)
4. n부터 m까지의 합을 출력하되, x의 배수만 계산
-> public int add(int n, int m, int x)
5. 임의의 수를 여러개 입력 받아서 합을 출력
-> public int add(int[] arr)
실행 예)
덧셈 결과를 출력하는 메소드 만들기
1. 1부터 10까지의 합을 출력
2. 1부터 n까지의 합을 출력
3. n부터 m까지의 합을 출력
4. n부터 m까지의 합을 출력하되, x의 배수만 계산
5. 임의의 수를 여러개 입력 받아서 합을 출력
6. 종료
선택(1~5, 6:종료)?1
1부터 10까지 합 : xxxx
덧셈 결과를 출력하는 메소드 만들기
1. 1부터 10까지의 합을 출력
2. 1부터 n까지의 합을 출력
3. n부터 m까지의 합을 출력
4. n부터 m까지의 합을 출력하되, x의 배수만 계산
5. 임의의 수를 여러개 입력 받아서 합을 출력
6. 종료
선택(1~5, 6:종료)?2
숫자 입력(n)? 100
1부터 100까지 합 : xxxx
//Calc.java
//Process.java
//Class40.java -> main() 포함
package com.test;
public class Calc {
public int add() { //1부터 10까지의 합을 출력
int result = 0;
for (int a=1; a<=10; a++) {
result += a;
}
return result;
}
public int add(int n) {//1부터 n까지의 합을 출력
int result = 0;
for (int a=1; a<=n ; a++) {
result += a;
}
return result;
}
public int add(int n, int m) {//n부터 m까지의 합을 출력
int result = 0;
for (int a=n; a<=m ; a++) {
result += a;
}
return result;
}
public int add(int n, int m, int x) {//n부터 m까지의 합을 출력하되, x의 배수만 계산
int result = 0;
for (int a=n; a<=m ; a++) {
if (a%x == 0) {
result += a;
}
}
return result;
}
public int add(int[] arr) {//임의의 수를 여러개 입력 받아서 합을 출력
int result = 0;
for(int a=0; a<arr.length; a++){
result += arr[a];
}
return result;
}
}
package com.test;
import java.util.Scanner;
public class Process {
public void menu1() {
Calc obj = new Calc();
System.out.printf("결과 : %d %n", obj.add());
}
public void menu2() {
Calc obj = new Calc();
Scanner sc = new Scanner(System.in);
System.out.print("숫자(n)?");
int n = sc.nextInt();
System.out.printf("1부터 %d까지의 합 : %d %n", n, obj.add(n));
}
public void menu3() {
Calc obj = new Calc();
Scanner sc = new Scanner(System.in);
System.out.print("숫자(n)?");
int n = sc.nextInt();
System.out.print("숫자(m)?");
int m = sc.nextInt();
System.out.printf("%d부터 %d까지의 합 : %d %n", n, m, obj.add(n, m));
}
public void menu4() {
Calc obj = new Calc();
Scanner sc = new Scanner(System.in);
System.out.print("숫자(n)?");
int n = sc.nextInt();
System.out.print("숫자(m)?");
int m = sc.nextInt();
System.out.print("배수(x)?");
int x = sc.nextInt();
System.out.printf("%d부터 %d까지의 숫자 중 %d의 배수들의 합 : %d %n", n, m, x, obj.add(n, m, x));
}
public void menu5() {
Scanner sc = new Scanner(System.in);
System.out.print("갯수 입력(2~10)?");
int size = sc.nextInt();
int[] arr = new int[size];
for (int a=0; a<arr.length; a++) {
System.out.printf("숫자%d?", (a+1));
arr[a] = sc.nextInt();
}
Calc obj = new Calc();
int result = obj.add(arr);
System.out.print("입력 받은 숫자 : ");
for (int a=0; a<arr.length; a++) {
System.out.printf("%d ", arr[a]);
}
System.out.println();
System.out.printf("입력 받은 숫자들의 합 : %d %n", result);
}
}
package com.test;
import java.util.*;
public class Class40 {
public static void main(String[] args) {
//메뉴구성(무한반복)
Scanner sc = new Scanner (System.in);
Process obj = new Process();
do{
System.out.println();
System.out.println();
System.out.println("덧셈 결과를 출력하는 메소드 만들기");
System.out.println("1. 1부터 10까지의 합을 출력");
System.out.println("2. 1부터 n까지의 합을 출력");
System.out.println("3. n부터 m까지의 합을 출력");
System.out.println("4. n부터 m까지의 합을 출력하되, x의 배수만 계산");
System.out.println("5. 임의의 수를 여러개 입력 받아서 합을 출력");
System.out.print("선택(1~5, -1:종료)?");
int menu = sc.nextInt();
if (menu == -1) {
System.out.println("프로그램을 종료합니다.");
break;
}
switch (menu) {
case 1: obj.menu1(); break;
case 2: obj.menu2(); break;
case 3: obj.menu3(); break;
case 4: obj.menu4(); break;
case 5: obj.menu5(); break;
}
}while(true);
}
}
상속(inheritance)
1. 객체 지향 프로그램에서 가장 중요한 개념.
2. 객체 지향 프로그램의 특성
- 상속, 다양성, 은닉성, 캡슐화
3. 클래스와 클래스 사이에 부모, 자식 관계가 맺어진 상태를 상속이라고 한다. 상속 관계인 클래스들은 파생 할 수 있는 상태가 된다.
원본A 클래스(기능3가지) -> (상속) -> 파생 B 클래스(기능3가지+기능 추가)
수퍼(부모) 클래스 서브(자식) 클래스
파생B 클래스는 원본 A 클래스의 기능을 재구현하기 위해서 해야 할 일이 없는 상태다. -> 상속 받겠다는 구문만 추가하면 됨.
서브 클래스가 수퍼 클래스를 선택해서 상속 표현하면 수퍼 클래스의 기능을 모두 내것으로 만들 수 있다.
상속 관계가 계속 이루어지는 경우 모든 수퍼 클래스의 모든 기능은 서브 클래스가 가지게 된다.
A 클래스(3가지) -> 상속 -> B 클래스(3가지 + 2가지) -> 상속 -> C 클래스(5가지+1가지)
4. 상속 관계에서 최상위 클래스는 Object 클래스이다. Object 클래스만은 상속 표기를 하지 않아도 자동 상속된다.
5. 상속 표기
public class 서브클래스명 extends 수퍼클래스명 {
//수퍼클래스의 멤버는 자동으로 서브클래스것이 된다.
//추가 멤버 구성
}
//Class41.java
package com.test;
//모든 클래스는 자동으로 Object 클래스를 상속받는다.
public class Class41 {
public static void main(String[] args){
Class41 obj = new Class41();
//Object 클래스에서 구현된 멤버인 toString() 메소드를 Class41 클래스의 멤버인 것처럼 호출 가능
String result1 = obj.toString(); //-> 객체명(자료형@해시코드) 리턴
System.out.println(result1);
//객체가 생성될 때마다 고유하게 생성되므로 독립적인 상태가 된다.
Class41 test = new Class41();
String result2 = test.toString();
System.out.println(result2);
}
}
수퍼클래스, 서브클래스 구현하기
//Super.java -> 메소드 한개만 구현
package com.test;
//Object 클래스 자동 상속
public class Super {
public void method1() {
}
}
//Sub.java -> 메소드 한개만 구현
package com.test;
//super 클래스를 상속받고 있다.
public class Sub extends Super {
//Super 클래스의 멤버도 Sub 클래스의 멤버가 된다.
//sub 클래스만의 고유 멤버 추가
public void method2() {
}
}
//Class42.java -> main()
//Sub 클래스의 멤버확인 -> 2개
package com.test;
public class Class42 {
public static void main(String[] args) {
//Sub 클래스의 객체 생성 과정
Sub obj = new Sub();
//멤버구성 확인
obj.method1(); //-> Super의 고유멤버
obj.method2(); //-> Sub의 고유멤버
}
}
6. 상속은 수퍼 클래스를 한개만 선택할 수 있다.
7. 수퍼클래스의 멤버중에서 private 멤버는 상속 받을 수 없다.
8. final 키워드가 있는 클래스는 상속 받을 수 없다.
문제) 프린터라는 원본 클래스를 가지고 파생을 시켜본다.
//원본 클래스
public class 프린터 {
public void 인쇄(String 출력대상) {
System.out.println(출력대상);
}
}
//파생0 클래스
public class 프린터종이추가 extends 프린터 {
public void 종이추가(int 종이) {
if (종이 == 0){
종이 = 100;
}
}
}
//파생1 클래스
public class 프린터잉크교체 extends 프린터종이추가 {
public void 잉크교체() {
새로운잉크카트리지;
if (잉크 == 0) {
잉크 = 새로운잉크카트리지;
}
}
}
//파생2 클래스
public class 복합기프린터_스캐너 extends 프린터잉크교체 {
public void 스캐너(String 스캔대상) {
Scanner sc = new Scanner(System.in);
String bmp = sc.next();
}
}
//파생3 클래스
public class 복합기프린터_팩스 extends 복합기프린터_스캐너 {
public void 팩스(전송서류) {
팩스 = 전송서류;
}
}
//파생4 클래스
public class 복합기프린터_이메일 extends 복합기프린터_팩스 {
public void 복합기(String 이메일) {
이메일 전송 처리클래스 obj = new 이메일 전송 처리클래스();
obj.이메일전송(이메일);
}
}
상속 제한1 - 수퍼클래스를 한개만 선택할 수 있다.
//Class43.java
package com.test;
//물리적인 java 파일 한 개에 논리적인 class가 여러개인 경우는
//파일명과 동일한 클래스를 제외하고 나머지 클래스는 public 지정 불가
/*
class Super1 {
}
class Super2 {
}
//다중 상속 불가 -> 인터페이스를 가지고 다중 상속을 시켜야 한다.
class Sub1 extends Super1, Super2 {
}*/
interface Super1 {
}
interface Super2 {
}
class Sub1 implements Super1, Super2 {
}
public class Class43 {
public static void main (String[] args){
}
}
상속 제한2 - 수퍼 클래스의 멤버중에서 private 멤버는 상속받을 수 없다.
//Super3.java
//Sub3.java
//Class44.java
package com.test;
public class Super3 {
//private 멤버
private void method1(){
}
//public 멤버
public void method2(){
}
//protected 멤버
protected void method3(){
}
}
package com.test;
public class Sub3 extends Super3 {
//Super3 클래스의 멤버들 중에서 특정 멤버는 상속을 받게된다.
//-> method2(), method3()
//private 멤버
private void method4(){
}
//public 멤버
public void method5(){
}
//protected 멤버 -> 같은 패키지 및 상속 관계에서 서브 클래스에서만 접근 가능.
protected void method6(){
}
}
package com.test;
public class Class44 {
public static void main(String[] args) {
Super3 obj1 = new Super3();
//Super3 클래스의 객체인 obj1은 하위 멤버를 ..... 가질 수 있다.
//method2 , method3
// obj1.method1(); //접근 불가 접근지정자가 private이므로 ㅇㅇ
obj1.method2();
obj1.method3();
Sub3 obj2 = new Sub3();
//Sub3 클래스의 객체인 obj2는 하위멤버 ()를 접근할 수 있다.
//method2, method3, method5 method6
//obj2.method1(); //X. Super3 클래스의 멤버. private 이므로..
obj2.method2(); //O Super3 클래스의 멤버. 상속받은 멤버
obj2.method3(); //O Super3 클래스의 멤버. 상속받은 멤버
//obj2.method4(); //X private 멤버는 접근 불가.
obj2.method5(); //O
obj2.method6(); //O
}
}
--------------------------- 다른 패키지 ---------------------------------
//Sub4.java
package com.sample;
import com.test.Super3;
public class Sub4 extends Super3 {
public void method7() {
//다른 패키지의 수퍼 클래스에 있는 protected 멤버는 서브 클래스에서 접근 가능.
//method3() 호출
this.method3();
}
}
//Class45.java
package com.sample;
import com.test.Sub3;
public class Class45 {
public static void main(String[] args) {
Sub3 obj2 = new Sub3();
//Sub3 클래스의 객체인 obj2는 하위멤버 ()를 접근할 수 있다.
//method2, method3, method5 method6
//obj2.method1(); //X.
obj2.method2(); //O
//obj2.method3(); //X. protected 접근 지정자. 다른 패키지에서 접근 불가
//obj2.method4(); //X
obj2.method5(); //O
//obj2.method6(); //x protected 접근 지정자. 다른 패키지에서 접근 불가
Sub4 obj3 = new Sub4();
//Sub4 클래스의 객체인 obj3는 하위멤버 ()를 접근할 수 있다.
//method2, method3, method5 method6
obj3.method2();
//obj3.method3();// X. 실제 호출하는 위치가 다른 패키지이기 때문에 안됨.
obj3.method7();
}
}
상속제한3 - final 키워드가 있는 클래스는 상속 받을 수 없다.
//Class46.java
package com.test;
import java.util.*;
final class FinalSuper { //파이널(상속 불가) 클래스
}
//class Sub extends FinalSuper { //X. 상속 불가
//
//}
class Sub extends Random {
}
public class Class46 {
public static void main(String[] args) {
FinalSuper obj = new FinalSuper(); // 객체 생성가능
//파이널클래스
System.out.println();
Scanner sc = new Scanner(System.in);
//일반클래스
Random rd = new Random();
int[] arr = new int[10];
Arrays.sort(arr);
}
}
메소드 오버라이딩(method overriding)
1. 동일한 명칭을 가진 메소드가 두개 이상인 경우를 메소드 오버라이딩 상태라고 함. 단, 서로 다른 클래스에서 같은 메소드가 존재하는 경우이고, 서로 다른 클래스는 상속 관계일 때만 성립.
2. 메소드가 재정의된 상태를 말함.
class Super {
public void method() {
//기능1
}
}
class Sub extends Super {
@Override
public void method() { //메소드 오버라이딩
//기능2 -> 기능1을 재정의한 상태
}
}
class Sub2 extends Sub {
@Override
public void method() { //메소드 오버라이딩
//기능3 -> 기능2을 재정의한 상태
}
}
//Class47.java
package com.test;
class Super4 {
public int add() {
//1 부터 10까지의 합을 계산해서 리턴
int result = 0;
for (int a=1 ; a<= 10; a++) {
result += a;
}
return result;
}
}
class Sub4 extends Super4 {
@Override
public int add() { //메소드 오버라이딩
//1 부터 100까지의 합을 계산해서 리턴
int result = 0;
for (int a=1 ; a<= 100; a++) {
result += a;
}
return result;
}
}
public class Class47 {
public static void main(String[] args) {
Super4 obj1 = new Super4();
System.out.printf("1부터 10까지의 합 : %d %n", obj1.add());
Sub4 obj2 = new Sub4();
System.out.printf("1부터 100까지의 합 : %d %n", obj2.add());
}
}
Member 클래스의 toString() 메소드 오버라이딩 테스트
//Member.java -> 이름, 전화번호 저장용 클래스
//Class48.java
package com.test;
public class Member {
private String name, tel;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
//toString() 메소드 오버라이딩 구현
//이클립스에서 오버라이딩 구현 기능 사용
//Source -> Override/Implement Methods...
@Override
public String toString() {
String result = "";
result = String.format("%4s %9s", this.getName(), this.getTel());
return result;
}
}
package com.test;
import java.util.*;
public class Class48 {
public static void main(String[] args) {
//입력
Scanner sc = new Scanner(System.in);
System.out.print("회원수 입력(1~10)?");
String num = sc.next();
int count = Integer.parseInt(num);
//이름및 전화번호 자료형 클래스 활성화 및 저장용 배열 생성
Member[] members = new Member[count]; // 사용자 정의 클래스 자료형인 배열을 생성
//처리
for (int a=0; a<members.length; a++) {
System.out.printf("이름:전화번호(%d)?", (a+1));
String name = sc.next(); //이름
String tel = sc.next(); //전화번호
Member member = new Member(); // Member 객체 생성 과정
member.setName(name); //Member 객체에 이름 저장
member.setTel(tel); //Member 객체에 전화번호 저장
members[a] = member; //Member 객체를 배열에 저장하는 과정
}
//출력
System.out.println("----------------");
System.out.printf("전체 회원수: %d명%n", count);
System.out.println("----------------");
System.out.println("이름 전화번호");
for (int a=0; a<members.length; a++) {
//System.out.printf("%4s %8s %n", ((Member)members[a]).getName(), ((Member)members[a]).getTel()); //캐스트 연산자 Member는 클래스 자료형이니까 ㅇㅇ
//오버라이딩 하기 전 상태 -> 해시코드 출력.
//오버라이딩 후 -> 재정의된 내용으로 출력.
System.out.println(members[a].toString());
}
System.out.println("----------------");
}
}
문제) 덧셈 결과를 출력하는 메소드 만들기. toString()메소드를 오버라이딩하여 구현.
1. 1부터 10까지의 합을 출력
2. 1부터 n까지의 합을 출력
3. n부터 m까지의 합을 출력
4. n부터 m까지의 합을 출력하되, x의 배수만 계산
실행 예)
덧셈 결과를 출력하는 메소드 만들기
1. 1부터 10까지의 합을 출력
2. 1부터 n까지의 합을 출력
3. n부터 m까지의 합을 출력
4. n부터 m까지의 합을 출력하되, x의 배수만 계산
선택(1~5, -1:종료)?1
1부터 10까지 합 : xxxx
//Calc2.java
//Class49.java
package com.test;
public class Calc2 {
private int n, m, sum;
private String x = "";
//기본생성자
public Calc2() {
this(1, 10, 1); //this 생성자
}
//생성자 오버로딩
public Calc2(int n) {
this(1, n, 1);
}
//생성자 오버로딩
public Calc2(int n, int m) {
this(n, m, 1);
}
//생성자 오버로딩
public Calc2(int n, int m, int x) {
this.n = n;
this.m = m;
if (x > 1) {
this.x = String.format("(%d의 배수만 계산)", x);
}
for (int a=n; a<=m; a++) {
if(a%x == 0) {
this.sum += a;
}
}
}
@Override // 상위상속클래스인 Object 클래스의 멤버인 toString()의 오버라이딩 (메소드 재정의)
public String toString() {
String result = "";
result = String.format("%d부터 %d까지의 합 %s : %d", this.n, this.m, this.x, this.sum);
return result;
}
}
package com.test;
public class Class49 {
public static void main(String[] args) {
Calc2 obj1 = new Calc2();
System.out.println(obj1.toString());
Calc2 obj2 = new Calc2(10);
System.out.println(obj2.toString());
Calc2 obj3 = new Calc2(10, 20);
System.out.println(obj3.toString());
Calc2 obj4 = new Calc2(1, 100, 5);
System.out.println(obj4.toString());
}
}
1부터 10까지의 합 : 55
1부터 10까지의 합 : 55
10부터 20까지의 합 : 165
1부터 100까지의 합 (5의 배수만 계산) : 1050