Erkek ve çocuğun ortak yönlerini ve nasıl farklı olduklarını bilmek isterim .
class Person {
name: string;
age: number;
}
class child extends Person {}
class man implements Person {}
Erkek ve çocuğun ortak yönlerini ve nasıl farklı olduklarını bilmek isterim .
class Person {
name: string;
age: number;
}
class child extends Person {}
class man implements Person {}
Yanıtlar:
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
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 şeylerJavascript'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 ...
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ırimplementsbu durumda neredeyse bir arayüz uygulamak gibidir. Alt nesne ebeveynmiş gibi davranabilir ... ancak herhangi bir uygulama almazextends-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?
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));
}
}
Ö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;
}
Sonuç olarak, çoğu durumda extendbaşka bir sınıfa gitmek istersiniz , implementona değil.
@ 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
extendsimplementsister arayüzler ister sınıflar olsun , miras almaya ve kısıtlamaya odaklanın.
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.implementsDaha 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ızimplements: İş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 / özelliklereclass 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)