TypeScript'te 'genişletmeler' ve 'uygulamalar' arasındaki fark nedir


Yanıtlar:


156

Kısa versiyon

  • extends anlamına geliyor:

Yeni sınıf bir çocuktur . Mirasla gelen faydalar alır. Tüm özelliklere, metotlara ebeveyn olarak sahiptir. Bunlardan bazılarını geçersiz kılabilir ve yenilerini uygulayabilir, ancak ana şeyler zaten dahil edilmiştir.

  • implements anlamına geliyor:

Yeni sınıf olarak tedavi edilebilir aynı "şekil" ise, o çocuk değil . PersonEbeveynden farklı olmasına bakılmaksızın, gerekli olduğu herhangi bir yönteme geçirilebilir.Person

Daha ...

In OOP (C #, Java gibi diller) kullanacağımız

extendsmirastan kar elde etmek için ( wiki'ye bakınız ). Küçük alıntı:

... Sınıf tabanlı nesne yönelimli dillerin çoğunda kalıtım, bir nesnenin ana nesnenin tüm özelliklerini ve davranışlarını elde ettiği bir mekanizmadır. Devralma, programcıların şunları yapmasına olanak tanır: mevcut sınıflar üzerine inşa edilmiş sınıflar oluşturma ...

implementspolimorfizm için daha fazla olacaktır ( wiki'ye bakınız ). Küçük alıntı:

... polimorfizm, farklı türlerdeki varlıklara tek bir arayüz sağlanmasıdır ...

Yani gerçekten farklı miras ağacımıza sahip olabiliriz class Man.

class Man extends Human ...

ancak aynı zamanda farklı bir tür gibi davranabileceğimizi de beyan edersek - Person:

class Man extends Human 
          implements Person ...

.. o zaman Persongerekli olan her yerde kullanabiliriz . Biz sadece Kişilerinkini yerine getirmeliyiz "interface" (yani, tüm kamusal malzemelerini uygulamalıyız) .

implementdiğer sınıf? Bu gerçekten harika şeyler

Javascript'in güzel yüzü (faydalarından biri) Duck yazmanın yerleşik desteğidir ( wiki'ye bakın ). Küçük alıntı:

"Ördek gibi yürüyorsa ve ördek gibi şarlatansa, o zaman bir ördek olmalı."

Dolayısıyla, Javascript'te, eğer iki farklı nesne ... benzer bir yönteme sahipse (örneğin render()) , onu bekleyen bir işleve geçirilebilirler:

function(engine){
  engine.render() // any type implementing render() can be passed
}

Bunu kaybetmemek için - Typescript'te de aynısını yapabiliriz - daha fazla tip desteği ile. Ve bu nerede

class implements class

mantıklı olduğu yerde rolü var

OOP dillerinde C#... bunu yapmanın yolu yok ...

Ayrıca belgeler burada yardımcı olmalıdır:

Sınıfları Genişleten Arayüzler

Bir arabirim türü bir sınıf türünü genişlettiğinde, sınıfın üyelerini miras alır ancak uygulamalarını devralmaz. Sanki arayüz, bir uygulama sağlamadan sınıfın tüm üyelerini bildirmiş gibidir. Arabirimler, bir temel sınıfın özel ve korumalı üyelerini bile miras alır. Bu, bir sınıfı özel veya korumalı üyelerle genişleten bir arabirim oluşturduğunuzda, bu arabirim türünün yalnızca o sınıf veya onun bir alt sınıfı tarafından uygulanabileceği anlamına gelir.

Bu, büyük bir devralma hiyerarşiniz olduğunda, ancak kodunuzun yalnızca belirli özelliklere sahip alt sınıflarla çalıştığını belirtmek istediğinizde kullanışlıdır. Alt sınıfların, temel sınıftan miras almanın yanı sıra ilişkili olması gerekmez. Örneğin:

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 {

}

Öyleyse

  • extends anlamına gelir - hepsini ebeveyninden alır
  • implementsbu durumda neredeyse bir arayüz uygulamak gibidir. Alt nesne ebeveynmiş gibi davranabilir ... ancak herhangi bir uygulama almaz

" extends-tümünü ebeveyninden alır " dediğinizde , özel üyeler için geçerli mi? Mesela class Person {private name: string} class man extends Person{gender: string;}yapar manözellik adı var?
davejoem

Özel de orada. Sadece TS tarafından erişilemez. Onları koruyun ve kullanabilirsiniz. "Uygulamalar" durumunda, sadece kamusal kısım mantıklıdır. Umarım biraz yardımcı olur
Radim Köhler

Mükemmel cevap. Sadece "özel orada, ancak TS tarafından erişilemez" yorumunuzdan emin değilim. Özel mülklerin yeni oluşturulan bu alt nesnede kopyalandığını mı söylüyorsunuz? Ve aletler söz konusu olduğunda, sadece kamu malları kopyalanır mı?
kushalvm

Ayrıca bir puan daha aldım. Extends tanımı buysa. Öyleyse lütfen bu stackoverflow.com/questions/60390454/…
kushalvm

99

Typcript'te (ve diğer bazı OO dillerinde) sınıflarınız ve arayüzleriniz vardır.

Bir arayüzün uygulaması yoktur, sadece bu tipteki üyelerin / yöntemin bir "sözleşmesidir".
Örneğin:

interface Point {
    x: number;
    y: number;
    distance(other: Point): number;
}

Bu Pointarabirimi uygulayan örnekler , iki tür numarası üyesine sahip olmalıdır: xve yve distancebaşka bir Pointörneği alan ve bir number.
Arayüz bunların hiçbirini uygulamıyor.

Sınıflar uygulamalardır:

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));
    }
}

