>  기사  >  웹 프론트엔드  >  JavaScript 객체지향 상속_javascript 기술에 대한 자세한 설명

JavaScript 객체지향 상속_javascript 기술에 대한 자세한 설명

WBOY
WBOY원래의
2016-05-16 15:26:081213검색

1. 객체 상속 메커니즘
이 예에서는 UML을 사용하여 상속 메커니즘을 잘 설명합니다.
상속 메커니즘을 설명하는 가장 간단한 방법은 기하학적 모양의 전형적인 예를 사용하는 것입니다. 실제로 기하학적 모양에는 타원(원형)과 다각형(특정 개수의 변이 있음)이라는 두 가지 유형만 있습니다. 원은 초점이 하나만 있는 타원의 한 유형입니다. 삼각형, 직사각형, 오각형은 변의 개수가 다양한 모든 유형의 다각형입니다. 정사각형은 모든 변의 길이가 같은 직사각형 유형입니다. 이는 완벽한 상속 관계를 구성하며 객체지향 상속 메커니즘을 잘 설명합니다.
이 예에서 모양은 타원과 다각형의 기본 클래스입니다(일반적으로 이를 상위 클래스라고 부를 수도 있으며 모든 클래스는 이 클래스에서 상속됩니다). 타원에는 타원의 초점 수를 나타내는 초점이 있습니다. Circle은 Ellipse를 상속하므로 Circle은 Ellipse의 하위 클래스이고 Ellipse는 Circle의 슈퍼 클래스입니다. 마찬가지로 삼각형, 직사각형, 오각형은 모두 상위 클래스인 다각형의 하위 클래스입니다. 마지막으로 정사각형은 직사각형을 상속받습니다.
UML(Unified Modeling Language)이 사용되는 상속 관계를 설명하려면 다이어그램을 사용하는 것이 가장 좋습니다. UML의 주요 용도 중 하나는 상속과 같은 복잡한 개체 관계를 시각적으로 표현하는 것입니다. 다음 다이어그램은 모양과 해당 하위 클래스 간의 관계를 설명하는 UML 다이어그램입니다.

UML에서 각 상자는 클래스 이름으로 설명되는 클래스를 나타냅니다. 삼각형, 직사각형, 오각형 상단의 선분은 함께 모여 모양을 가리키며, 이는 이러한 클래스가 모양에서 상속됨을 나타냅니다. 마찬가지로 정사각형에서 직사각형을 가리키는 화살표는 둘 사이의 상속 관계를 나타냅니다.
2. ECMAScript 상속 메커니즘 구현
ECMAScript로 상속 메커니즘을 구현하려면 상속하려는 기본 클래스부터 시작할 수 있습니다. 개발자가 정의한 모든 클래스는 기본 클래스로 사용될 수 있습니다. 보안상의 이유로 네이티브 및 호스트 클래스는 기본 클래스로 사용될 수 없습니다. 이는 악의적인 공격에 사용될 수 있는 컴파일된 브라우저 수준 코드에 대한 공개 액세스를 방지합니다.
기본 클래스를 선택한 후 해당 하위 클래스를 생성할 수 있습니다. 기본 클래스를 사용할지 여부는 전적으로 귀하에게 달려 있습니다. 때로는 직접 사용할 수 없지만 하위 클래스에 공통 기능을 제공하는 데만 사용되는 기본 클래스를 만들고 싶을 수도 있습니다. 이 경우 기본 클래스는 추상 클래스로 간주됩니다. ECMAScript는 추상 클래스를 다른 언어만큼 엄격하게 정의하지는 않지만 때때로 사용이 허용되지 않는 클래스를 생성합니다. 일반적으로 우리는 이 클래스를 추상 클래스라고 부릅니다.
생성된 하위 클래스는 생성자 및 메서드 구현을 포함하여 슈퍼클래스의 모든 속성과 메서드를 상속합니다. 모든 속성과 메서드는 공개이므로 하위 클래스에서 이러한 메서드에 직접 액세스할 수 있습니다. 하위 클래스는 슈퍼클래스에 없는 새로운 속성과 메서드를 추가하거나 슈퍼클래스의 속성과 메서드를 재정의할 수도 있습니다. JS는 정통 객체 지향 언어가 아니기 때문에 일부 명사도 변경해야 합니다.
3. ECMAScript 상속 방법
ECMAScript 언어에서는 상속된 클래스(기본 클래스)를 슈퍼타입(supertype)이라고 하고, 하위 클래스(또는 파생 클래스)를 서브타입(subtype)이라고 합니다. 다른 기능과 마찬가지로 ECMAScript는 여러 가지 방법으로 상속을 구현합니다. 이는 JavaScript의 상속 메커니즘이 명시적으로 지정되지 않고 모방을 통해 구현되기 때문입니다. 이는 모든 상속 세부 사항이 인터프리터에 의해 완전히 처리되지는 않는다는 것을 의미합니다. 개발자는 자신에게 가장 적합한 상속 방법을 결정할 권리가 있습니다. 다음은 귀하를 위한 몇 가지 구체적인 상속 방법입니다.
(1) 프로토타입 체인 방식
이러한 형태의 상속은 원래 ECMAScript의 프로토타입 체인에 사용되었습니다. 이전 블로그 게시물에서는 객체를 생성하는 프로토타입 방법을 소개했습니다. 프로토타입 체인은 이 접근 방식을 확장하여 흥미로운 방식으로 상속 메커니즘을 구현합니다. 프로토타입 개체는 템플릿이며 인스턴스화할 개체는 이 템플릿을 기반으로 합니다. 요약하면 프로토타입 객체의 모든 속성과 메서드는 해당 클래스의 모든 인스턴스에 전달됩니다. 프로토타입 체인은 이 기능을 활용하여 상속 메커니즘을 구현합니다. 예를 살펴보겠습니다.

