기록
  • 0926 12일차
    2023년 09월 26일 16시 33분 28초에 업로드 된 글입니다.
    작성자: 삶은고구마

    sc.nextLine(); 개행을 없애주지만 대기중

    이전에 개행이 남아있지 않은 상태

    즉, 맨 처음 이 코드를 실행한다면 엔터를 한 번 더 쳐야 그 다음 코드가 실행

    입력버퍼는 하나로 공유하기때문에 이전에 입력한 개행이 버퍼에 남아있으면 다음 nextLine에 영향을끼침

     

    Entity class = VO class

    new TestBookArray().menu(); //한번쓰고 말겠다 1회용 호출
    TestBookArray app = new TestBookArray(); //변수 생성해서 재사용
    app.menu();

     

    입력받은 알파벳을 무조건 대문자로 변경 한 후, 첫 번째 글자만을 char 변수로 할당하는 코드

    char gender = sc.next().toUpperCase().charAt(0);

     


    1.상속

    다른 클래스(부모)가 가지고 있는 멤버들을 새로 작성할 클래스(자식)에서 직접 만들지 않고 상속 받음으로써

    새 클래스가 자신의 멤버처럼 사용할 수 있는 기능

    =>코드의 재사용,관리 용이

    =>하나의 클래스를 여러 클래스가 상속 받을 수 있음. 한 부모 여러 자식.

    =>부모 클래스 private 멤버는 상속 되는데 직접 접근 불가(.) 상속은 일방통행

     

    public class 자식클래스명 extends 부모클래스명 

    자식이 부모보다 할 수 있는 것이 더 많다. 그래서 extend(확장)의 의미를 갖고있음.

    한 부모 클래스 아래에 여러 자식 클래스를 둘 수 있는데 자식클래스끼리는 별개라 서로 영향없음.

     

    1.모든 클래스는 Object의 후손이다.

    Object는 메소드만 있는데, 모든 클래스에서 사용 가능 ex)hashCode,toString..

    2.생성자,초기화 블럭은 상속 대상이 아니다.

    자식 생성자 안에서 super()로 부모생성자 호출 가능.

    3.부모의 private 멤버(필드/메소드)는 직접 접근이 불가능하다.

    자식클래스도 불가능하다.

    1)부모클래스의 필드/메소드의 접근제한자를 protected로 변경.

    2)접근제한자를 변경할 수 없다면 super생성자 or getter/setter를 통해 처리한다.(보통 전자의 방법을 쓴다)

    ex) 생성자:super(매개인자);, getter setter:setCreatedAt(createdAt);

    4.override 메소드

    부모메소드를 재작성해서 씀.

    메소드 시그니처(접근제한자 리턴타입 메소드명 매개변수 예외)가 동일해야함.

    -접근제한자는 더 개방가능 보통은 public으로 변경

    -예외선언도 제거 가능 throws 뒤 익셉션 제거

    /**
    	 * 오버라이드 규칙
    	 * 1.부모메소드 시그니쳐 동일
    	 * 2.접근제한자를 더 개방하는쪽으로 변경
    	 * private:애초에 오버라이드 안됨
    	 * default:잘 안씀
    	 * protected=>public <<이걸씀
    	 * 3.에외던지기 구문을 축소(일부 제거
    	 * =더 호출하기 편한 방향으로 편집
    	 * 4.공변반환타입 허용 - 리턴타입을 자식타입으로 변환가능
    	 */	
    	@Override
    	//protected Object clone() throws CloneNotSupportedException {
    	public Car clone(){
    		//복사생성자 이용
    		
    		//return new Car(this.brand,this.model,this.color); //필드값이 동일한 객체 생성
    		return new Car(this); //복사 생성자 /주소값만
    		//this:자기자신
    	}

    상속 예제1

    parents - child - grandchild

                                 - child2

    더보기
    package sh.java.inheritance.simple;
    
    
    /**
     * @author 고혜진
     * 2023-09-26
     * 부모 클래스의 선언된 멤버변수/멤버메소드 (non-static)를 
     * 자식클래스에서 선언없이 제 것처럼 사용할 수 있게 하는 문법
     * 
     *
     */
    public class Main 
    {
    	public static void main(String[] args)
    	{
    		Child c = new Child();
    		c.hello();
    		c.name = "홍길동";
    		c.age = 10;
    		System.out.println(c.info());
    		System.out.println();
    		//이런식으로 자식객체를 여러개 만들 수 있고, 당연히 부모의 변수,함수도 사용가능.
    		
    		Child2 c2 = new Child2();
    		c2.name="윤봉길";
    		c2.age = 25;
    		System.out.println(c2.info());
    		c2.hello();
    		c2.game();
    		//c2.camp();// 형제클래스 기능 사용불가. c1와 c2는 별개의 클래스임.
    		System.out.println();
    		
    		//부모의 부모 함수변수사용도 가능
    		GrandChild gc = new GrandChild();
    		gc.hello();
    		gc.name = "농담곰";
    		gc.age = 5;
    		System.out.println(gc.info()); 
    		gc.camp();
    		System.out.println();
    		
    		//부모도 자식의 기능(필드,메소드)을 사용할 수 있는가?!	=>no..
    		Parent p = new Parent();
    		System.out.println(); 
    		p.hello(); 
    		//p.camp();//부모타입에서 자식타입은 사용 불가능
    		
    
    		
    	}
    }
    package sh.java.inheritance.simple;
    
    /**
     * 2023-09-26
     * 자식 클래스
     *
     */
    public class Child extends Parent
    {
    	//method overriding(덮어쓰기?) 
    	//메소드 시그니처 동일 = 접근제한자, 리턴타입, 메소드명 , 매개변수부 까지 동일해야함
    	//@Override : 사용시 문법적으로 오류를 컴파일타임(코드 작성 시)에 체크할 수있다.런타임:실행시
    	@Override
    	public void hello()
    	{
    		super.hello();//부모타입에 선언된 메소드 호출
    		System.out.println("나는 자식이다");
    	}
    	
    	public void camp()
    	{
    		System.out.println("자식이 캠핑감");
    	}
    }
    package sh.java.inheritance.simple;
    
    public class Child2 extends Parent 
    {
    	public void game()
    	{
    		System.out.println("자식2가 게임을 한다.");
    	}
    }
    package sh.java.inheritance.simple;
    
    
    //java에서는 다중상속을 지원하지 않는다. extends Child,Parent (x)
    public class GrandChild extends Child 
    {
    	//gc입장에서는 상속에서 가까운 child를 따르게된다
    	//child의 camp 메소드 메소드 시그니처 동일하게
    	@Override
    	public void camp() 
    	{
    		System.out.println("손자가 캠핑감");
    	}
    }
    package sh.java.inheritance.simple;
    /**
     * @author 고혜진
     * 2023-09-26
     * 상속개념 예제 부모 클래스
     */
    public class Parent //extends Object 생략되어있는 구문,모든 클래스에서 Object 기능 사용가능
    {
    	String name;
    	int age;
    	
    	public void hello()
    	{
    		System.out.println("내가 부모다.");
    	}
    	
    	public String info()
    	{
    		return this.name+","+this.age;
    	}
    }

     

     

    상속예제2

    실행클래스:ProductMain

    부모클래스:Product

    자식클래스:DeskTop,Tv,SmartPhone

    더보기
    package sh.java.inheritance.product;
    
    import java.time.LocalDate;
    
    /**
     * @author 고혜진
     * 2023-09-26
     *
     */
    public class ProductMain 
    {
    	public static void main(String[] args)
    	{
    		//데스크탑 객체
    		Desktop desktop1 = new Desktop(1,"내컴퓨터1","삼성",1000000,LocalDate.now(),
    				"Win11",16,"i-9",1024);
    		Desktop desktop2 = new Desktop(2,"내컴퓨터2","애플",2000000,LocalDate.now(),
    				"MacOs",16,"m2",1024);
    		
    		//스마트폰 객체
    		SmartPhone smartPhone1 = new SmartPhone(3,"갤럭시S23","삼성",1000000,LocalDate.now(),
    				"안드로이드","sk");
    		SmartPhone smartPhone2 =new SmartPhone (4,"아이폰14","애플",1500000,LocalDate.now(),
    				"ios","kt");
    		
    		//티비 객체
    		Tv  tv1 = new Tv(5,"샤오미 롤러블tv","샤오미",5000000,LocalDate.now(),
    				"UHD",80);
    		Tv  tv2 = new Tv(6,"lg 롤러블tv","LG",10000000,LocalDate.now(),
    				"FHD",100);
    		
    //		desktop1.printProductInfo();
    //		desktop2.printProductInfo();
    //		smartPhone1.printProductInfo();
    //		smartPhone2.printProductInfo();
    //		tv1.printProductInfo();
    //		tv2.printProductInfo();
    		
    		System.out.println(desktop1);
    		System.out.println(desktop2);
    		System.out.println(smartPhone1);
    		System.out.println(smartPhone2);
    		System.out.println(tv1);
    		System.out.println(tv2);
    	}
    }

     

    package sh.java.inheritance.product;
    
    import java.time.LocalDate;
    
    
    
    
    /**
     * 2023-09-26
     * 상속 Inheritance
     * -부모클래스의 멤버필드/멤버메소드를 자식클래스에서 선언없이 사용할 수 있는 문법
     * -중복(공통)된 코드 관리가 용이하다.
     * 
     * 특징
     * 1.모든 클래스는 Object의 후손이다.
     *   -object는 메소드만있는데, 모든 클래스에서 사용가능/hashCode,toString...
     * 2.생성자,초기화블럭은 상속 대상이 아니다.
     *   -자식생성자 안에서 super()로 부모생성자 호출가능
     * 3.부모의 private 멤버는(필드/메소드) 직접 접근이 불가능하다.(자식도 불가능)
     *   -부모클래스의 필드/메소드를 protected로 접근제한자 변경
     *   -private로 해야한다면 super 생성자/getter&setter를 통하여 값을 세팅. 
     *    생성자:super(code,name, brand, price, createdAt);
     *    겟셋:setCreatedAt(createdAt);
     * 4.override 메소드
     *   -부모 메서드를 재작성해서 씀.
     *   -메소드 시그니처(접근제한자,리턴타입,메소드명,매개변수,예외)가 동일해야함. 
     *     -접근제한자는 더 개방가능
     *     -예외선언도 제거 가능
     *   -super참조를 통해 부모메소드 호출 가능
     *   -private, final(고쳐쓰지못함 상수) 메소드는 오버라이드 불가
     * 5.자바는 단일상속만 가능 extends a,b 이런거 없다
     * 6.final 클래스는 상속이 불가
     *   -String class
     */
    public class Product 
    {
    	//상품들마다 공통된 속성들을 부모클래스로 가져옴
    	
    	//private=>protected로 변경
    	//protected:다른패키지여도 상속관계면 ok
    //	protected long code;//식별자
    //	protected String name;//상품명
    //	protected String brand;//브랜드
    //	protected int price; //가격
    //	protected LocalDate createdAt;//제조일
    	
    	private long code;//식별자
    	private String name;//상품명
    	private String brand;//브랜드
    	private int price; //가격
    	private LocalDate createdAt;//제조일
    	
    	public Product()
    	{
    		super(); //오브젝트 호출
    	}
    
    	public Product(long code, String name, String brand, int price, LocalDate createdAt) {
    		super();
    		this.code = code;
    		this.name = name;
    		this.brand = brand;
    		this.price = price;
    		this.createdAt = createdAt;
    	}
    
    	public long getCode() {
    		return code;
    	}
    
    	public void setCode(long code) {
    		this.code = code;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public String getBrand() {
    		return brand;
    	}
    
    	public void setBrand(String brand) {
    		this.brand = brand;
    	}
    
    	public int getPrice() {
    		return price;
    	}
    
    	public void setPrice(int price) {
    		this.price = price;
    	}
    
    	public LocalDate getCreatedAt() {
    		return createdAt;
    	}
    
    	public void setCreatedAt(LocalDate createdAt) {
    		this.createdAt = createdAt;
    	}
    	
    	public void printProductInfo()
    	{
    		System.out.print("code:"+code+"/"
    				+  "name:"+name+"/"
    				+  "brand:"+brand+"/"
    				+  "price:"+price+"/"
    				+  "createdAt:"+createdAt);
    	}
    
    	//오후에 추가
    	@Override
    	public String toString() {
    		return "code=" + code + ", name=" + name + ", brand=" + brand + ", price=" + price + ", createdAt="
    				+ createdAt + ",";
    	}
    	
    	
    	
    }
    package sh.java.inheritance.product;
    
    import java.time.LocalDate;
    
    import sh.java.inheritance.simple.Parent;
    
    public class Desktop extends Product
    {
    
    	private String os;//운영체제버전
    	
    	private int ram;
    	private String cpu;
    	private int storage;
    	
    	public Desktop()
    	{
    		super();
    	}
    	/**
    	 * super()
    	 * -부모생성자 호출
    	 * -this() or super() 생성자 맨 첫줄에 한 번 반드시 호출되어야함.
    	 * -매개인자를 전달해 필드생성자 호출가능
    	 * -생략가능.
    	 * @param code
    	 * @param name
    	 * @param brand
    	 * @param price
    	 * @param createdAt
    	 * @param os
    	 * @param ram
    	 * @param cpu
    	 * @param storage
    	 */
    
    	public Desktop(long code, String name, String brand, int price, LocalDate createdAt, String os, int ram, String cpu,
    			int storage) {
    		//protected 필드인 경우엔 직접 접근 가능.
    //		this.code = code; 
    //		this.name = name;
    //		this.brand = brand;
    //		this.price = price;
    //		this.createdAt = createdAt;
    		
    		
    		//부모클래스로 이동한 code가 private속성이라 사용못한다고 에러남. 자식클래스도 외부클래스임
    		//부모클래스에서 물려받은 필드의 접근 제한자가 private인 경우, 직접 접근 불가
    		//만약 필드 접근제한자를 private만 쓰지 못한다면 부모클래스의 setter를 사용해서 필드값을 변경한다.
    //		setCode(code);
    //		setName(name);
    //		setBrand(brand);
    //		setPrice(price);
    //		setCreatedAt(createdAt);
    		
    		//혹은 맨 위의 기본생성자 호출 super();를 없애고 아래 매개인자를 전달해주는 생성자를 호출하면 된다!굿
    		super(code,name, brand, price, createdAt);
    		
    		
    		this.os = os;
    		this.ram = ram;
    		this.cpu = cpu;
    		this.storage = storage;
    	}
    
    
    
    	public String getOs() {
    		return os;
    	}
    
    	public void setOs(String os) {
    		this.os = os;
    	}
    
    	public int getRam() {
    		return ram;
    	}
    
    	public void setRam(int ram) {
    		this.ram = ram;
    	}
    
    	public String getCpu() {
    		return cpu;
    	}
    
    	public void setCpu(String cpu) {
    		this.cpu = cpu;
    	}
    
    	public int getStorage() {
    		return storage;
    	}
    
    	public void setStorage(int storage) {
    		this.storage = storage;
    	}
    	
    	
    	@Override
    	public void printProductInfo()
    	{
    		//super:부모타입의 멤버에 접근하기위한 숨은참조
    		//만약 @Override 하지 않으면 this=super
    		super.printProductInfo();//# 멤버호출
    		//printProductInfo();//this.printProductInfo로 고치면 자기자신을 호출=무한루프에러
    		//. 스태틱호출
    		//# 멤버호출
    		System.out.println("os:"+os+"/"
    						+  "ram:"+ram+"/"
    						+  "cpu:"+cpu+"/"
    						+  "storage"+storage);
    	}
    	@Override
    	public String toString() {
    		//super.toString에서 super빼면 재귀호출임 주의
    		return "Desktop ["+ super.toString()+"os=" + os + ", ram=" + ram + ", cpu=" + cpu + ", storage=" + storage + ", toString()="
    				 + "]";
    	}
    
    	
    	
    }
    package sh.java.inheritance.product;
    
    import java.time.LocalDate;
    
    public class Tv extends Product
    {
    	private String resolution; //FHD..UHD
    	private int size; //사이즈 80인치이런거
    	
    	public Tv()
    	{
    		super();
    	}
    	public Tv(long code, String name, String brand, int price, LocalDate createdAt, String resolution, int size) {
    		//super(); //이거 주석처리 안하면 Constructor call must be the first statement in a constructor
    		super(code,name, brand, price, createdAt);
    		
    		this.resolution = resolution;
    		this.size = size;
    	}
    
    
    	public String getResolution() {
    		return resolution;
    	}
    
    	public void setResolution(String resolution) {
    		this.resolution = resolution;
    	}
    
    	public int getSize() {
    		return size;
    	}
    
    	public void setSize(int size) {
    		this.size = size;
    	}
    	
    	@Override
    	public void printProductInfo()
    	{
    		super.printProductInfo();
    		System.out.println( "resolution:"+resolution+"/"
    						+  "size:"+size);
    	}
    	
    }

     

    package sh.java.inheritance.product;
    
    import java.time.LocalDate;
    
    public class SmartPhone extends Product
    {
    	private String os;
    	private String carrier;//통신사
    	
    	public SmartPhone() 
    	{
    		super();
    	}
    	public SmartPhone(long code, String name, String brand, int price, LocalDate createdAt, String os, String carrier) {
    		super(code,name, brand, price, createdAt);
    		this.os = os;
    		this.carrier = carrier;
    	}
    	//물려받은 code~createdAt까지의 get/set지움
    	public String getOs() {
    		return os;
    	}
    
    	public void setOs(String os) {
    		this.os = os;
    	}
    
    	public String getCarrier() {
    		return carrier;
    	}
    
    	public void setCarrier(String carrier) {
    		this.carrier = carrier;
    	}
    	
    	@Override
    	public void printProductInfo()
    	{
    		super.printProductInfo();
    		System.out.println( "os:"+os+"/"
    						+  "carrier:"+carrier);
    	}
    	
    }

     

     

     


    2.메소드 오버라이드(override)

    1.부모메소드와 시그니처 동일

    2.접근제한자를 더 개방하는 쪽으로 변경

    -private :애초에 오버라이드 안됨

    -default : 잘 안씀

    -protected에서 public으로 변경 <주로 이 방법

    3.예외 던지기 구문을 축소 (일부를 제거한다.)

    4.공변반환 타입 허용

    리턴타입을 자식타입으로 변환 가능

     

      수정 전 수정 후
    접근제한자 protected public
    리턴타입 Object Car
    예외처리 CloneNotSupportedException 제거

     

    @Override
    	//protected Object clone() throws CloneNotSupportedException {
    	public Car clone(){
    		//복사생성자 이용
    		
    		//return new Car(this.brand,this.model,this.color); //필드값이 동일한 객체 생성
    		return new Car(this); //복사 생성자 /주소값만
    		//this:자기자신
    	}

     

    예제 CarMain - car

    더보기
    package sh.java.inheritance.car;
    
    public class CarMain 
    {
    	public static void main(String[] args)
    	{
    		Car sonata = new Car("현대","소나타","WHITE");
    		
    		//toString
    		System.out.println(sonata.toString());
    		
    		//equals / hashcode
    		//equals 비교 결과가 true인 경우, hashCode값이 동일해야한다는 암묵적 룰이 있음.
    		//그래서 보통 둘을 묶어서 오버라이드함.
    		Car sonata2 = new Car("현대","소나타","WHITE");
    		System.out.println(sonata2);
    		 
    		//false , 메모리상의 주소값이 다르다. new Car할때마다 다른 메모리
    		System.out.println(sonata == sonata2);
    		
    		
    		//주소값 말고 객체 내용 비교 : equals
    		//Object#equals는 ==(동등비교연산자)를 통한 주소값 비교
    		System.out.println(sonata.equals(sonata2));
    		//return (this == obj); this:sonata, obj:sonata2
    		//현재는 sonata와 sonata2의 주소값을 비교하는..그래서 false
    		//그럼 주소값 말고 값이 같으면 동일하다고 결론을 내리자는게 Car 클래스의 equals.(override)
    		
    		System.out.println(sonata.hashCode());
    		System.out.println(sonata2.hashCode());
    		
    		//clone
    		Car granduer = new Car("현대","그랜져","BLACK");
    //		Car granduer2 = (Car)granduer.clone(); 
    		Car granduer2 = granduer.clone(); //clone메소드의 리턴타입을 Object에서 Car로
    		
    		System.out.println(granduer);
    		System.out.println(granduer2);
    		
    		System.out.println(granduer == granduer2); //주소값 비교 false
    		System.out.println(granduer.equals(granduer2)); //내용비교 true
    		
    		
    	}
    }
    package sh.java.inheritance.car;
    
    import java.util.Objects;
    
    public class Car 
    {
    	private String brand;
    	private String model;
    	private String color;
    	
    	
    	public Car() {
    		super();
    	
    	}
    
    	public Car(String brand, String model, String color) {
    		super();
    		this.brand = brand;
    		this.model = model;
    		this.color = color;
    	}
    
    	/**
    	 * 복사 생성자
    	 * @param other
    	 * 기존에 존재하던 필드값들을 읽어와서 현재의 brand에 대입하겠다.뜻
    	 */
    	public Car(Car other) 
    	{
    		this.brand = other.brand;
    		this.model = other.brand;
    		this.color = other.color;
    	}
    
    	public String getBrand() {
    		return brand;
    	}
    
    
    	public void setBrand(String brand) {
    		this.brand = brand;
    	}
    
    
    	public String getModel() {
    		return model;
    	}
    
    
    	public void setModel(String model) {
    		this.model = model;
    	}
    
    
    	public String getColor() {
    		return color;
    	}
    
    
    	public void setColor(String color) {
    		this.color = color;
    	}
    
    	
    	//필드 정보 확인용으로 많이 사용함.
    	//원래는 해시코드만 읽어올수있지만 Override하면 필드정보를 읽어올수있다
    	@Override
    	public String toString() {
    		return "Car [brand=" + brand + ", model=" + model + ", color=" + color + "]";
    	}
    	
    	/**
    	 * 필드값 brand, model, color 기준으로 equals override
    	 * 
    	 */
    	@Override //물려받은 메소드를 재정의
    	public boolean equals(Object obj)
    	{
    		if(obj == null)
    			return false;
    		if(this.getClass() != obj.getClass())//클래스비교
    			return false;
    		Car other  = (Car)obj; //Object타입을 Car타입 형변환
    		if(!brand.equals(other.brand))
    			return false;
    		if(!model.equals(other.model))
    			return false;
    		if(!color.equals(other.color))
    			return false;
    		return true;
    	}
    	
    	//hashCode작업
    	/**
    	 * equals 비교에 사용한 필드기준으로 해시코드를 재생성한다.override
    	 */
    	@Override
    	public int hashCode() {
    		// TODO Auto-generated method stub
    		//괄호안에 필드값을 넣으면 그 필드값 기준으로 해시코드를 만들어준다.
    		return Objects.hash(brand, model, color);
    	}
    	//equals랑 hashcode로 비교작업할때 비교할 필드갯수가 같아야함.
    	//만약 아래 hashCode에서 brand color만 비교할거면 위에 equals에서도 2개만 비교해야함
    	
    	
    	
    	/**
    	 * 오버라이드 규칙
    	 * 1.부모메소드 시그니쳐 동일
    	 * 2.접근제한자를 더 개방하는쪽으로 변경
    	 * private:애초에 오버라이드 안됨
    	 * default:잘 안씀
    	 * protected=>public <<이걸씀
    	 * 3.예외던지기 구문을 축소(일부 제거
    	 * =더 호출하기 편한 방향으로 편집
    	 * 4.공변반환타입 허용 - 리턴타입을 자식타입으로 변환가능
    	 */	
    	@Override
    	//protected Object clone() throws CloneNotSupportedException {
    	public Car clone(){
    		//복사생성자 이용
    		
    		//return new Car(this.brand,this.model,this.color); //필드값이 동일한 객체 생성
    		return new Car(this); //복사 생성자 /주소값만
    		//this:자기자신
    	}
    }

     

    '공부' 카테고리의 다른 글

    1006(16일차)  (0) 2023.10.06
    1005(15일차)  (0) 2023.10.05
    1004 14일차  (2) 2023.10.04
    0927 13일차  (0) 2023.09.27
    0925 11일차  (0) 2023.09.25
    댓글