JAVA

[JAVA]객체#2

로돌씨 2024. 2. 20. 18:18

overloading

오버로딩이란 한클래스 내에서 같은 이름의 메소드를 여러개 사용하는것!

  1. 메소드 이름이같고
  2. 매개변수의 타입 , 갯수가 달라야함

-this: 할당된 객체를 가르킴 , 객체의 주소를 자동으로 받음

-this():같은클래스의 다른 생성자 호출

 

package com.test.chapter05_method.test01;

public class OverLoadingTest {
//같은 클래스 내부에서 같은 이름의 메소드를 여러개 쓰는 구문
	public int /*리턴값*/ test() {
		System.out.println("String");
		return 0;
		//생성자구문
	}

	public int test(int a) { // 같은 이름에도 사용가능한 모습 (매개변수값을 지정해줬기떄문에 )
		// ol.test(a); 로 실행
		return 0;
	}

	public int test(int a, int b) { // ol.test(a, b);로 실행
		return 0;
	}

	public int test(int a, String b) {// 같은 수 지만 타입이 다르기때문에 에러 x
		return 0;
	}
	
	 /* public int test(int b , int a) { return 0 ; } 에러발생, 
	 * 매개변수명은 상관없이 자료형의 갯수와 순서가 다르게 작성되어야한다.
	 */
	public int test(String b,int a) {
		return 0; //자료형의 순서가 달라 에러 x 
	}
	/*public String test(int a , int b , String str) {
		return null;
	}
	public int test(int a , int b ,String str) {
		return 0; // -> 에러 , 리턴타입이 다르다고 오버로딩이 적용되는건 아님
	}
	*/
/*private String test(int a , int b ,String str) {
	return null;  -> 에러 , 접근제한자가 다르다고 오버로딩이 적용되는건 아님
	*/ 
}

 

static / nonstatic method()

static

  • 클래스내에서 static 키워드로 선언된 변수 / 메서드
  • 인스턴스가 여러개 생성되어도 스태틱으로 선언된 변수/메서드는 한번만 생성 가능
  • 동일한 클래스에 의해 생성된 모든 인스턴스가 공유함

non-static

  • 클래스 내에서 그냥 선언된 변수 / 메서드
  • 인스턴스간에 공유되지 않음
  • 객체가 생성될 때마다 새롭게 변수/메서드 생성
public class StaticMethodTest {
	//리턴값이 있는 메소드
public static void staticmethod1() {
	int num1 = 10;
	int num2 = 20;
	System.out.println("10과 20의 합은 "+(num1+num2)+ "입니다.");
	
}
public static String staticmethod2(String name) {
	//리턴값이 있는 메소드
	return name + "님의 방문을 환영합니다. ";
}
}

-> static 

 

public class NonStaticMethodTest {
// 매개변수 유무와 반환값 유무에 따른 메소드 표현
	//1. 매개변수 없고 = () 반환값 없는 메소드 = void
	public void method1() {
		System.out.println("매개 변수와 반환값이 둘다 없는 메소드.");
		//return; 이 생략 되어있음.
		
	}
	//2. 매개변수 있고 반환값이 없는 메소드
public void method2(int num1, int num2) { //필드변수가 아닌 지역변수 = 메소드 내에서만 사용해라.
	int sum = num1 + num2;
	System.out.println(sum);
	return;
}
//3.매개 변수 없고 반환값이 있는 메소드
public String method3() { //리턴값이 없어서 에러 ,
	return "매개 변수 없고 반환값이 있는 메소드.";
}
//4.매개변수있고 반환값도 있는 메소드
public int method4(int num1,int num2) {
	return num1 + num2 ;
	//int sum = num1 + num2 ; 
	//return sum; 이렇게도 가능
}

	
}

-> non-static

 

public class Run {