function A() {//超类型A中必须没有参数 
 this.color = "red"; 
 this.showColor = function () { 
  return this.color; 
 }; 
}; 
function B() {//子类型B 
 this.name = "John"; 
 this.showName = function () { 
  return this.name; 
 }; 
}; 
B.prototype = new A();//子类型B继承了超类型A,通过原型,形成链条 
var a = new A(); 
var b = new B(); 
document.write(a.showColor());//输出:blue 
document.write(b.showColor());//输出:red 
document.write(b.showName());//输出:John 

프로토타입 체인에서는 instanceof 연산자도 독특한 방식으로 작동합니다. B의 모든 인스턴스에 대해 instanceof는 A와 B 모두에 대해 true를 반환합니다. 이는 약한 유형의 ECMAScript 세계에서 매우 유용한 도구이지만 객체 가장을 사용할 때는 사용할 수 없습니다. 예:

var b = new B(); 
document.write(b instanceof A);//输出:true 
document.write(b instanceof B);//输出:true 

       使用原型链方式实现了继承,但是这种方式无法共享和子类型给超类型传递参数。我们可以借用构造函数方式(也就是对像冒充)的方式来解决这两个问题。
(2)对象冒充方式
      对象冒充方式的其原理如下:构造函数使用this关键字给所有属性和方法赋值(即采用对象声明的构造函数方式)。因为构造函数只是一个函数,所以可使A构造函数成为B的方法,然后调用它。B就会收到A的构造函数中定义的属性和方法。例如,用下面的方式改写上面的例子创建对象A和B:
call()方法

function A(Color) {//创建超类型A 
 this.color = Color; 
 this.showColor = function () { 
   return this.color; 
 }; 
}; 
function B(Color,Name) {//创建子类型B 
 A.call(this, Color);//对象冒充,给超类型传参 
 this.name = Name;//新添加的属性 
 this.showName = 
}; 
var a = new A("blue"); 
var b = new B("red", "John"); 
document.write(a.showColor());//输出:blue 
document.write(b.showColor());//输出:red 
document.write(b.showName());//输出:John 

apply()方法
和上面call()方法唯一的区别就是在子类型B中的代码:
A.call(this,arguments);//对象冒充,给超类型传参 
      当然,只有超类型中的参数顺序与子类型中的参数顺序完全一致时才可以传递参数对象。如果不是,就必须创建一个单独的数组,按照正确的顺序放置参数。
      使用对象冒充方式虽然解决了共享和传参的问题,但是没有原型,复用就更不可能了,所以我们组合上述的两种方式,即原型链方式和对象冒充的方式实现JS的继承。
(3)混合方式
      这种继承方式使用构造函数定义类,并非使用任何原型。对象冒充的主要问题是必须使用构造函数方式,这不是最好的选择。不过如果使用原型链,就无法使用带参数的构造函数了。开发者如何选择呢?答案很简单,两者都用。由于这种混合方式使用了原型链,所以instanceof运算符仍能正确运行。
       在上一篇文章,创建对象的最好方式是用构造函数定义属性,用原型定义方法。这种方式同样适用于继承机制,用对象冒充继承构造函数的属性,用原型链继承prototype对象的方法。用这两种方式重写前面的例子,代码如下:

function A(Color) { 
 this.color = Color; 
}; 
A.prototype.showColor = function () { 
 return this.color; 
}; 
function B(Color, Name) { 
 A.call(this, Color);//对象冒充 
 this.name = Name; 
}; 
B.prototype = new A();//使用原型链继承 
B.prototype.showName = function () { 
 return this.name; 
}; 
var a = new A("blue"); 
var b = new B("red", "John"); 
document.write(a.showColor());//输出:blue 
document.write(b.showColor());//输出:red 
document.write(b.showName());//输出:John 

       继承的方式和创建对象的方式有一定的联系,推荐使用的继承方式还时原型链和对象冒充的混合方式。使用这种混合方式可以避免一些不必要的问题。
       看这篇文章的时候,必须看一下前面的创建对象的方式:详解JavaScript基于面向对象之创建对象(1)详解JavaScript基于面向对象之创建对象(2)

以上就是本文的全部内容,希望对大家的学习有所帮助。

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.