문법/기본 문법

상속, 다형성

코딩 화이팅 2023. 1. 20. 15:52
package test06_many;

public class person extends Object{
	String name;
	int age;
	
	//파라미터가 있는 생성자
	public person(String name, int age) {
		this.name=name;
		this.age=age;
	}
	
	public void eat() {
		System.out.println("음식을 먹는다.");
	}

	@Override
	public String toString() {
		return "person [name=" + name + ", age=" + age + "]";
	}
	
	
}
================================================================================
package test06_many;

//클래스의 상속은 extends 키워드를 사용
public class student extends person {

	String major;
	
	//파라미터가 있는 생성자를 만들어줘야한다.
	public student(String name, int age, String major) {
		super(name, age);//부모클래스의 생성자를 호출
		this.major=major;
	}
	
	
	public void study() {
		System.out.println("공부를 한다.");
	}
	
	//어노테이션을 붙이는 것을 권장
		//붙이지 않아도 오버라이드는 됨
		@Override//어노테이션
	public void eat() {
		System.out.println("지식을 먹는다.");
	}
	//마우스 우클릭->Source->generate toString()
	
		
		
		@Override
	public String toString() {
		return "student [name="+super.name+", age="+super.age+", major="+this.major+"]";
	}

//마우스 우클릭->Source->
		@Override
		public boolean equals(Object obj) {
			// TODO Auto-generated method stub
			return name.equals(((student)obj).name);
		}
		
		
		@Override
		public int hashCode() {
			return name.hashCode();
		}
}
========================================================================================
package test06_many;


public class test01 {
	public static void main(String[] args) {
		
		person[] persons=new person[3];
		persons[0]=new  person("강현", 26);
		persons[1]=new  person("강현일", 27);
		persons[2]=new  student("강현이", 28,"java");
		//부모 클래스로 참조할 수 있지만,
		//부모 클래스의 관점에서 보기 때문에
		//접근 가능한 범위가 달라진다.	
		
		for(person p:persons) {
			System.out.println(p.toString());
		}
		
		person st=new student("강현", 26, "java");
		
	}
	
}