	public static void main(String[] args) {
		// TODO Auto-generatd method stub
		NonStaticMethodTest ns = new NonStaticMethodTest(); // 괄호가 비어 있기에 기본생성자
		
		//매개변수와 반환값이 없는 메소드 호출
	    ns.method1();
	    //매개변수가 있고 반환값이 없는 메소드
	    ns.method2(5,7); //매개 변수가 sum이었기때문에 출력값은 1+3으로 표기됨
	    //매개변수 없고 반환값이 있는 메소드
	    //ns.method3(); // -> 메소드 호출문 자체가 "매개변수가없고 반환값이 있는 메소드"
	    String res = ns.method3();
	    System.out.println(res); // -> 잘 실행이되는모습

	    System.out.println(ns.method3());//-> 이것또한 잘 실행이 된다.
	    //매개변수와 반환값이 모두 있는 메소드
	    int res1 = ns.method4(5,6);// 리턴값인 int  선언 해준뒤에 출력 
	    System.out.println(res1); 

	    System.out.println(ns.method4(6, 7)); //마찬가지로 잘 실행이 되는 모습

	    //클래스명.메소드명()
	    StaticMethodTest.staticmethod1();
	    String res2 = StaticMethodTest.staticmethod2("박영석");
	    System.out.println(res2);
	    
	    
	}

} 
출력값 :
매개 변수와 반환값이 둘다 없는 메소드.
12
매개 변수 없고 반환값이 있는 메소드.
매개 변수 없고 반환값이 있는 메소드.
11
13

10과 20의 합은 30입니다.
박영석님의 방문을 환영합니다.

-> 실행문과 출력값!

 

객체배열

객체를 저장하는 배열로 배열의 자료형을 클래스명으로 지정하여 사용

 

public class Book {
private String title;
private String writer;
private String publisher;
private int price;

//생성자 (기본 하나 매개변수 하나 )
public Book () {}
public Book (String title , String writer, String publisher, int price ) {
	this.title = title;
	this.writer = writer;
	this.publisher = publisher;
	this.price = price;
	
}
// 프라이빗은 외부에서 접근 불가능 그래서 게터 세터메소드를 만들어줄것
public String getTitle() {// 해당 필드 ( 타이틀 ) 의 자료형과 동일하게 , get필드명() {} 
	return title;
}
public void setTitle(String title) { // 값을 저장만 하기때문에 리턴값은 필요없음 ( void ) , set필드명(자료형 타이틀) {}
	this.title = title;
}
public String getWriter() {
	return writer;
}
public void setWriter(String writer) {
	this.writer = writer;
}
public String getPublisher() {
	return publisher;
}
public void setPublisher(String publisher){
	this.publisher = publisher;
}
public int getPrice() {
	return price;
}
public void setPrice(int price) {
	this.price = price;
}
public String information () {
	return "title = " + title + ", writer : "+ writer + ", publisher : "+publisher+ ", price :"+ price ; 
}
}

예제

package com.test01.run;
import java.util.Scanner;
import com.test01.model.*;

public class ObjectArrayTest {

