Gostaria de saber o que o homem e a criança têm em comum e como eles diferem.
class Person {
name: string;
age: number;
}
class child extends Person {}
class man implements Person {}
Gostaria de saber o que o homem e a criança têm em comum e como eles diferem.
class Person {
name: string;
age: number;
}
class child extends Person {}
class man implements Person {}
Respostas:
extends
significa:A nova classe é uma criança . Ele obtém benefícios provenientes da herança. Ele tem todas as propriedades e métodos como pai. Ele pode sobrescrever alguns deles e implementar novos, mas o material pai já está incluído.
implements
significa:A nova classe pode ser tratada como a mesma "forma" , embora não seja uma criança . Pode ser passado para qualquer método em que Person
seja necessário, independentemente de ter um pai diferentePerson
Em OOP (linguagens como C #, Java) , usaríamos
extends
lucrar com a herança (ver wiki ). Citação pequena:
... Herança na maioria das linguagens orientadas a objetos baseadas em classes é um mecanismo no qual um objeto adquire todas as propriedades e comportamentos do objeto pai. A herança permite aos programadores: criar classes que são construídas sobre classes existentes ...
implements
será mais para polimorfismo (veja wiki ). Citação pequena:
... polimorfismo é o fornecimento de uma única interface para entidades de diferentes tipos ...
Portanto, podemos ter uma árvore de herança realmente diferente da nossa class Man
.
class Man extends Human ...
mas se também declararmos que podemos fingir ser um tipo diferente - Person
:
class Man extends Human
implements Person ...
.. então podemos usá-lo em qualquer lugar, onde Person
for necessário. Nós apenas temos que cumprir as Pessoas "interface"
(ou seja, implementar todas as suas coisas públicas) .
implement
outra classe? Isso é muito legalA cara legal do Javascript (um dos benefícios) é o suporte integrado à digitação Duck ( consulte a wiki ). Citação pequena:
"Se ele anda como um pato e grasna como um pato, então deve ser um pato."
Então, em Javascript, se dois objetos diferentes ... tivessem um método semelhante (por exemplo render()
), eles podem ser passados para uma função que o espera:
function(engine){
engine.render() // any type implementing render() can be passed
}
Para não perder isso - podemos fazer o mesmo em Typescript - com mais suporte de digitação. E é aí que
class implements class
tem seu papel, onde faz sentido
Em linguagens OOP como C#
... nenhuma maneira de fazer isso ...
Interfaces estendendo classes
Quando um tipo de interface estende um tipo de classe, ele herda os membros da classe, mas não suas implementações. É como se a interface tivesse declarado todos os membros da classe sem fornecer uma implementação. As interfaces herdam até mesmo os membros privados e protegidos de uma classe base. Isso significa que, ao criar uma interface que estende uma classe com membros privados ou protegidos, esse tipo de interface só pode ser implementado por essa classe ou uma subclasse dela.
Isso é útil quando você tem uma grande hierarquia de herança, mas deseja especificar que seu código funcione apenas com subclasses que possuem certas propriedades. As subclasses não precisam ser relacionadas, além de herdar da classe base. Por exemplo:
class Control { private state: any; } interface SelectableControl extends Control { select(): void; } class Button extends Control implements SelectableControl { select() { } } class TextBox extends Control { select() { } } // Error: Property 'state' is missing in type 'Image'. class Image implements SelectableControl { private state: any; select() { } } class Location { }
Por enquanto
extends
significa - obtém tudo de seu paiimplements
neste caso, é quase como implementar uma interface. O objeto filho pode fingir que é pai ... mas não obtém nenhuma implementaçãoextends
- obtém tudo de seu pai", isso se aplica a membros privados? Por exemplo class Person {private name: string} class man extends Person{gender: string;}
, man
tem o nome da propriedade?
Em typescript (e em algumas outras linguagens OO), você tem classes e interfaces.
Uma interface não tem implementação, é apenas um "contrato" de quais membros / método esse tipo possui.
Por exemplo:
interface Point {
x: number;
y: number;
distance(other: Point): number;
}
As instâncias que implementam esta Point
interface devem ter dois membros do tipo number: x
and y
, e um método distance
que recebe outra Point
instância e retorna a number
.
A interface não implementa nenhum desses.
As classes são as implementações:
class PointImplementation implements Point {
public x: number;
public y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
public distance(other: Point): number {
return Math.sqrt(Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2));
}
}
Em seu exemplo, você trata sua Person
classe uma vez como uma classe ao estendê-la e uma vez como uma interface ao implementá-la.
Seu código:
class Person {
name: string;
age: number;
}
class Child extends Person {}
class Man implements Person {}
Tem um erro de compilação dizendo:
A classe 'Man' implementa incorretamente a interface 'Person'.
A propriedade 'nome' está ausente no tipo 'Homem'.
E isso porque as interfaces carecem de implementação.
Então, se você implement
uma classe, você apenas pega seu "contrato" sem a implementação, então você precisará fazer isso:
class NoErrorMan implements Person {
name: string;
age: number;
}
O ponto principal é que, na maioria dos casos, você deseja extend
outra classe e não implement
ela.
Ótima resposta de @nitzan-tomer! Me ajudou muito ... Eu estendi um pouco sua demonstração com:
IPoint interface;
Point implements IPoint;
Point3D extends Point;
E como eles se comportam em funções que esperam um IPoint
tipo.
Portanto, o que aprendi até agora e tenho usado como regra geral: se você estiver usando classes e métodos que esperam tipos genéricos, use interfaces como os tipos esperados. E certifique-se de que o pai ou a classe base usa essa interface. Dessa forma, você pode usar todas as subclasses daquelas, na medida em que implementam a interface.
Aqui está a demonstração estendida
extends
foco em herdar e implements
foco na restrição sejam interfaces ou classes.
extends
: A classe filha (que é estendida) herdará todas as propriedades e métodos da classe é extendsimplements
: A classe que usa a implements
palavra - chave precisará implementar todas as propriedades e métodos da classe que elaimplements
Para colocar em termos mais simples:
extends
: Aqui você obtém todos esses métodos / propriedades da classe pai para que não precise implementá-los sozinhoimplements
: Aqui está um contrato que a turma deve seguir. A classe deve implementar pelo menos os seguintes métodos / propriedadesclass Person {
name: string;
age: number;
walk(): void {
console.log('Walking (person Class)')
}
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
class child extends Person { }
// Man has to implements at least all the properties
// and methods of the Person class
class man implements Person {
name: string;
age: number
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
walk(): void {
console.log('Walking (man class)')
}
}
(new child('Mike', 12)).walk();
// logs: Walking(person Class)
(new man('Tom', 12)).walk();
// logs: Walking(man class)
No exemplo, podemos observar que a classe filha herda tudo de Person, enquanto a classe man tem que implementar tudo da própria Person.
Se tivéssemos de remover algo da classe man, por exemplo, o método walk, obteríamos o seguinte erro de tempo de compilação :
A classe 'man' implementa incorretamente a classe 'Person'. Você quis dizer estender 'Person' e herdar seus membros como uma subclasse? A propriedade 'walk' está ausente no tipo 'man', mas é necessária no tipo 'Person'. (2720)