상속 및 합성의 기본 개념
상속 : 기존 클래스를 기반으로 새로운 클래스를 구성 할 수 있습니다. 기존 클래스를 상속하면 이러한 클래스의 방법과 도메인을 재사용 할 수 있습니다. 이를 바탕으로 클래스의 기능을 확장하기 위해 새로운 방법과 도메인을 추가 할 수 있습니다.
합성 : 새 클래스에서 원래 객체를 만드는 것을 합성이라고합니다. 이렇게하면 양식을 변경하지 않고 기존 코드를 재사용 할 수 있습니다.
1. 상속 된 구문
키워드 확장은 새 클래스가 기존 클래스에서 파생되었음을 나타냅니다. 기존 클래스를 부모 클래스 또는 기본 클래스라고하며 새 클래스를 서브 클래스 또는 파생 클래스라고합니다. 예를 들어:
클래스 학생 확장 사람 {}학급 학생은 사람을 물려받습니다. 개인 수업은 부모 수업 또는 기본 클래스라고하며 학생 수업을 서브 클래스 또는 파생 클래스라고합니다.
2. 합성의 합성
합성은 비교적 간단하며, 이는 클래스에서 기존 클래스를 만드는 것입니다.
클래스 학생 {개 개;}상향 스타일
1. 기본 개념
상속의 역할은 코드 재사용에 있습니다. 상속은 부모 클래스의 모든 방법이 서브 클래스로도 사용할 수 있음을 의미하기 때문에 부모 클래스로 전송 된 메시지도 파생어 클래스로 보낼 수도 있습니다. 개인 수업에 Eat Method가 있으면 학생 수업 에이 방법이있을 것입니다. 이는 학생 대상이 또한 사람의 유형임을 의미합니다.
클래스 사람 {public void eat () {system.out.println ( "eat");} 정적 무효 쇼 (person p) {p.eat ();}} public class 학생 확장 사람 {public static void main (string [] args) {학생 s = new Student (); person.show (s); // ①}}}【작동 결과】 :
먹다
직접 정의 된 쇼 메소드는 사람 핸들을받는 데 사용되지만 ① ①에서는 학생 대상에 대한 참조를받습니다. 학생 대상이 또한 개인 대상이기 때문입니다. 쇼 메소드에서 통과 된 핸들 (객체 참조)은 사람 객체와 사람이 파생 된 클래스 객체 일 수 있습니다. 학생 핸들을 개인 핸들로 변환하는 이러한 행동은 상향 패턴이됩니다.
2. 왜 모양을 추적해야합니까?
Eat를 호출 할 때 호출하는 객체 유형을 의도적으로 무시하고 싶습니까? 쇼 메소드를 단순히 학생을 다루는 것이 더 직관적이고 이해하기 쉬운 것처럼 보이지만, 개인 수업에서 파생 된 모든 새로운 수업이 자체 쇼 메소드를 구현하게됩니다.
클래스 값 {private int count = 1; private value (int count) {this.count = count;} public static final val v1 = new value (1), v2 = new vale (2), v3 = new value (3);} class person {value v) {system.out.println ( "person.eat ()"; {system.out.println ( "교사 .Eat ()");}} 클래스 학생 확장 사람 {public void eat (value v) {system.out.println ( "winder.eat ()";}} public class upcastingdemo {public static void show (student s) {s.eat (value.v1); {t.eat (value.v1);} public static void show (person p) {p.eat (value.v1);} public static void main (string [] args) {Student S = new Student (); 교사 T = New Teacher (); New Person (); show (s); show (t); show (p);}}이 접근법에서 명백한 결함은 각 개인 클래스의 파생 등급과 밀접한 관련된 방법을 정의해야한다는 것입니다. 반면에, 메소드의 과부하를 잊어 버리면 오류를보고하지 않습니다. 위의 예에서 세 가지 쇼 방법은 하나로 병합 될 수 있습니다.
public static void show (person p) {p.eat (value.v1);} 동적 바인딩
쇼를 수행 할 때 출력 결과는 Student.eat ()입니다. 이것은 실제로 원하는 결과이지만, 우리가 원하는 형태로 실행되지 않는 것 같습니다. 쇼 메소드를 다시 살펴 보겠습니다.
public static void show (person p) {p.eat (value.v1);}그것은 사람의 손잡이를받습니다. 쇼를 수행 할 때, 사람이 교사 대상 대신 학생 대상을 가리키는 것을 어떻게 알 수 있습니까? 컴파일러는이를 알 수있는 방법이 없으며, 다음에 바인딩 문제를 포함합니다.
1. 방법 호출 바인딩
방법과 동일한 메소드 본체를 연결하는 것을 바인딩이라고합니다. 실행하기 전에 바인딩이 수행되면 "조기 바인딩"이라고합니다. 위의 예에서는 한 사람 만 처리 할 때 컴파일러는 어떤 메소드를 호출 해야하는지 모릅니다. Java는 작동 중 객체의 유형을 결정한 다음 해당 방법을 호출 할 수있는 메소드 호출 메커니즘을 구현합니다. 물체의 유형에 기초한이 결합을 작동 중에 동적 결합이라고합니다. 메소드가 최종 선언되지 않으면 Java의 모든 방법은 동적으로 바인딩됩니다.
위쪽 모양의 상속 관계를 나타내려면 그림을 사용하십시오.
코드에서는 다음과 같이 요약됩니다.
Shapes=newShape();
상속 관계에 따르면, 원은 모양에 속하기 때문에 생성 된 원 객체 핸들을 모양에 할당하는 것이 합법적입니다.
기본 클래스 방법 중 하나를 호출하는 경우
Shapes=newShape();
현재 Circle.Draw ()가 호출되는데, 이는 동적 바인딩 때문입니다.
클래스 사람 {void eat () {} void speak () {}} 클래스 소년은 사람을 확장합니다. {system.out.println ( "girl.eat ()");}} 공개 계급 사람 {public static person randperson () {switch ((int) (int) (int) {int) (int) {default : case 0 : case 0 : case 0 : case 0 : case ();); Case 1 : return new girl ();}} public static void (string [] args) {p = new person [4]; i <p.length; i ++) {p [i] = randperson (); // (int i = 0; i <p.length; i ++) {p [i] .eat ();}}}에 대한 (int i = 0; i <p.length;사람으로부터 파생 된 모든 수업의 경우 사람은 일반적인 인터페이스를 설정하고 모든 파생 수업에는 먹고 말하는 두 가지 행동이 있습니다. 파생 클래스는 이러한 정의를 무시하고 두 행동을 모두 재정의합니다. 메인 클래스에서 Randperson은 사람 객체의 핸들을 무작위로 선택합니다. ** 항소 스타일은 반환 문에서 발생합니다. ** return 문은 소년이나 소녀 손잡이를 취하여 사람 유형으로 반환합니다. 이 시점에서 나는 그것이 어떤 유형인지 모르겠다. 나는 그것이 사람 객체 손잡이라는 것을 알고있다. 주요 방법에서는 Randperson 방법을 호출하여 배열에 사람 객체를 채우지 만 특정 상황을 모릅니다. 배열의 각 요소의 EAT 방법이 호출되면 동적 바인딩의 기능은 객체의 재정의 된 메소드를 실행하는 것입니다.
그러나 동적 바인딩은 전제 조건이며, 바인딩 방법은 기본 클래스에 존재해야하며, 그렇지 않으면 컴파일 및 통과되지 않습니다.
클래스 사람 {void eat () {system.out.println ( "person.eat ()");}} 클래스 보이는 사람을 연장합니다 {void eat () {system.out.println ( "boy.eat ()";} void speak () {system.out.println ( "boy.speak ()"; {person p = new Boy (); p.eat (); p.speak (); // method speak ()는 유형의 사람에 대해 정의되지 않습니다}}하위 클래스에서 재정의 메소드가 정의되지 않으면 부모 클래스의 메소드가 다음과 같이 호출됩니다.
클래스 사람 {void eat () {system.out.println ( "person.eat ()");}} 클래스 소년은 Person {} 공개 클래스 사람 {public static void main (String [] args) {person p = new Boy (); p.eat ();}}【작동 결과】 :
person.eat ()
2. 정적 방법의 바인딩
위의 방법에 정적 키워드를 추가하고 정적 메소드로 전환하십시오.
클래스 사람 {static void eat () {system.out.println ( "person.eat ()");} 정적 void speak () {systation.out.println ( "person.speak ()");}} 클래스 소년은 static void eat () {system.out.println ( "boy.eat ()"; {system.out.println ( "boy.speak ()";}} class girl extends person {static void eat () {system.out.println ( "girl.eat ()";} 정적 무효 연설 () {system.out.println ( "girl.speak ()"; ((int) (math.random () * 2)) {default : case 0 : return new Boy (); case 1 : return new girl ();}} public static void main (string [] args) {person [] p = new Person [4]; (int i = 0; i <p.length; i ++) {i] = 0 (randperson); <p.length; i ++) {p [i] .eat ();}}} 【작동 결과】 :
person.eat ()
person.eat ()
person.eat ()
person.eat ()
관찰 결과 : 정적 메소드의 경우, 상위 클래스가 언급하는 서브 클래스 객체에 관계없이 상위 클래스의 메소드가 호출됩니다.
니모닉 포뮬러
- 정적 메소드 : 정적 메소드는 모 부모 클래스를 살펴 봅니다.
-비 정적 방법 : 비 정적 메소드는 서브 클래스를 살펴 봅니다
요약
위의 내용은이 기사의 Java 상속 개념에 대한 자세한 해석의 모든 내용이며, 모든 사람에게 도움이되기를 바랍니다. 관심있는 친구는이 사이트의 다른 관련 주제를 계속 참조 할 수 있습니다. 단점이 있으면 메시지를 남겨 두십시오. 이 사이트를 지원해 주신 친구들에게 감사드립니다!