( oyun alanında kod )

Örneğinizde, Personsınıfınızı bir kez genişlettiğinizde bir sınıf olarak ve bir kez uyguladığınızda bir arayüz olarak ele alıyorsunuz.
Senin kodun:

class Person {
    name: string;
    age: number;
}
class Child  extends Person {}

class Man implements Person {}

Şu derleme hatası var:

"Adam" sınıfı, "Kişi" arayüzünü yanlış uyguluyor.
"Man" türünde "name" özelliği eksik.

Bunun nedeni arayüzlerin uygulama eksikliğidir.
Dolayısıyla, eğer implementbir sınıfsanız, o zaman sadece "sözleşmesini" uygulama olmadan alırsınız, bu yüzden şunu yapmanız gerekir:

class NoErrorMan implements Person {
    name: string;
    age: number;
}

( oyun alanında kod )

Sonuç olarak, çoğu durumda extendbaşka bir sınıfa gitmek istersiniz , implementona değil.


6

@ Nitzan-tomer! Bana çok yardımcı oldu ... Demosunu biraz genişlettim:

IPoint interface;
Point implements IPoint;
Point3D extends Point;

Ve bir IPointtür bekleyen işlevlerde nasıl davrandıklarını .

Şimdiye kadar öğrendiğim ve bir başparmak kuralı olarak kullandığım şey: Genel türler bekleyen sınıflar ve yöntemler kullanıyorsanız, beklenen türler olarak arabirimleri kullanın. Ve ana veya temel sınıfın bu arabirimi kullandığından emin olun. Bu şekilde, arayüzü uyguladıkları sürece tüm alt sınıfları kullanabilirsiniz.

İşte genişletilmiş demo


Bu soruya bir cevap vermiyor. Bir yazarı eleştirmek veya açıklama istemek için yazının altına bir yorum bırakın. - Yorumdan
aronisstav

1
@aronisstav Bana zaten yardımcı olan iyi bir yanıt bulduğum şeyin yalnızca genişletilmiş bir demosunu yayınladım. Ama belki bir başkası benim yaptığım çalışmayı demoyu genişletmek için yararlı bulabilir. Bu kadar. Yorumlar gerçekten bir kod bloğu koymak için tasarlanmamıştır, bu yüzden bir Cevap Gönderisinde daha anlaşılır buluyorum. Peki bununla ilgili sorun ne?
andzep

Cevabınız uzunluk ve içerik nedeniyle (otomatik olarak?) İşaretlendi, inceleme kuyruğumda göründü ve bayrakta sunulan nedenleri hak ettim. Ana katkısı (demoyu uzattığınızı açıklamak) bir yorum olarak daha iyi olacaktır. Eklenen paragrafla belki de gerçekten daha kullanışlıdır.
aronisstav

@andzep, genişletilmiş demo örneğiniz gerçekten yardımcı oluyor.
namit

3
  1. Arayüz arayüzü şekli ile genişletir
  2. Arayüz sınıfı şekil ile genişletir
  3. Sınıf uygulamaları arayüzü, arayüz tarafından sağlanan tüm alanları uygulamalıdır
  4. Sınıf, sınıfı şekliyle uygular
  5. Sınıf, sınıfı tüm alanlarla genişletir

extendsimplementsister arayüzler ister sınıflar olsun , miras almaya ve kısıtlamaya odaklanın.


0

VS uygulamalarını genişletir

  • extends: Çocuk sınıfı (genişletilmiş) , sınıfın tüm özelliklerini ve yöntemlerini miras alır.
  • implements: implementsAnahtar kelimeyi kullanan sınıfın, sınıfın tüm özelliklerini ve yöntemlerini uygulaması gerekecektir.implements

Daha basit terimlerle ifade etmek gerekirse:

  • extends: Burada tüm bu yöntemleri / özellikleri ana sınıftan alırsınız, böylece bunu kendiniz uygulamak zorunda kalmazsınız
  • implements: İşte sınıfın uyması gereken bir sözleşme. Sınıfı vardır uygulanması en azından aşağıdaki yöntemler / özelliklere

Misal:

class 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)

Örnekte, çocuk sınıfının her şeyi Person'den miras aldığını, oysa erkek sınıfının her şeyi Person'un kendisinden uygulaması gerektiğini gözlemleyebiliriz.

Man sınıfından bir şeyi kaldıracak olsaydık, örneğin yürüme yöntemi aşağıdaki derleme zamanı hatasını alırdık :

"Adam" sınıfı, "Kişi" sınıfını yanlış bir şekilde uygular. 'Kişi'yi genişletmek ve üyelerini bir alt sınıf olarak miras almak mı istediniz? "Yürüyüş" özelliği "adam" türünde eksik, ancak "Kişi" türünde gerekli. (2720)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.