java - overriding(1/2)
재정의
목표 : 부모가 가지고 있는 메소드를 물려받긴했지만 자식클래스에 맞게
기능을 변경하는 방법 알아보자
부모클래스도가지고있고 자식클래스에서도 가지고 있는 메소드 두개가 있으면
호출을 하면 ( 같은이름이겠지두개가 ) 부모클래스에 있는 메서드는 무시가 되고 자식 클래스에 있는 메서드가 호출이 된다. : 메서드 overriding
기본적인 컨셉: 하위클래스에서 사용할 것은 우선순위를 높게 부여했고 광범위하게 사용되는 것은 범위를 넓게 사용한다.
overriding 2/2
class SubstractionableCalculator extends Calculator {
public void sum() {
System.out.println("실행 결과는 " + (this.left + this.right) + " 입니다 . " ) ;
}
public int avg () {
return (this.left + thisright ) / 2 ;
-> 오버라이딩한 메소드를 재정의 해주면 된다.
하지만 return 값이 int 로 해놓았는데 부모타입의 avg메소드의 리턴 형식이 void 라서 서로 다르면 오류가 생긴다.
오버라이딩을 해야하면
1) 메소드의 이름
2) 메소드 매개변수의 숫자와 데이터 타입 그리고 순서
3) 메소드의 리턴타입
모두 동일해야한다.
이와 같이 메소드의 형태를 정의하는 사항들을 통털어서 메소드의 서명 (signature) 라고 한다.
그렇게 됬을때 부모와 자식의 메소드안에 리턴값도 전부 같아지겠지 ? ->
중복이 생긴다.
이렇게 써준다.
public int avg() {
return super.avg(); ( super는 부모로부터 온것 avg는 부모클래스의 메소드 )
super.부모클래스메소드() 쓰고 그 뒤에 좀 더 추가할 수 있다.
}
overloading (1/2)
public static void main ( String[] args) {
Calculator c1 = new Calculator () ;
c1.setOprands(10,20) ;
c1.sum();
c1.avg();
Calculator c2 = new Calculator () ;
c2.setOprands(20,40) ;
c2.sum();
c2.avg();
}
}
만약 넣는 변수를 3개로 설정하고 싶다면
public void setOpreands(int left , int right) {
System.out.println("setOprands(int left, int right) " ) ;
this.left = left;
this.right = right;
}
public void setOprands (int left, int right , int third) {
System.out.println("setOprands(int left , int right, int third) " ) ;
this.left = left;
this.right = right;
tjos.third = third;
}
메소드의 이름이 동일하더라고 해도 안에 넣는 인자가 다르면 다른 메서드로 인식이 가능하다.
중복을 없애보자
public void setOpreands(int left , int right) {
System.out.println("setOprands(int left, int right) " ) ;
this.left = left;
this.right = right;
}
public void setOprands (int left, int right , int third) {
this.setoprands(left,right);
System.out.println("setOprands(int left , int right, int third) " ) ;
this.third = third;
}
중복의 제거, 유지보수 편의성
오버로딩 ( overloading) : 같은이름 다른 매개변수인 것을 여러개 정의 하는 것이다.
overloading ( 2/2 ) 오버로딩의 규칙
메소드 오버로딩에서 리턴타입은 같은 매개변수형식을 가지고 있는 반환값이 달라지면 오버로딩이 되는게 아니라 오류가 발생
public class OverloadingDemo {
void A () {System.out.print("void A()") ; }
void A ( int arg1 { System.out.println("void A (int arg1) " ) ; }
void A ( String arg1 ) { System.out.println("void A (String arg1) " ) ; }
//int A() {System.out.println("void A()") ; } 매개변수를 가지고 있지 않은 두개의 같은이름의 메소드가 있는데 두개의 리턴값의 타입이 서로 다르다 . -> 오류
od.A(); 로 두개를 호출 하는건데, 이게 리턴값이 void 인지 int 인지 자바는 이해할 수 없다.
반환값은 메소드를 사용한 결과이기때문에
결과 : 메소드의 이름은 같아야하고 매개변수는 달라야하지만 리턴값만 다른것을 새로 만들어지지 않는다.
*매개변수의 이름은 상관이 없다.
그러니까 void A ( int arg1) 을 -> void A ( int param2 ) 이렇게도 메소드 overriding 을 할 수 없다.
그러니까 void A(int arg1 ) void A (int param ) 이렇게 두개를 쓸 수 없음.
****오버라이딩과 오버로딩의 차이
public class OverloadingDemo2 extends OverloadingDemo {
void A (String arg1 , String arg2 ) { System.out.println("sub class : void A ()"); }
//이 메소드는 인자가 두개고 각각의 인자는 문자열 특징
//밑에 있는 void A 는 있는데 매개변수가 다른애로 새로 만들었으니까 : 오버로딩
void A () {System.out.println("sub class : void A ()");} //인자가 없는 메소드는 분명이 부모에서도 존재하기 때문에 메소드 : 오버 라이딩
public static void main (String[] args ) {
OverloadingDemo2 od = new OverloadingDemo2();
od.A();
od.A(1);
od.A("coding everybody");
od.A("coding everybody", "coding everybody");
}
}
라이딩 . 로딩 riding , loading
라이딩 : 부모 클래스의 메소드의 동작방법을 변경하고, 로딩 : 같은 이름, 다른 매개변수의 메소드들을 여러개 만들 수 있다.
클래스패스 (1/3)컴파일과 클래스
클래스패스 (3.1) 클래스와 경로의 관계
클래스패스(3/3) 환경변수
환경변수는 운영체제안에 셋팅해주는 변수 global 한 변수
자바 가상머신과 같은 애플리케이션들은 환경변수의 값을 참고해서 동작하게 된다.
자바는 클래스 패스로 환경변수 CLASSPATH를 사용하는데 이 값을 지정하면 실행할 때마다 -classpath 옵션을 사용하지 않아도 되기에 편리하다. 하지만 운영체제를 변경하면 클래스 패스가 사라지기 때문에 이식성면에서 불리하다.
자바를 실행시킬 때 클래스를 사용하는데 클래스를 저장시킬 위치가 어디인지를 지정하는 것
다른 사람이 만든 클래스를 내가 만들던 클래스에 가지고 올때 경로를 지정해줄 필요가 있다.
컴파일을 할때마다 클래스패스를 설정하는건 번거롭다 -> 환경변수를 지정해준다.
환경변수셋팅 하는 방법이 나와있다.
패키지(1/4) : 패키지의 개념
여러개의 클래스들이 존재할 때
패키지를 통해서 이름의 중복문제를 해결할 수 있다.
정보공학에서는 '이름의 충돌' 이라는 문제를 해결하기 위해서 다양한 노력을 하고 있다. 전역변수와 지역변수, 객체도 그런 연장선에 있다고 볼 수 있다.
패키지 ( 2/4) : 패키지 사용
패키지 에서 오른쪽마우스 클릭 -> properties
패키지는 일종의 디렉토리의 개념
각각의 패키지가 디렉토리 안에 존재하기 때문에
import 를 해주지 않았을 시 : class B가 속해있는 패키지가 다른 패키지에 있는 A라는 클래스를 객체생성을 해주면 컴파일 오류로 됨
다른 패키지에 있는 클래스를 로드해주는 것이 불가능
기본적으로 같은 패키지에 있는 것이어야 함 -> 로드해주면 문제해결 -> import 해준다.
import 패키지B.* ;
.* 를 해주면 패키지B에 있는 모든 클래스를 가지고 올 수 있다.
--> 특정한 클래스만을 가지고 오려면
import 패키지B.A; --> 패키지 B 에있는 A라는 클래스를 가지고 오는 것
패키지 (3/4) : 손컴파일
BIN SRC
COMAND
cd..
dir/w
cd src
cd..
java_tutorials
cd ..
ㅁ
로드된 패키지들간의 중복
API와 API 문서 (1/2 ) : API
메소드 앞에 System.out이 있다. System은 클래스이고 out은 그 클래스의 필드 (변수) 이다.
-> 이 필드는 변수이다. -> 이 필드가 메소드를 가지고 있는 것은 이 필드 역시 객체라는 겨
것을 알 수 있다.
print는 System 소속이 아니라 out에 담겨져 있는 것이다. out이 가지고 있는 메소드가 println이다.
System을 객체화한적도 없고 import 를 한적도 없는데 어떻게 가져와서 쓸 수 있는 것인가?
import java.lang.* --> java.lang에 있는 모든 클래스를 로드한것.
System이라는 클래스가 java.lang 안에 있는 클래스이다.
만약
java.lang 이라는 패키지를 import 하지 않았다면 자바는 자동으로 java.lang 이라는 패키지를 import 한다. 자바가 기본으로 import 하는 애들
import 하는 수고를 덜어주기 위해 암시적으로 자동으로 java.lang 패키지를 import 를 해준다.
댓글
댓글 쓰기