🧩오늘의 알고리즘 : 두 수의 합 🧩
/*java로 작성한 코드*/
class Solution {
public int solution(int num1, int num2) {
return num1 +num2;
}
}
#python으로 작성한 코드
def solution(num1, num2):
answer = num1 + num2
return answer
오버로딩이 성립하기 위한 3가지 조건
1. 메서드 이름이 같아야 함
2. 매개변수의 개수 또는 타입이 달라야 함
3. 반환 타입은 영향없음
/*잘못 된 예시 1. 매개변수의 개수와 타입이 모두 같아서 오버로딩 X*/
int add(int a, int b) {return a+b;}
int add(int x, int y) {return x+y;}
/*잘못 된 예시 2. 위와 같은 타입의 중복 정의, 오버로딩 X*/
int add(int a, int b) {return a+b;}
long add(int a, int b) {return (long)(a+b);} // 반황 타입은 영향을 주지 않음
/*옳바른 오버로딩 예시*/
long add(int a, int b) {return a+b;}
long add(long a, int b) }{return a+b;} //메서드 이름이 같고, 매개변수의 타입이 다르기 때문에 오버로딩 O
Card c = new Card(); // Card() - 생성자 호출
클래스이름(타입 변수명, 타입 변수명, ...) {
// 인스턴스 생성 시 수행될 코드,
// 주로 인스턴스 변수의 초기화 코드를 작성함
}
class Card{
...
Card() { // 매개변수 없는 생성자
// 인스턴스 초기화 작업
}
Card(String kind, int number) { // 매개변수 있는 생성자
// 인스턴스 초기화 작업
}
}
클래스이름() {} // 기본 생성자
class Car{
String color; // iv, 색상
String gearType; // iv, 변속기 종류
int door; // iv, 문의 개수
Car() {} // 기본 생성자
Car(String c. String g, int d) { //매개변수가 있는 생성자
color = c;
gearType = g;
door = d;
}
}
왼쪽에 있는 코드를 오른쪽 처럼 한 줄로 사용할 수 가능
Car c = new Car();
c.color = "white"; => Car c = new Car("white", "auto", 4);
c.gearType = "auto";
c.door = 4;
추가 설명
iv(인스턴스 변수) => 참조변수.변수이름
참조변수 this ≠ 생성자 this()
this : 인스턴스 자신을 가리키는 참조 변수, 인스턴스의 주소가 저장되어 있음
this(), this(매개변수) : 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용
class MyMath2{
long a, b; // this.a, this.b - iv의 진짜 이름, this 생략 가능
MyMath2(int a, int b) { // 생성자 -> this 사용 가능
this.a = a; //this.a - iv, a - lv
this.b = b; // this 생략 불가, 지역 변수와 인스턴스 변수명이 같아 헷갈리기 때문
}
long add(){ // 인스턴스 메서드 -> this 사용 가능
return a + b; // return this.a + this.b; this 생략 가능
}
static long add(long a, long b) { // 클래스 메서드(static 메서드) => this 사용 불가
return a +b; // a, b는 지역 변수, iv 사용 불가 => this 사용 불가
}
}
class Car{
int door = 4; // 기본형 변수의 초기화
Engine e = new Engine(); // 참조형 변수의 초기화
}
Car(String color, String gearType, int door) { //매개변수가 있는 생성자
this.color = color;
this.gearType = gearType;
this.door = door;
}
class InitTest {
static int cv = 1; // 명시적 초기화 실행 순서 : 2
int iv = 1; // 실행 순서 : 5
static { cv = 2;} // 클래스 초기화 블럭 실행 순서 : 3
{iv = 2;} // 인스턴스 초기화 블럭 실행 순서 : 6
InitTest() { // 생성자
iv = 3; // 실행 순서 : 7
}
}
class StaticBlockTest {
static int[] arr = new int[10]; // 명시적 초기화
static {
for(int i=0; i<arr.length; i++){ // 클래스 (복잡)초기화 블럭 - 배열 arr을 난수로 채움
arr[i] = (int)(math.random()*10)+1;
}
}
}
클래스의 관계 1. 상속, 2. 포함
/*1번, 포함 관계 예제*/
class Circle { // 포함
MyPoint p = new MyPoint();
itn r;
}
public class InheritanceTest {
public static void main(String[] args) {
Circle c = new Circle();
c.p.x =1;
c.p.y =2;
c.r =3;
System.out.println("c.p.x=" + c.p.x);
System.out.println("c.p.y=" + c.p.y);
System.out.println("c.r=" + c.r);
}
}
/*2번, 참조변수 초기화만 하는 코드*/
class Circle { // 포함
// 참조변수의 초기화
MyPoint p // = new MyPoint();
itn r;
}
public class InheritanceTest {
public static void main(String[] args) {
Circle c = new Circle();
c.p.x =1;
c.p.y =2;
c.r =3;
System.out.println("c.p.x=" + c.p.x);
System.out.println("c.p.y=" + c.p.y);
System.out.println("c.r=" + c.r);
}
}
위의 코드를 1첫째 코드처럼 사용하고 싶다면 아래와 같이 수정하면 된다.
/*3번, 생성자를 사용해서 1번 코드와 같은 동작을 수행할 수 있도록 함*/
class Circle { // 포함
// 참조변수의 초기화
MyPoint p // = new MyPoint();
itn r;
}
Circle() {
p = new MyPoint();
}
public class InheritanceTest {
public static void main(String[] args) {
Circle c = new Circle();
c.p.x =1;
c.p.y =2;
c.r =3;
System.out.println("c.p.x=" + c.p.x);
System.out.println("c.p.y=" + c.p.y);
System.out.println("c.r=" + c.r);
}
}
상속 관계 '~은 ~이다. (is-a)' / 꼭 필요할때만 사용
포함 관계 '~은 ~을 가지고 있다. (has-a)' / 대부분 포함 관계 사용
EX)
class Parent {
void parentMethod() {}
}
class Child extends Parent {
void parentMethod() {} // 오버라이딩
void parentMethod(int i) {} // 오버로딩 (상속X)
void ChildMethod() {} // 메서드 정의
void ChildMethod(int i) {} //오버로딩
void ChildMethod() {} // 중복정의, 오류
}
super - 조상멤버와 자신멤버 구별할 때 사용
this - lv와 iv 구별할 때 사용
class EX1{
public static void main(String args[]) {
Child c = new Child();
c.method();
}
}
class Parent {int x = 10; /* super.x */}
class Child extends Parent {
int x = 20;
void method() {
System.out.println("x=" + x); //결과 x= 20
System.out.println("x=" + this.x); //결과 this.x= 20
System.out.println("x=" + super.x); //결과 super.x= 10
}
}
class EX2{
public static void main(String args[]) {
Child2 c = new Child2();
c.method();
}
}
class Parent2 {int x = 10; /* super.x와 this.x 둘 다 가능 */}
class Child2 extends Parent2 {
void method() {
System.out.println("x=" + x); //결과 x= 20
System.out.println("x=" + this.x); //결과 this.x= 20
System.out.println("x=" + super.x); //결과 super.x= 10
}
}
class Point {
int x, y;
Point (int x, int y) {
this.x = x;
this.y = y;
}
}
Point3D(int x, int y, int z){
super(x,y); // 조상클래스의 생성자 Point(int x, int y)를 호출
this.z = z; // 자신의 멤버를 초기화
}
- 생성자의 첫 줄에 반드시 생성자를 호출해야 함
- 그렇지 않으면 컴파일러가 생성자의 첫 줄에 super(); 삽입함
클래스를 사용할 때 패키지 이름을 생략할 수 있음
컴파일러에게 클래스가 속한 패키지를 알려줌
java.lang 패키지릐 클래스는 import 하지 않고 사용 가능
import문은 컴파일 시에 처리되므로 프로그램의 성능에 영향X
이름이 같은 클래스가 속한 두 패키지를 import할 때는 클래스 앞에 패키키명을 붙여줘야 함
이클립스 단축기 : ctrl+shift+o / 인텔리제이 단축키 : ctrl_alt+o
import문 선언방법
- import 패키지명.클래스명;
import문은 패키지문과 클래스선언 사이에 선언함
import static java.lang.Math.random;
import static java.lang.System.out;
// System.out.println(Math.random());
out.println(random));
접근 제어자 : public, protected, (default), private
> 접근 제어자가 제일 왼쪽에 작성되어야 함
그 외 : static, final, abstract, ...
멤버 변수
메서드
class StaticTest {
static int width = 200; // 클래스 변수(static 변수)
static int height = 120; // 클래스 변수(static 변수)
static { // 클래스 초기화 블럭
// static변수의 복잡한 초기화 수행
}
static int max(int a, int b) { // 클래스 메서드(static메서드
)
return a > b ? a : b;
}
}
클래스
메서드
멤버변수 / 지역변수
final calss FinalTest { // 조상이 될 수 없는 클래스
final int MAX_SIZE = 10; // 값을 변경할 수 없는 멤버변수(상수)
final void get MAXSIZE() { // 오버라이딩할 수 없는 메서드(변경불가)
final int LV = MAX_SIZE; // 값을 변경할 수 없는 지역변수(상수)
return MAX_SIZE;
}
}
클래스
abstract class AbstractTest{ // 추상 클래스(추상 메서드를 포함한 클래스)
abstract void move(); // 추상 메서드(구현부가 없는 메서드)
}
AbstractTest a = new AbstractTest(); //에러, 추상 클래스의 인스턴스 생성불가
/*추상 클래스를 상속 받아서 완전한 클래스를 만든 후에 객체 생성 가능*/
private : 같은 클래스 내에서만 접근이 가능
(default) : 같은 패키지 내에서만 접근이 가능
protected : 같은 패키지 내에서, 다른 패키지의 자손 클래스에서 접근 가능
public : 접근 제한이 전혀 없음
접근 제어자를 사용하는 이유
class Tv {
boolean power;
int channel;
void power() {power = !power;}
void channelUp() {++channel;}
void channelDown() {--channel;}
}
class SmartTv extends Tv{
Strign text; //캡션(자막)을 보여주기 위한 문자열
void caption() {/*생략*/}
}
Tv t = new SmartTv(); //타입 불일치하지만 가능
원래 - 타입을 일치시켜 사용함
Tv t = new Tv();
SmartTv s = new SmartTv();
객체와 참조변수의 타입이 일치할 때와 일치하지 않을 때의 차이
Tv t = new Tv(); // 참조 변수와 인스턴스의 타입이 일치
SmartTv s = new SmartTv(); // 조상 타입 참조변수로 자손 타입 인스턴스 참조
자손 타입의 참조변수로 조상 타입의 객체를 가리킬 수 없음
EX)
- Tv t = new SmartTv(); // 허용
- SmartTv s = new Tv(); // 허용 안 됨, 에러
Q. 참조변수의 타입은 인스턴스의 타입과 반드시 일치해야 함?
A. 일치하는 것이 보통이지만 일치 하지 않을 수도 있음.
Q. 참조변수가 조상타입일 때와 자손타입일 때의 차이는?
A. 참조변수로 사용할 수 있는 멤버의 갯수가 달라짐.
Q. 자손 타입의 참조변수로 조상 타입의 객체를 가리킬 수 있음?
A. 허용되지 않음.
열심히 유튜브 영상을 봤지만 원하는 목표치를 다 하지 못 했다,, 속상해😭 내일 더 열심히 해야지!