상속

  • 누가? : 클래스(설계도)
  • 무엇을? : 멤버변수 / 메서드
  • 왜? : 기존의 설계도를 재사용하기 위해
  • 어떤 클래스의 특성을 그대로 갖는 새로운 클래스를 정의하는 것
  • 1. 확장성 재사용성 : 부모의 생성자와 초기화 블록은 상속X
  • 2. 클래스 선언시 extends  키워드를 명시 : 자바는 다중 상속 허용X, 단일 상속 지원->extends 뒤에 하나의 클래스만 나올 수 있다.
  • 3. 자식 클래스는 부모 클래스와 멤버변수, 메서드를 자신의 것처럼 사용할 수 있다.(단 접근 제한자에 따라 사용 여부가 달라진다.->private(상속 불가능) / default(같은 패키지 내에서 상속 가능) / protected(다른 패키지에 있더라도 상속 관계면 상속 가능) / public(누구나 가능)
  • 4. Object 클래스는 모든 클래스의 조상 클래스
package test01_no_inheritance;

public class person {
	String name;
	int age;
	
	public void eat() {
		System.out.println("음식을 먹는다.");
	}
}
===============================================================================
package test01_no_inheritance;

public class student {
	String name;
	int age;
	String major;
	
	public void eat() {
		System.out.println("음식을 먹는다.");
	}
	
	public void study() {
		System.out.println("공부를 한다.");
	}
}
===============================================================================
package test01_no_inheritance;

public class test01 {
	public static void main(String[] args) {
		student st=new student();
//		st.
	}
}
package test01.inheritance;

public class person {
	String name;
	int age;
	
	public void eat() {
		System.out.println("음식을 먹는다.");
	}
}
======================================================================
package test01.inheritance;

//클래스의 상속은 extends 키워드를 사용
public class student extends person {

	String major;
	
	public void study() {
		System.out.println("공부를 한다.");
	}
}
//상속 전과 달리 상속 후 중복되었던 나이와 이름 멤버변수를 없애고 먹는 메소드를 생략할 수 있었다.
======================================================================
package test01.inheritance;

public class test01 {
	public static void main(String[] args) {
		student st=new student();
//		st.
	}
}

super 클래스

  • 조상 클래스의 생성자 호출
  • super.멤버변수
  • super.메서드()
package test02_super;

public class person {
	String name;
	int age;
	
	//파라미터가 있는 생성자
	public person(String name, int age) {
		this.name=name;
		this.age=age;
	}
	
	public void eat() {
		System.out.println("음식을 먹는다.");
	}
}
=============================================================================
package test02_super;

//클래스의 상속은 extends 키워드를 사용
public class student extends person {

	String major;
	
	//파라미터가 있는 생성자를 만들어줘야한다.
	public student(String name, int age, String major) {
		super(name, age);//부모클래스의 생성자를 호출
		this.major=major;
	}
	
	
	public void study() {
		System.out.println("공부를 한다.");
	}
}
=============================================================================
package test02_super;

public class test01 {
	public static void main(String[] args) {
		student st=new student("강현", 26, "java");
		st.eat();//override하지 않았기 때문에 부모의 메서드를 그대로 사용
//		st.
	}
}

오버라이딩

package test03_overriding;

public class person {
	String name;
	int age;
	
	//파라미터가 있는 생성자
	public person(String name, int age) {
		this.name=name;
		this.age=age;
	}
	
	public void eat() {
		System.out.println("음식을 먹는다.");
	}
}
=================================================================================
package test03_overriding;

//클래스의 상속은 extends 키워드를 사용
public class student extends person {

	String major;
	
	//파라미터가 있는 생성자를 만들어줘야한다.
	public student(String name, int age, String major) {
		super(name, age);//부모클래스의 생성자를 호출
		this.major=major;
	}
	
	
	public void study() {
		System.out.println("공부를 한다.");
	}
	
	//어노테이션을 붙이는 것을 권장
	//붙이지 않아도 오버라이드는 됨
	@Override//어노테이션
	public void eat() {
		System.out.println("지식을 먹는다.");
	}
}
=================================================================================
package test03_overriding;

public class test01 {
	public static void main(String[] args) {
		student st=new student("강현", 26, "java");
		st.eat();//필요하다면 자식 클래스에서 부모의 메서드를 재정의할 수 있다.
	}
}
//지식을 먹는다 출력
  • 상위 클래스에 선언된 메서드를 자식 클래스에서 재정의 하는 것
  • 메서드의 이름, 반환형, 매개변수(타입, 개수, 순서) 동일해야 한다.
  • 하위 클래스의 접근제어자 범위가 상위 클래스보다 크거나 같아야 한다.
  • 조상보다 더 큰 예외를 던질 수 없다.
  • 메서드 오버로딩과 혼동하지 말 것

Object  클래스

  • 가장 최상위 클래스로 모든 클래스의 조상
  • object의 멤버는 모든 클래스의 멤버

hashcode

  • 객체의 해시 코드 : 시스템에서 객체를 구별하기 위해 사용되는 정수값
  • 2개의 객체가 동일-> 같은 해시값 / 2개가 같은 해시값->두 객체가 동일할 수도 있고, 아닐수도 있다.
  • HashSet, HashMap 등에서 객체의 동일성을 확인하기 위해 사용
  • equals 메서드를 재정의할 때는 반드시 hashcode도 재정의할 것

final

다형성

  • 상속관계에 있을 때 조상 클래스의 타입으로 자식 클래스 객체를 참조할 수 있다.
package test04_binding;

public class person {
	String name;
	int age;
	
	//파라미터가 있는 생성자
	public person(String name, int age) {
		this.name=name;
		this.age=age;
	}
	
	public void eat() {
		System.out.println("음식을 먹는다.");
	}
}
=============================================================================
package test04_binding;

//클래스의 상속은 extends 키워드를 사용
public class student extends person {

	String major;
	
	//파라미터가 있는 생성자를 만들어줘야한다.
	public student(String name, int age, String major) {
		super(name, age);//부모클래스의 생성자를 호출
		this.major=major;
	}
	
	
	public void study() {
		System.out.println("공부를 한다.");
	}
	
	//어노테이션을 붙이는 것을 권장
		//붙이지 않아도 오버라이드는 됨
		@Override//어노테이션
	public void eat() {
		System.out.println("지식을 먹는다.");
	}
}
============================================================================
package test04_binding;

public class test01 {
	public static void main(String[] args) {
		student st=new student("강현", 26, "java");
		st.eat();//필요하다면 자식 클래스에서 부모의 메서드를 재정의할 수 있다.
		
		person st2=new student("강현일", 27, "java");
		st2.eat();
	}
	
}
package test05_object;

public class person extends Object{
	String name;
	int age;
	
	//파라미터가 있는 생성자
	public person(String name, int age) {
		this.name=name;
		this.age=age;
	}
	
	public void eat() {
		System.out.println("음식을 먹는다.");
	}

	@Override
	public String toString() {
		return "person [name=" + name + ", age=" + age + "]";
	}
	
	
}
=============================================================================
package test05_object;

//클래스의 상속은 extends 키워드를 사용
public class student extends person {

	String major;
	
	//파라미터가 있는 생성자를 만들어줘야한다.
	public student(String name, int age, String major) {
		super(name, age);//부모클래스의 생성자를 호출
		this.major=major;
	}
	
	
	public void study() {
		System.out.println("공부를 한다.");
	}
	
	//어노테이션을 붙이는 것을 권장
		//붙이지 않아도 오버라이드는 됨
		@Override//어노테이션
	public void eat() {
		System.out.println("지식을 먹는다.");
	}
	//마우스 우클릭->Source->generate toString()
	
		
		
		@Override
	public String toString() {
		return "student [name="+super.name+", age="+super.age+", major="+this.major+"]";
	}

//마우스 우클릭->Source->
		@Override
		public boolean equals(Object obj) {
			// TODO Auto-generated method stub
			return name.equals(((student)obj).name);
		}
		
		
		@Override
		public int hashCode() {
			return name.hashCode();
		}
}
===================================================================================
package test05_object;

import java.util.HashSet;
import java.util.Set;

public class test01 {
	public static void main(String[] args) {
		student st=new student("강현", 26, "java");
		st.eat();//필요하다면 자식 클래스에서 부모의 메서드를 재정의할 수 있다.
		st.toString();//object 
		System.out.println(st.toString());//object의 메서드를 상속받고 있다.
		//재정의한대로 나온다.
		
		student st2=new student("강현", 26, "java");
		System.out.println(st==st2);//false 출력->다른 객체, 주소값이 다르기 때문에
		System.out.println(st.equals(st2));//false출력-> 원래는 주소값을 비교하고 있으니까 달랐지만, 이름만 같아도 같다고 override했으므로 같다고 출력
		
		Object o=new Object();
		o.equals(st);
		
		//이름만 같으면 같은 사람이다 라고 가정
		
		//집합
		Set<student> set=new HashSet<>();
		set.add(st);
		set.add(st2);
		
		System.out.println(set.size());//집합에 들어있는 원소의 개수
		//set에서는 동일성을 판단하기 위해서 equals(), hashcode();
		//hashcode를 재정의하고 나서야 두 객체가 같은 것으로 봄.
		
		
	}
	
}
package test07;

public class person extends Object{
	String name;
	int age;
	
	//파라미터가 있는 생성자
	public person(String name, int age) {
		this.name=name;
		this.age=age;
	}
	
	public void eat() {
		System.out.println("음식을 먹는다.");
	}

	@Override
	public String toString() {
		return "person [name=" + name + ", age=" + age + "]";
	}
	
	
}
==================================================================================
package test07;

//클래스의 상속은 extends 키워드를 사용
public class student extends person {

	String major;
	
	//파라미터가 있는 생성자를 만들어줘야한다.
	public student(String name, int age, String major) {
		super(name, age);//부모클래스의 생성자를 호출
		this.major=major;
	}
	
	
	public void study() {
		System.out.println("공부를 한다.");
	}
	
	//어노테이션을 붙이는 것을 권장
		//붙이지 않아도 오버라이드는 됨
		@Override//어노테이션
	public void eat() {
		System.out.println("지식을 먹는다.");
	}
	//마우스 우클릭->Source->generate toString()
	
		
		
		@Override
	public String toString() {
		return "student [name="+super.name+", age="+super.age+", major="+this.major+"]";
	}

//마우스 우클릭->Source->
		@Override
		public boolean equals(Object obj) {
			// TODO Auto-generated method stub
			return name.equals(((student)obj).name);
		}
		
		
		@Override
		public int hashCode() {
			return name.hashCode();
		}
}
========================================================================================
package test07;


public class test01 {
	public static void main(String[] args) {
		
		student st=new student("강현", 26, "java");
		person p=st;
		
		student st3=(student)p;
		st3.study();
		
		person p2=new person("강현일", 27);
		
		student st2=(student) p2;
		st2.study();
	}
	
}
package test08;

public class subclass extends superClass{
	String x="sub";
	
	@Override
	public void method() {
		System.out.println("sub class method");
	}
}
=============================================================================
package test08;

public class superClass {
	String x="super";
	
	public void method() {
		System.out.println("super class method");
	}
}
================================================================================
package test08;

public class test {
	public static void main(String[] args) {
		subclass child=new subclass();
		System.out.println(child.x);
		child.method();
		
		superClass parent=child;
		System.out.println(parent.x);
		parent.method();
		
	}
}