	public static void main(String[] args) {

		// 선언 및 할당
		//Book[] bk = new Book[3];
		//초기화 
		//bk[0] = new Book();
		//bk[1] = new Book();
		//bk[2] = new Book();
		
		//선언 할당 초기화 동시에
		Book[] bk = { 
				new Book("자바의 정석","홍길동","한빛",20000)	,
				new Book("이것이 자바다","신용권","한빛",30000),	
				new Book("이것이 mysql이다" ,"이창진", "멀티",40000),
		};
System.out.println(bk); // 배열자체의 주솟값이 출력됨 (Book [])의 값출력 
System.out.println(bk[0]); // 첫번째 방(객체)의 주솟값이 출력됨 (Book)의 값 출력 
System.out.println(bk[0].getPrice()); // get이용해서 필드 price의 값 가르킴 (int)
//도서출력
for ( int i = 0; i <bk.length ; i ++ ) {
System.out.println(bk[i].information());
//for문을 이용해 모두 출력
	}
//도서 검색 
//제목을 입력받아 저장된 book객체중 title값과 동일하면 information 실행
Scanner sc = new Scanner(System.in);
System.out.print("도서명 검색: ");
String searchTitle = sc.nextLine();
for(int i = 0; i < bk.length ; i++) {
	if (bk[i].getTitle().equals(searchTitle)) {
		System.out.println(bk[i].information());
		break;
	}//객체 배열을 이용해 북클래스의 정보 찾기
}
}
}
출력값->
[Lcom.test01.model.Book;@2173f6d9
com.test01.model.Book@307f6b8c
20000
title = 자바의 정석, writer : 홍길동, publisher : 한빛, price :20000
title = 이것이 자바다, writer : 신용권, publisher : 한빛, price :30000
title = 이것이 mysql이다, writer : 이창진, publisher : 멀티, price :40000
도서명 검색: 이것이 자바다
title = 이것이 자바다, writer : 신용권, publisher : 한빛, price :30000

-> 출력

package com.test01.run;

import java.util.Scanner;

import com.test01.model.*;

public class ObjectTest {
	public static void main(String[] args) {
		// 객체 배열만 써보기
		Book Bt1 = new Book("자바의정석 ", "홍길동", "한빛", 20000);
		// 매개변수에 해당하는 내용을 직접적어 값 출력
		Book Bt2 = new Book("이것이자바다", "신용권", "한빛", 30000);
		Book Bt3 = new Book("이것이 mysql이다", "홍길동", "이창진", 40000);
		//각각의 객체에서 인포메이션이 출력이 됨 (각각 다른 메세지 출력됨)
		System.out.println(Bt1.information());
		System.out.println(Bt2.information());
		System.out.println(Bt3.information());
		// 도서 검색
		Scanner sc = new Scanner(System.in);
		System.out.println("도서명 검색 : ");
		String searchTitle = sc.nextLine();
		
		if(Bt1.getTitle() /*게터를 이용해 캡슐화하여 접근이안되는값을 가져옴*/.equals(searchTitle)) {
			System.out.println(Bt1.information());
		}else if(Bt2.getTitle().equals(searchTitle)) {
			System.out.println(Bt2.information());
		}else if(Bt3.getTitle().equals(searchTitle)) {
			System.out.println(Bt3.information());
		} //.equals ->스트링( 문자열 ) 이 같다는 뜻 , int의  '==' 과 흡사 
		// 책이 만개가 넘는다면 이프문을 만개이상쓰기 힘드니 여기서 객체 배열을 사용할수있도록 배워보자 . 
	}
}
->출력값
title = 자바의정석 , writer : 홍길동, publisher : 한빛, price :20000
title = 이것이자바다, writer : 신용권, publisher : 한빛, price :30000
title = 이것이 mysql이다, writer : 홍길동, publisher : 이창진, price :40000
도서명 검색 : 
이것이자바다
title = 이것이자바다, writer : 신용권, publisher : 한빛, price :30000

-> 출력

 

상속(inherit)

  • 다른클래스가 가지고있는 멤버 (필드 , 메소드)를 새로작성할 클래스에 만드는게아닌 원래있던클래스에서 상속받음으로서써 새클레스에서 자신의 멤버처럼 사용가능
  • 작은양의 코드로 새로운클래스 작성 가능
  • 에러 발생시에 부모클래스만 수정하면 되니 유지보수에 용이함
클래스 간 상속시 extends 사용
ex) class A extends B{}

 

import java.util.Date;

public class Television {
	private String brand;
	private String productNumber;
	private String productCode;
	private String productName;
	private int price;
	private Date date;
	private int inchType;
	

	// 생성자(기본 ,매개변수)

	public Television() {
	}

	public Television(String brand, String productNumber, String productCode, String productName, int price, Date date,
			int inchType) {
		this.brand = brand;
		this.productNumber = productNumber;
		this.productCode = productCode;
		this.productName = productName;
		this.price = price;
		this.date = date;
		this.inchType = inchType;

	}

	// getter & setter
	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public String getProductNumber() {
		return productNumber;
	}

	public void setProductNumber(String productNumber) {
		this.productNumber = productNumber;
	}

	public String getProductCode() {
		return productCode;
	}

	public void setPruductCode(String productCode) {
		this.productCode = productCode;
	}

	public String getProductName() {
		return productName;
	}

	public void setProductName(String productName) {
		this.productName = productName;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}
	public int getInchType() {
		return inchType;
	}public void setInchType(int inchType) {
		this.inchType = inchType;
	}
	public String information() {
		return brand + ", " + productNumber+", "+ productCode + ", " + productName + ", "+ price + "," + date + "," + inchType ; 
	}
}//상속을 이용해 데스크탑과 텔레비전의 부모클래스를 만들어 중복되는 코드를 줄여보자.
import java.util.Date;

