>  기사  >  웹 프론트엔드  >  JavaScript의 다형성에 대한 자세한 소개

JavaScript의 다형성에 대한 자세한 소개

零下一度
零下一度원래의
2017-07-17 14:19:571635검색

안녕 친구들, 오늘은 이전 내용을 이어가겠습니다. 오늘은 JavaScript 언어의 유연성으로 인해 OOP의 마지막 표현에 대해 이야기하겠습니다. 이 문제에 대해 너무 많이 걱정할 필요는 없습니다. ECMAScript의 최신 버전이 이러한 문제를 해결해 줄 것이기 때문입니다. OOP 다형성 주제로 돌아가서 우리는 상속이 어떤 것인지 이미 명확하게 이해할 수 있습니다. 즉, 먼저 부모 클래스를 선언한 다음 부모 클래스의 속성과 메서드를 상속하기 위해 많은 하위 클래스를 작성할 수 있습니다. 상위 클래스와 동일한 기능을 달성하려면 최소한의 코드를 사용하십시오. 이것이 상속입니다. 즉시 반 친구가 질문을 제기했습니다. 저는 이전 상속을 오랫동안 읽어서 이해할 수 있지만 그 용도가 무엇인지 모르겠습니다. 왜 그렇게 많은 상속 클래스를 작성해야 합니까? 이 질문은 즉시 적중하며 매우 중요합니다. 다형성이 없으면 앞서 언급한 상속은 실제로 쓸모가 없습니다. 상속된 모든 클래스는 동일한 복사본이고 특성이 없기 때문입니다. 예를 들면 다음과 같습니다.

다형성은 말 그대로 "다중 상태"를 의미합니다. 동일한 동작(메서드)이 다른 객체에 대해 다른 상태를 갖습니다.
  다형성 기능은 OOP의 여러 곳에서 사용됩니다. 예를 들어 마우스 오른쪽 버튼 클릭, 바로가기 클릭, 바탕화면 빈 공간 클릭, 작업 표시줄 클릭 등 팝업 메뉴가 나타납니다. 다른.

메서드 재정의:

 즉, 하위 클래스는 상위 클래스와 동일한 이름의 메서드를 정의하여 상위 클래스의 메서드를 재정의하여 다른 기능을 수행합니다.

 1     function Animal(){} 2     var AnimalP = Animal.prototype; 3     AnimalP.eat = function(food){ 4         console.log('这个动物正在吃' + food); 5     }; 6  7     function Snake(){} 8     var SnakeP = extend(Snake,Animal);//extend函数请看上一节 9     /*snake没有对eat方法重写,继承的父类eat()方法*/10     function Dog(){}11     var DogP = extend(Dog,Animal);12     DogP.eat = function(food){13         /*对eat()方法重写*/14         /*上一章讲过,也可以在这里通过 Animal.eat.call(this,food)调用父方法;*/15         console.log("这只狗正在吃"+food);16     };17 18     function Cat(){}19     var CatP = extend(Cat,Animal);20     CatP.eat = function(food){21         console.log("这只猫正在吃"+food);22     };23     var snake = new Snake();24     snake.eat('老鼠');//log:这个动物正在吃老鼠25     var dog = new Dog();26     dog.eat('骨头');//log:这只狗正在吃骨头27     var cat = new Cat();28     cat.eat('鱼');//log:这只猫正在吃鱼

추상 클래스:

 위 코드에서 Snake 클래스는 자체 eat() 메서드를 구현하지 않지만 때로는 하위 클래스에 특정 메서드(추상 메서드)가 있어야 하므로 이를 표준화할 수 있습니다. 이때 추상 클래스를 사용해야 하는데 ES5와 ES6에는 추상 클래스 개념이 없으므로 시뮬레이션을 통해서만 구현할 수 있습니다. eat() 메소드는 추상 메소드로 정의됩니다:

