- 메서드의 이름은 물론 파라메터의 갯수나 타입도 동일해야 함
- 주로 상위 클래스의 동작을 상속받은 하위 클래스에서 변경하기 위해 사용
똑같은 클래스 내에서 완전히 똑같은 메소드를 만들어낼 수 없지만(그럴 이유도 없고), 상속 관계에서 부모의 메소드를 자식의 메소드를 재정의하여 사용할 수 있다.
똑같은 클래스 내에서는 오버로딩으로, "한 메소드"가 다양한 입력값을 받을 수 있는 식으로 활용이 되는 것이고 오버라이딩은 함수를 바꿔서 쓰려는 것이다.
| 메소드 상속받아 더 구현 |
public void print(){
super.print();
System.out.println("a");
}
오버라이딩 되었을 때
Parent도 public int getI()메소드를 가지고 있고, Child도 public int getI()메소드를 가지고 있다면
package family;
class Parent {
int i = 5;
public int getI() {
return i;
}
}
package family;
class Child extends Parent {
int i = 10; // 필드 오버라이딩
public int getI(){ // 메소드 오버라이딩
return i;
}
}
package family;
public class Exam06 {
public static void test(Parent p){
System.out.println(p.i);
System.out.println(p.getI());
}
public static void main(String[] args) {
Parent pc = new Child();
test(pc);
// 필드는 parent의 i=5, 메소드는 오버라이딩 된 getI() = 10
}
}
Child의 getI()메소드가 실행된다.
Object 클래스의 메소드들 활용하기🔗 Java Docs 🔎 java api Object

코딩을 하다보면 이렇게 객체의 설계도,
class에 구현해둔 필드•메소드들 외에 뜨는equals(),hashCode()와 같은 것들이 있다. 이 아이들은 모두Object클래스의 메소드들이다.
Object클래스는 왜 이 메소드들을 제공할까?
모든 클래스는 Object의 자손이다. 따라서 자식들인 모든 객체들은 이를 오버라이드해서 사용할 수 있다.Object가 이렇게 할 수 있도록 구현해둔 이유는 통일성 있게 출력하고 싶어서이다.
예를 들면, 세상에 있는 많은 객체들은 정보를 출력해보고 싶을 때가 있을 것이다. 이때 어떤 객체는 ~메소드로, 이 객체는 ~메소드로, ... 출력하기보다는 같은 방법으로 출력하는 편이 좋을 것이다. 그렇지 않는다면 정보를 보기 위해 사용해야 하는 메소드를 객체마다 매번 찾아야 할 것이기 때문이다. 변수는 출력하면 값이 나오지만, 객체는 값이 하나가 아니므로 이 정보를 보기 위해 저마다의 메소드가 만들어졌을 것이다. 따라서Object클래스는 정보를 보여주는 메소드toString()을 정의해두어 사용하는 방법에 통일성이 있을 수 있게 했다.
equals()
주소값을 비교하고 있기 때문에 달라요 라고 출력
하지만 같아요라고 하고 싶을 때가 있음
toString()처럼 equals 메소드를 오버라이드해서 활용해보자
"세상에 같은 게 하나도 없다"가 철학이지만 "같은 것끼리 모아봐"가 안되므로 필요한 기능 : equals()
default: 메모리 공간이 다를 것이므로 다르다고 출력할 것이지만 값이 같다면 같다고 출력하도록 equals() 바꿔주기
같은 애니? 판단
equals : 하나하나
레퍼런스 데이터 타입은 주소를 담고 있기 때문에 주소를 비교하는 거임
그래서 같니 라는 걸 얻기 위한 메소드 가 필요했구나~
equals 오버라이드 안 해두면 계속해서 주소로 비교
자료구조 배울 때 더 참고
hashcode
: 객체의 값을 알고리즘을 이용해 숫자값으로 바꿔서 같은 값이면 같은 숫자값 리턴 아니면 숫자값이 서로 다르게 리턴
hashcode가 속도 더 빠름(더 빠르게 값 도출)
cf.
가급적 표준을 지키는 게 좋지만 기업 입장에서는 내 거가 더 특별해야 선택받으니까
(~는 ~이렇게 쓰는 게 더 편하고~)이런 게 있음
그래도 표준을 지키는 게 편하긴 함
데이터베이스도 마찬가지
기본적 쿼리문은 다 같은데 또 회사마다 다른 것들이 있긴 함
String은 불변 클래스이다.불변 클래스란?
불변 클래스는 생성된 객체의 데이터를 수정할 수 없는 클래스다.
String str = "hello";
객체 = 생성된 메모리 상의 실체
이기 때문에 이 코드에서 객체는 "hello"이다. 불변 클래스 String에서 수정할 수 없는 건 바로 이 "hello"이다.
메모리상에서의 String
메모리에는 string값만 저장하는 공간이 존재한다. 메모리상에서 문자열이 너무 많이 생성되므로 더 효율적으로 관리할 방법을 제공하는 것이다.
String 타입과 primitive 타입의 비교
String | primitive type int |
|---|---|
String str1 = "hello"; | int num1 = 10; |
String str2 = str1; // str1과 같은 객체를 참조 | int num2 = num1; // num1의 값을 복사 |
System.out.println(str1); // "hello" | System.out.println(num1); // 10 |
System.out.println(str2); // "hello" | System.out.println(num2); // 10 |
// str1을 변경 (새 객체 생성) | // num1 값을 변경 |
⭐ str1 = str1.concat(" world"); | num1 = 20; |
// 결과 확인 | // 결과 확인 |
System.out.println(str1); // "hello world" | System.out.println(num1); // 20 |
System.out.println(str2); // "hello" | System.out.println(num2); // 10 |
⭐이 num1 = 20;과 같았다면?
num2의 값은 num1을 따라 변하지 않는다.str2의 값은 str1과 같이 변해버렸을 것이다.[
str1,str2]는 참조변수로, 하나를 변경하면 모든 참조 변수가 영향을 받게 되지만,
[num1,num2]는 기본형변수로, 독립적인 값을 가지기 때문에
num1값을 변경해도num2는 영향을 받지 않는다.
package day07;
public class StringTest {
public static void main(String[] args) {
MyClass myClass = new MyClass();
myClass.i = 10;
String str1 = "hello";
String str2 = new String("hello");
String str3 = new String("hell0");
String str4 = "hello";
}
}