public class Desktop {
	private String brand;
	private String productNumber;
	private String productCode;
	private String cpu;
	private int hdd;
	private int ram;
	private String os;
	private int price;
	private Date date;
	private boolean allinOne;

	public Desktop() {
	}



	public Desktop(String brand, String productNumber, String productCode, String cpu, int hdd, int ram, String os,
			int price, Date date, boolean allinOne) {
		this.brand = brand;
		this.productNumber = productNumber;
		this.productCode = productCode;
		this.cpu = cpu;
		this.hdd = hdd;
		this.ram = ram;
		this.os = os;
		this.price = price;
		this.date = date;
		this.allinOne = allinOne;
	}

	public String getBrand() {
		return brand;

	}
	public void setBrand(String brand) {
		this.brand = brand;
	}
	public String getProductNumber() {
		return productNumber;

	}
	public void setProductNumber(String productNumber) {
		this.productNumber = productNumber;
	}
	public String getProductCode() {
		return productCode;

	}
	public void setProductCode(String productCode) {
		this.productCode = productCode;
	}
	public String getCpu() {
		return cpu;

	}
	public void setCpu(String cpu) {
		this.cpu = cpu;
	}
	public int getHdd() {
		return hdd;

	}
	public void setHdd(int hdd) {
		this.hdd = hdd;
	}
	public int getRam() {
		return ram;
	}
	public void setRam(int ram) {
		this.ram = ram;
	}
	public String getOs() {
		return os;
	}
	public void setOs(String os) {
		this.os = os;
	}
	public int getPrice() {
		return price;
		
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public Date getDate() {
		return date;
	}
	public void setDate(Date date) {
		this.date = date;
	}
	public boolean getAllinOne() {
		return allinOne;
	}
	public void getAllinOne(boolean allinOne) {
		this.allinOne = allinOne;
	}
	public String information() {
		return brand +", " + productNumber + ", " + productCode + ", " + cpu + ", " + hdd + ", "+ ram + ", "
				+os+", " + price + ", " + date + ", " + allinOne ;
	}
}

→ 예제 (캡슐화 → 기본생성자 → 매개변수 생성자 this.변수명=변수명 ;→ getter , setter → 인포메이션)

package com.inherit.part01_inheritTest.before;
import java.util.Date;
public class Run {
public static void main(String[] args) {
	Television tv = new Television ("LG" , "01" , "T-1234","LG TV" , 5000000 , new Date(), 65);
	Desktop d = new Desktop("삼성" , "02" , "D-1234" , "i9" , 500 , 64 , "window 11 " , 2000000 ,new Date() , false);
System.out.println(tv.information());
System.out.println(d.information());
}
}
출력값:
LG, 01, T-1234, LG TV, 5000000,Wed Mar 01 11:28:16 KST 2023,65
삼성, 02, D-1234, i9, 500, 64, window 11 , 2000000, Wed Mar 01 11:28:16 KST 2023, false

-> 출력시 

상속 기능사용하기전엔 이렇게 중복되는 코드가많고 한번바꿀때 둘다 수정을 해줘야하는 번거로움이 생기며 보기에도 양이많아 힘들다. 상속을 이용해 코드의 양을 줄여보자 

1. super() 를 통해 부모 클래스 생성

package com.inherit.part01_inheritTest.after;
import java.util.Date;
public class Product {
//모든 상품에 대한 공통적인 요소만 추출하여 작성할 '부모클래스'
private String brand;
private String productNumber;
private String productCode;
private String productName;
private int price;
private Date date;



public Product() {
	super(); //부모클래스(object)를 생성하는 구문
}
public Product(String brand, String productNumber, String productCode, String productName, int price, Date date) {
	super();
	this.brand = brand;
	this.productNumber = productNumber;
	this.productCode = productCode;
	this.productName = productName;
	this.price = price;
	this.date = date; //자동 생성 (우클릭 -> 소스 -> 제네레이트 유징 필드) 
}
public String getBrand() {
	return brand;
}
public void setBrand(String brand) {
	this.brand = brand;
}
public String getProductNumber() {
	return productNumber;
}
public void setProductNumber(String productNumber) {
	this.productNumber = productNumber;
}
public String getProductCode() {
	return productCode;
}
public void setProductCode(String productCode) {
	this.productCode = productCode;
}
public String getProductName() {
	return productName;
}
public void setProductName(String productName) {
	this.productName = productName;
}
public int getPrice() {
	return price;
}
public void setPrice(int price) {
	this.price = price;
}
public Date getDate() {
	return date;
}
public void setDate(Date date) {
	this.date = date;
} // 우클릭-> 소스 -> 제네레이트 게터 세터 
public String information() {
	return brand + ", " + productNumber + ", " +productCode + ", " + productName + ", " + price + ", " + date ;
}
}

2.public class Computer extends Product 를통해 부모 클래스를불러와주고 그밑에 추가 , this생성후 게터 세터 생성

import java.util.Date;

public class Computer extends Product{
	private String cpu;
	private int hdd;
	private int ram;
	private String os;
 public Computer () {
	 
 }
public Computer(String brand, String productNumber, String productCode, String productName, int price, Date date) {
	super(brand, productNumber, productCode, productName, price, date);
	// TODO Auto-generated constructor stub
	
}


public Computer(String brand, String productNumber, String productCode, String productName, int price, Date date,
		String cpu, int hdd, int ram, String os) {
	super(brand, productNumber, productCode, productName, price, date);
	this.cpu = cpu;
	this.hdd = hdd;
	this.ram = ram;
	this.os = os;
}
public String getCpu() {
	return cpu;
}
public void setCpu(String cpu) {
	this.cpu = cpu;
}
public int getHdd() {
	return hdd;
}
public void setHdd(int hdd) {
	this.hdd = hdd;
}
public int getRam() {
	return ram;
}
public void setRam(int ram) {
	this.ram = ram;
}
public String getOs() {
	return os;
}
public void setOs(String os) {
	this.os = os;
}

public String information() {
	return super.information()+ "," + cpu + ", " + hdd + ", " + ram + ", "+os ;
}
}

3.다시 불러와 데스크탑 클래스 생성

package com.inherit.part01_inheritTest.after;

import java.util.Date;

public class Desktop extends Computer {
	private boolean allInOne;

