Zaten soyut sınıflar varsa neden bir arayüze ihtiyacınız var?
Çoklu kalıtımın önlenmesi (bilinen birden fazla soruna neden olabilir).
Bu tür problemlerden biri:
"Elmas problemi" (bazen "ölümcül ölüm pırlantası" olarak da anılır), iki B ve C sınıfı A'dan ve D sınıfı hem B hem de C'den miras alındığında ortaya çıkan bir belirsizliktir. A'da bir yöntem varsa B ve C geçersiz kılındı ve D onu geçersiz kılmadı, o zaman D yöntemin hangi sürümü miras alır: B'nin mi yoksa C'nin mi?
Kaynak: https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem
Neden / ne zaman bir arayüz kullanılır?
Bir örnek ... Dünyadaki tüm arabalar aynı arayüze (yöntemlere) sahiptir ... AccelerationPedalIsOnTheRight()
, BrakePedalISOnTheLeft()
. Her otomobil markasının bu "yöntemlere" başka bir markadan farklı olacağını düşünün. BMW'nin sağ tarafında frenler ve Honda'da tekerleğin sol tarafında frenler olurdu. İnsanlar farklı bir marka otomobil satın aldıklarında bu "yöntemlerin" nasıl çalıştığını öğrenmek zorunda kalacaklardı. Bu yüzden aynı arayüzü birden çok "yerde" kullanmak iyi bir fikirdir.
Bir arayüz sizin için ne yapar (neden biri bile bir tane kullansın)? Bir arabirim "hatalar" yapmanızı engeller (belirli bir arabirimi uygulayan tüm sınıfların, arabirimde bulunan yöntemlere sahip olmasını sağlar).
// Methods inside this interface must be implemented in all classes which implement this interface.
interface IPersonService
{
public function Create($personObject);
}
class MySqlPerson implements IPersonService
{
public function Create($personObject)
{
// Create a new person in MySql database.
}
}
class MongoPerson implements IPersonService
{
public function Create($personObject)
{
// Mongo database creates a new person differently then MySQL does. But the code outside of this method doesn't care how a person will be added to the database, all it has to know is that the method Create() has 1 parameter (the person object).
}
}
Bu şekilde, Create()
yöntem her zaman aynı şekilde kullanılacaktır. MySqlPerson
Sınıfı mı yoksa sınıfı mı kullanmamız önemli değil MongoPerson
. Bir yöntemi kullanma şeklimiz aynı kalır (arayüz aynı kalır).
Örneğin, şu şekilde kullanılacaktır (kodumuzun her yerinde):
new MySqlPerson()->Create($personObject);
new MongoPerson()->Create($personObject);
Bu şekilde, böyle bir şey olamaz:
new MySqlPerson()->Create($personObject)
new MongoPerson()->Create($personsName, $personsAge);
Bir arayüzü hatırlamak ve aynı arayüzü her yerde kullanmak, birden fazla farklı arayüzden çok daha kolaydır.
Bu şekilde, Create()
yöntemin içi, bu yöntemi çağıran "dış" kodu etkilemeden farklı sınıflar için farklı olabilir. Dış kodun bilmesi gereken, yöntemin Create()
1 parametresine ( $personObject
) sahip olmasıdır, çünkü dış kod bu yöntemi kullanacak / çağıracaktır. Dış kod, yöntemin içinde neler olduğunu umursamıyor; sadece onu nasıl kullanacağını / arayacağını bilmelidir.
Bunu bir arabirim olmadan da yapabilirsiniz, ancak bir arabirim kullanırsanız, "daha güvenlidir" (çünkü hata yapmanızı engeller). Arayüz, yöntemin Create()
, arabirimi uygulayan tüm sınıflarda aynı imzayı (aynı tür ve aynı sayıda parametre) sahip olmasını sağlar. Bu şekilde, IPersonService
arabirimi uygulayan HERHANGİ sınıfın yönteme Create()
(bu örnekte) sahip olduğundan ve $personObject
çağrılacak / kullanılacak yalnızca 1 parametreye ( ) ihtiyaç duyacağından emin olabilirsiniz .
Bir arabirimi uygulayan bir sınıf, arabirimin sahip olduğu / sahip olduğu tüm yöntemleri uygulamalıdır.
Umarım kendimi fazla tekrarlamamıştım.