먼저 상위 클래스의 인스턴스화 객체를 만든 다음 해당 객체를 하위 클래스의 프로토타입 속성에 할당합니다.
이런 방식으로 상위 클래스의 모든 공개 인스턴스 멤버는 하위 클래스에 상속됩니다. 그리고 instanceof 연산자로 판단할 때 하위 클래스의 인스턴스화된 객체는 하위 클래스와 상위 클래스 모두에 속합니다.
그런 다음 서브클래스 자체를 해당 프로토타입의 생성자 속성에 할당합니다. (참고: 여기에 값을 할당할 때 ()가 없습니다!)
이 단계는 하위 클래스의 인스턴스화된 객체의 생성자 속성을 볼 때 상위 클래스가 아닌 하위 클래스의 정의가 표시되는지 확인하기 위한 것입니다. . 정의.
다음으로 o.method1() 호출 결과를 통해 서브클래스가 상속한 퍼블릭 인스턴스 메서드 중 프라이빗 인스턴스 필드나 프라이빗 인스턴스 메서드를 호출하면 Private 인스턴스 멤버가 호출되는 것을 볼 수 있습니다. 상위 클래스에 속합니다.
마찬가지로 o.method2()를 호출한 결과를 통해 서브클래스에 정의된 인스턴스 메소드가 프라이빗 인스턴스 필드나 프라이빗 인스턴스 메소드를 호출하면 호출된 프라이빗 인스턴스 멤버가 다음에 속해 있음을 알 수 있습니다. 하위 카테고리.
o.method()를 호출한 결과를 통해 상위 클래스의 프로토타입에 정의된 메소드가 하위 클래스에 상속되는 것을 알 수 있습니다.
o.method3() 호출 결과를 통해 하위 클래스에 정의된 인스턴스 메서드가 상위 클래스에 정의된 프라이빗 인스턴스 멤버에 접근할 수 없음을 알 수 있습니다.
마지막으로 subClass.staticMethod() 호출 결과를 통해 정적 멤버가 상속되지 않음을 알 수 있습니다.
2.4 상속 메서드 호출
상속 호출의 본질은 하위 클래스의 생성자에서 부모 클래스의 생성자 메서드가 하위 클래스의 실행 컨텍스트에서 실행되고, 상속 메서드의 모든 생성자 메서드가 실행된다는 것입니다. 상위 클래스는 하위 클래스의 실행 컨텍스트에서 실행됩니다. 이 메서드를 통해 작동되는 콘텐츠는 실제로 작업 하위 클래스의 인스턴스화된 개체에 대한 콘텐츠입니다. 따라서 이 접근 방식은 중복 코드 작성을 줄이기 위한 것일 뿐입니다.
function parentClass() {
/ / private field
var x = "나는 parentClass 필드입니다!"
// private method
function method1() {
alert(x)>alert("I' m은 parentClass 메소드입니다!");
}
// 공개 필드
this.x = "나는 parentClass 객체 필드입니다!";
// 공개 메소드
this.method1 = function( ) {
alert(x);
alert(this.x);
method1()
}
}
parentClass.prototype.method() {
alert("나는 parentClass 프로토타입 메서드입니다!");
}
parentClass.staticMethod = function () {
alert("나는 parentClass 정적 메서드입니다! ");
}
function subClass() {
// 상속
parentClass.call(this);
// 비공개 필드
var x = "나는 하위 클래스 필드입니다!";
// 비공개 메서드
function method2() {
alert(x)
alert("나는 하위 클래스 메서드입니다!"); >}
// public field
this.x = "나는 subClass 객체 필드입니다!"
// public method
this.method2 = function() {
alert( x) ;
alert(this.x);
method2();
}
this.method3 = function() {
method1();
// 테스트
var o = new subClass();
alert(o 인스턴스of parentClass); // false
alert(o 인스턴스of subClass); 🎜>
alert(o.constructor); // function subClass() {...}
o.method1(); // 나는 parentClass 필드입니다! 나는 subClass 객체 필드입니다!
// 나는 parentClass 메소드입니다!
o.method2(); 🎜> // 저는 subClass 객체입니다!
// 저는 subClass 필드입니다!
o.method() // 오류!
o.method3(); // 오류!!!
subClass.staticMethod();
위의 예는 호출 상속 방법을 사용하여 상속을 구현하는 방법을 잘 반영한 것입니다.
호출 상속 사용의 핵심은 단 한 단계입니다.
하위 클래스가 정의되면 상위 클래스의 호출 메서드를 통해 하위 클래스의 this 포인터를 전달합니다. 상위 클래스 메서드가 하위 클래스 컨텍스트에서 실행되도록 합니다.
이런 방식으로 상위 클래스 내부에서 이 메소드를 통해 정의된 상위 클래스의 모든 퍼블릭 인스턴스 멤버는 하위 클래스에 상속됩니다.
instanceof 연산자로 판단하면 하위 클래스의 인스턴스화된 객체는 상위 클래스가 아닌 하위 클래스에만 속합니다.
하위 클래스의 인스턴스화된 객체의 생성자 속성을 보면 상위 클래스의 정의가 아니라 하위 클래스의 정의가 표시됩니다.
다음으로 o.method1()과 o.method2()를 호출한 결과는 프로토타입 상속을 호출한 결과와 동일하며 설명된 문제도 동일하므로 여기서는 반복하지 않겠습니다.
o.method() 호출 결과를 통해 상위 클래스의 프로토타입에 정의된 메소드가 하위 클래스에 상속되지 않음을 알 수 있습니다.
o.method3() 호출 결과를 통해 하위 클래스에 정의된 인스턴스 메서드가 상위 클래스에 정의된 프라이빗 인스턴스 멤버에 접근할 수 없음을 알 수 있습니다.
마지막으로 subClass.staticMethod() 호출 결과를 통해 정적 멤버도 상속되지 않음을 알 수 있습니다.
마지막으로 이 예제에 반영되지 않은 또 다른 점이 있습니다. 즉, 상속 메서드를 호출하여 다중 상속이 가능하다는 것입니다. 즉, 하위 클래스는 이 메서드를 통해 상위 클래스 내부에 정의된 모든 공용 인스턴스 멤버를 여러 상위 클래스로부터 상속할 수 있습니다.
약한 유형의 언어인 JavaScript는 풍부한 다형성을 제공하며 다른 강력한 유형의 객체 지향 언어와 비교할 수 없습니다.
다형성
오버로딩과 덮어쓰기
먼저 오버로딩과 덮어쓰기의 차이점을 설명하겠습니다. Overloading의 영어 단어는 Overload이고, Coverage의 영어 단어는 Overload입니다. 나는 인터넷상의 대부분의 사람들이 재정의를 과부하로 간주한다는 것을 알았습니다. 이는 잘못된 것입니다. 오버로딩과 오버라이딩에는 차이가 있습니다.
오버로딩이란 동일한 이름을 가진 함수(여기에 함수가 포함되어 있음) 또는 메서드가 여러 구현을 가질 수 있으며 매개변수 유형 및/또는 매개변수 개수로 구별된다는 의미입니다.
덮어쓰기의 의미는 하위 클래스가 상위 클래스와 동일한 이름, 동일한 매개변수 유형 및 번호를 가진 메소드를 정의할 수 있다는 것입니다. 이러한 메소드는 정의된 후 인스턴스화 시 상위 클래스에 상속됩니다. 동일한 이름을 가진 이러한 메서드는 숨겨집니다.
오버로딩
JavaScript의 함수 매개변수는 유형이 지정되지 않으며 매개변수 수는 임의적입니다. 예를 들어 정의할 수는 있지만
function add(a, b) {
return a b; 🎜>이런 방식으로 함수를 호출할 수 있지만 매개변수 수에 제한 없이 호출할 수 있습니다. 물론 매개변수 유형도 임의적입니다. 오류 발생 여부는 이 함수에서 실행되는 내용에 따라 결정됩니다. JavaScript는 사용자가 지정하는 매개변수의 수와 유형에 따라 호출하는 함수를 결정하지 않습니다.
따라서 오버로드된 메서드를 정의하려면 강력한 형식의 언어처럼 정의할 수 없습니다. 하지만 여전히 오버로딩을 구현할 수 있습니다. 이는 함수의 인수 속성을 통해서입니다. 예:
코드 복사
for (var i = 0; i < 인수.길이; i ) {
sum = 인수[i];
return sum; }
이런 방식으로 매개변수 수에 관계없이 덧셈 함수를 오버로드할 수 있습니다.
물론, 인스턴스 오브(instanceof) 또는 생성자를 사용하여 함수의 각 매개변수 유형을 결정하여 나중에 수행할 작업을 결정하고 더 복잡한 함수 또는 메서드 오버로드를 구현할 수도 있습니다. 즉, JavaScript 오버로딩은 사용자가 직접 인수 속성을 조작하여 함수에서 구현합니다.
Override
override를 구현하는 것도 쉽습니다. 예를 들면 다음과 같습니다.
코드 복사
}
function subClass () {
this .method = function() {
alert("subClass 메소드");
}
}
subClass.prototype = new parentClass()
subClass. 프로토타입.constructor = subClass;
var o = new subClass()
o.method();
이런 방식으로 하위 클래스에 정의된 메서드가 상위 클래스에서 상속된 메서드를 재정의합니다.
이런 덮어쓰기가 좋다고 할 수도 있겠지만, Java에서는 재정의된 메서드(부모 클래스의 메서드)를 호출할 수 있는데 여기서는 어떻게 구현하나요? 또한 Java보다 매우 쉽고 유연합니다. Java에는 재정의된 메서드를 재정의하는 메서드에서 super를 사용하여 재정의된 메서드만 호출할 수 있다는 제한이 있습니다. 이를 달성할 수 있을 뿐만 아니라 하위 클래스의 모든 메서드가 상위 클래스의 재정의된 메서드를 호출하도록 만들 수도 있습니다. 아래 예를 보세요.
function parentClass( ) {
this.method = function() {
alert("parentClass 메소드");
}
}
function subClass() {
var method = this.method;
this .method = function() {
method.call(this);
alert("subClass 메서드")
}
}
subClass.prototype = new parentClass( );
subClass.prototype.constructor = subClass;
var o = new subClass()
재정의 메서드를 정의하기 전에 전용 변수를 정의한 다음 부모 클래스에 정의된 재정의할 메서드를 여기에 할당한 다음 나중에 계속 호출할 수 있으며 이 메서드는 개인용이므로 매우 간단합니다. 서브클래스의 경우 객체가 보이지 않습니다. 이는 다른 고급 언어에서 구현된 적용 범위와 일치합니다.
마지막으로, 재정의 메서드에서 이 메서드를 호출할 때 호출 메서드를 사용하여 실행 컨텍스트를 this로 변경해야 한다는 점에 유의해야 합니다(이 예에서는 필요하지 않음). 이 메소드를 직접 호출하면 실행 컨텍스트가 전역 객체가 됩니다.