	public Desktop() {
	}

public Desktop(String brand, String productNumber, String productCode, String productName, int price, Date date,
		String cpu, int hdd, int ram, String os, boolean allInOne) {
	super(brand, productNumber, productCode, productName, price, date, cpu, hdd, ram, os);
	this.allInOne = allInOne;
}



public String information() {
	return super.information() + ", " + this.allInOne;
}
}

4. 제일 상위에있는 부모클래스(product) 만 불러와 텔레비전 클래스 생성

package com.inherit.part01_inheritTest.after;

import java.util.Date;

public class Television extends Product { // extends 클래스명 을 이용해서 상속클래스를 만들어줬음.
	private int inchType;

	public Television() { // 기본생성자에 슈퍼 추가
		super();
	}

	public Television(String brand, String productNumber, String productCode, String productName, int price,
			Date date , int inchType) {
		super(brand, productNumber, productCode, productName, price, date);
		// TODO Auto-generated constructor stub

		this.inchType = inchType;
// 소스 -> 제네레이트 유징필드 + 위 항목에서 두번째항목눌러 슈퍼안의값도 다 받아옴 
		System.out.println("Product를 상속받은 Television클래스 생성자 호출완료");

	}

	public int getInchType() {
		return inchType;
	}

	public void setInchType(int inchType) {
		this.inchType = inchType;
	}