↳ new해서 만드는 것이 다소 비효율적
그럼에도 생성자가 존재하는 이유는 다양한 방법으로 string 만들고 싶기도 하기 때문
package day07;
public class StringTest04 {
public static void main(String[] args) {
// 다른 객체들의 일반적 방법이었다~
String str = new String("Hello");
// 그런데 String은 너무 많이 사용이 되므로
// 자바가 설계할 때 이렇게 쓸 수 있게 했다.
String str2 = "hello";
// str2가 참조하는 객체와 동일한 "hello" 객체를 참조하고 있는 것
String str3 = "hello";
// string 객체가 스스로 바뀌면 안되겠구나~
// String 클래스가 가지고 있는 많은 메소드를 사용
// 명시적으로 추가해두어야 한다.
System.out.println(str3);
System.out.println(str2=str2.toUpperCase());
System.out.println(str2);
}
}

↳str2=str2.toUpperCase()에서 아예 새로운 "HELLO"라는 객체가 생성된다.
추상클래스의 필요성
추상클래스는 추상메소드를 가질 수 있다.
"동물?" "새?" "음식?" : 구체적이지 않다
기능구현이 어려운 애들은 추상적이기 때문
애매하다고 빼기에는,새.노래하다()라고 쓸 수 없다.
구현하지 않으면 자식이 구현하는 메소드를 부모가 쓸 수 없다.
"내가 구현하기 좀 힘들어"하는 애들 앞에abstract라고 써줌
추상메서드의 필요성
- 강제성
추상메서드를 가진 추상클래스를 상속받은 클래스는 반드시 메소드를 구현해야 한다는 강제성을 가진다.
↳ "꼭 있어야 해"라고 말을 해도 빼먹을 수 있는 것을 미연 방지 가능
- 표준화
다 ~방식으로 노래하게 될 것: 저마다 다르게 노래를 부르도록 하면 통일성이 없었을 것!
원래 부모가 물려주지 않은 것들은 접근할 수 없었음
그러나 추상메서드로라도 알고 있기 때문에 형변환 없이 자식의 메소드 사용하는 것이 가능
✏️ 새를 구현하려고 하는데 "짹짹" 할지 "뻐꾹"할지 모르기 때문에 추상 메소드를 만드는 것
✏️ 자바 api에도 이렇게 제공되고 있는 애들이 많음
↳ 객체 설계할 때에도 참고 가능!
이렇게 안 하면 결국 자식이 다 마지막에 구현해야 함.. 누군가는 구현해야 한다..
인스턴스화가 되지 않는다.(당연하지만~)
abstract를 붙이면 구현부{} 붙이면 안됨abstract 붙여줘야cf. Object 클래스의 toString() equals() : 추상메서드와 닮았다!!
Object는 왜 그럼 추상 클래스로 안 만들고, 추상 메소드로 안 만들고 구현해뒀을까?
추상 메소드는 강제성을 가지고 있기 때문에, 추상 메소드로 만들게 되면 모든 상속받은 자식들은 무조건 toString equals를 구현해야 하는데 모든 자식들이 이 둘이 필요하지 않음
구현하기 애매하지만 강제성까지는 필요 없을 때
필요에 따라서는 오버라이드해서 사용하고, 그렇지 않으면 쓰지 않도록
final어디에 붙냐에 따라~
| 위치 | final | |
|---|---|---|
| 메소드 | final | |
| 클래스 | final | |
| 필드 | final | 상수다 |
cf1. Math 클래스에 붙어있는 final
악의적으로 사용해버리면 안 되기 때문에 붙어있다.
cf2. 메소드에 붙어있는 final
오버로딩은 가능! 이름은 같고 다른 메소드이기 때문에
기타 쫌쫌따리 지식
- 메소드에 들어갈 때 모두 묵시적 형변환이 일어남
- return : 돌아간다~
- 문자열 조작: 문자열 Class
↳차를 차 클래스가 제일 잘 바꾸듯이