1     AnimalP.eat = function(food){2         /*定义抽象方法(虚函数),如果子类没有重写这个方法,在执行这方法的时候就会抛出错误*/3         throw '"' + this.constructor.name + "'类没有eat()方法";4     };5     function Snake(){}6     var SnakeP = extend(Snake,Animal);7     var snake = new Snake();8     snake.eat('老鼠');//throw:"Snake'类没有eat()方法

메소드 오버로드(overload):

전달된 매개변수(유형, 매개변수 수)에 따라 메소드를 작성해야 합니다. 실행 결과도 다릅니다.

1 var run = function(speed){2         if(typeof speed == 'number'){3             console.log('跑的速度有' + speed + 'm/s');4         }else if(typeof speed == 'string'){5             console.log('跑的速度有' + speed);6         }7     }8     run(15);//log:跑的速度有15m/s9     run('20KM/h');//log:跑的速度有20KM/h
하지만 위에서 작성한 코드를 유지하는 것은 분명히 어렵습니다. 클래스에서 사용하면 매개변수 유형에 따라 다른 메소드를 실행하는 인터페이스로 run 메소드를 사용할 수 있습니다.

 1     function Dog(){} 2     var DogP = Dog.prototype; 3     DogP.run = function(speed){ 4         if(typeof speed == 'number'){ 5             this._runNumber(speed); 6         }else if(typeof speed == 'string'){ 7             this._runString(speed); 8         }else{ 9             throw '参数不匹配';10         }11     }12     DogP._runString = function(speed){13         console.log('这只狗跑的速度有' + speed);14     }15     DogP._runNumber = function(speed){16         console.log('这只狗跑的速度有' + speed + 'm/s');17     }18     var dog = new Dog();19     dog.run(15);//log:这只狗跑的速度有15m/s20     dog.run('20KM/h');//log:这只狗跑的速度有20KM/h21     dog.run([]);//throw:参数不匹配
메소드 오버로딩 시뮬레이션인데 실제로 ES5, ES6, typecipt는 구문적 메소드 오버로딩을 지원하지 않고, typecipt는 함수 오버로딩만 지원합니다.

이는 다형성을 구현하는 또 다른 방법입니다.

Demo by ES6:

 1     class Animal{ 2         eat(food){ 3             throw '"' + this.constructor.name + "'类没有eat()方法"; 4         } 5     } 6     class Snake extends Animal{} 7     class Dog extends Animal{ 8         eat(food){ 9             console.log("这只狗正在吃"+food);10         }11     }12     class Cat extends Animal{13         eat(food){14             console.log("这只猫正在吃"+food);15         }16     }17     let snake = new Snake();18     snake.eat('老鼠');//throw:"Snake'类没有eat()方法19     let dog = new Dog();20     dog.eat('骨头');//log:这只狗正在吃骨头21     let cat = new Cat();22     cat.eat('鱼');//log:这只猫正在吃鱼

Demo by TypeScript:

 1 abstract class Animal{//定义抽象类Animal 2     constructor(){} 3     abstract eat(food: string){} 4     /*定义抽象方法eat(),并且限定传入的参数类型是string, 5     还可以定义返回值,接口等,如果子类不符合限定的规范,编译的时候就会报错。 6     */ 7 } 8 class Snake extends Animal{}//报错,无法通过编译,因为没有定义eat()抽象方法 9 class Dog extends Animal{10     eat(food: string){11         console.log("这只狗正在吃"+food);12     }13 }14 class Cat extends Animal{15     eat(food: string){16         console.log("这只猫正在吃"+food);17     }18 }19 let dog = new Dog();20 dog.eat('骨头');//log:这只狗正在吃骨头21 let cat = new Cat();22 cat.eat('鱼');//log:这只猫正在吃鱼

Afterword

저자의 글이 마음에 든다면 북마크에 추가해 두세요. 여러분의 좋아요는 글쓴이에게 가장 큰 격려가 됩니다.

 객체지향의 주요 지식은 여기서 끝났습니다. 제가 말한 것은 확실히 완벽하지는 않습니다. 시간이 있으면 빨리 시작하는 것이 좋습니다. js OOP를 체계적으로 읽고 배우세요

위 내용은 JavaScript의 다형성에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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