	@Override
	public String information() {
		return super.information() + ", " + inchType; // 부모클래스의 인포메이션을 가져온 모습
	}

}

 

package com.inherit.part01_inheritTest.after;

import java.util.Date;

public class Run {
	public static void main(String[] args) {
		Television t = new Television("LG", "01", "T-123", "LGTV", 5000000, new Date(), 65);
		Desktop d = new Desktop("삼성", "02", "S-1234", "삼성컴퓨터", 2000000, new Date(), "i9",60,50,"window11",true );
		System.out.println(t.information());
		System.out.println(d.information());
	}
}
출력값:
Product를 상속받은 Television클래스 생성자 호출완료
LG, 01, T-123, LGTV, 5000000, Wed Mar 01 12:33:16 KST 2023, 65
삼성, 02, S-1234, 삼성컴퓨터, 2000000, Wed Mar 01 12:33:16 KST 2023,i9, 60, 50, window11, true

-> 출력값

 

오버라이드(Override)

자식 클래스가 상속 받은 부모 메소드를 재작성 하는 것 부모가 제공하는 기능을 후손이 일부 고쳐 사용하겠다는 의미로 자식 객체를 통한 실행 시 후손 것이 우선권을 가짐

특징:

메소드 헤드라인 위에 반드시 Annotation, @Override 표시 접근 제어자를 부모 것보다 같거나 넓은 범위로 변경 가능 부모 메소드의 예외처리 클래스 처리범위보다 좁은 범위로 예외처리 클래스 수정 가능

조건:

부모 클래스의 메소드와 자식 클래스의 메소드 비교

  • 메소드 이름 동일
  • 매개변수의 개수, 타입 동일
  • 리턴 타입 동일

-private 메소드 오버라이딩 불가

package com.inherit.part02_override;

public class Book {
	private String title;
	private String writer;
	private int price;

	public Book() {
	}

	public Book(String title, String writer, int price) {
		super();
		this.title = title;
		this.writer = writer;
		this.price = price;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getWriter() {
		return writer;
	}

	public void setWriter(String writer) {
		this.writer = writer;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return title + ", " + writer + "," + price;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		// 전달받은 객체가 null인경우 무조건 다른객체
		if (obj == null) {
			return false;
		}
		// ---------------------------------------//
		// 전달받은 객체의 필드값과 비교하여 같은지 판단 .
		Book other = (Book) obj;
		if (title == null) {
			if (other.title != null) {
				return false;
			}
		} else if (!title.equals(other.title)) {
			return false;
		}
		if (writer == null) {
			if (other.writer != null) {
				return false;
			}
		} else if (!writer.equals(other.writer)) {
			return false;
		}
		if (price != other.price) {
			return false;
		}
		return true;
	} // b1과b2가 false 에서 true로 바뀜
	
	@Override
	public int hashCode() {
		return (title+writer+price).hashCode();
	}
}

-> 예제

package com.inherit.part02_override;

public class Run {
	public static void main(String[] args) {
		Book b1 = new Book("수학의 정석" , "이창진" , 100);
		Book b2 = new Book("이것이 자바다" , "홍길동 " , 200);  
		
		System.out.println("b1 = "+b1);
		System.out.println("b2 = "+b2);
		System.out.println(b1.equals(b2));
		
		Book b3 = b1; //주솟값 복사
		System.out.println(b1.equals(b3));
		
		Book b4 = new Book("수학의 정석" , "이창진" , 100);
		//new 연산자를 통해 새로운 객체 생성
		System.out.println("b1과 b4는 같은 객체? : " + b1.equals(b4)); //데이터만 같을뿐 객체는 같지않음
		
		System.out.println(b1.hashCode());
		System.out.println(b4.hashCode()); //해시 코드가 달랐으나 같아진 모습
	}
	
}
출력값:
b1 = 수학의 정석, 이창진,100
b2 = 이것이 자바다, 홍길동 ,200
false
true
b1과 b4는 같은 객체? : true
-228702489
-228702489

-> 출력문

 

이렇듯 비슷한 특징을 가진 클래스들을 하나의 클래스를 이용해 상속하여 하나의 클래스만으로 여러 제품들의 정보를 설명하거나 나열하기 쉽고 코드의 양도 현저히 줄어듦과 동시에 가시성도 좋아져 코드를 읽기에 수월해졌다!

'JAVA' 카테고리의 다른 글

[JAVA]예외처리  (0) 2024.02.22
[JAVA]객체#3  (0) 2024.02.21
[JAVA]객체지향 프로그래밍  (0) 2024.02.19
[JAVA]배열  (0) 2024.02.14
[JAVA]조건문  (1) 2024.02.13