Çağdaş diller için, sadece sözdizimsel şeker; tamamen dilden bağımsız bir şekilde, bundan daha fazlası.
Daha önce bu cevap basitçe sözdizimsel şekerden daha fazlasını ifade ediyordu, ancak yorumlarda görüyorsanız, Falco, çağdaş dillerin eksik olduğu bir bulmacanın bir parçası olduğu noktasını dile getirdi; aynı aşamada hangi işlevi çağıracaklarını dinamik belirleme ile yöntem aşırı yüklemesini karıştırmazlar. Bu daha sonra açıklanacaktır.
İşte bu yüzden daha fazla olmalı .
Hem yöntem aşırı yüklenmesini hem de türlenmemiş değişkenleri destekleyen bir dil düşünün. Aşağıdaki yöntem prototiplerine sahip olabilirsiniz:
bool someFunction(int arg);
bool someFunction(string arg);
Bazı dillerde, derleme zamanında bunlardan hangisinin belirli bir kod satırı tarafından çağrılacağını bilmek istifa edersiniz. Ancak bazı dillerde, tüm değişkenler yazılmaz (veya hepsi örtük olarak Object
veya herhangi bir şekilde yazılır ), bu nedenle anahtarları farklı türdeki değerlerle eşleşen bir sözlük oluşturduğunuzu düşünün:
dict roomNumber; // some hotels use numbers, some use letters, and some use
// alphanumerical strings. In some languages, built-in dictionary
// types automatically use untyped values for their keys to map to,
// so it makes more sense then to allow for both ints and strings in
// your code.
O zaman, someFunction
bu oda numaralarından birine başvurmak istersen ? Buna şöyle diyorsunuz:
someFunction(roomNumber[someSortOfKey]);
Is someFunction(int)
denir, ya da someFunction(string)
aradı? Burada, özellikle üst düzey dillerde bunların tamamen dik yöntem olmadığı bir örnek görüyorsunuz. Dil, çalışma zamanı boyunca bunlardan hangisini çağıracağını bulmalıdır, bu yüzden bunları en azından bir şekilde aynı yöntem olarak görmelidir.
Neden sadece şablon kullanmıyorsunuz? Neden basitçe bir argüman kullanmıyorsunuz?
Esneklik ve ince taneli kontrol. Bazen şablonlar / türlenmemiş argümanlar kullanmak daha iyi bir yaklaşımdır, ancak bazen değildir.
Örneğin, her birinin bir int
ve bir string
bağımsız değişken olarak aldığı iki yöntem imzası olabileceği , ancak her imzada siparişin farklı olduğu durumları düşünmeniz gerekir . Bunu yapmak için iyi bir nedeniniz olabilir, çünkü her imzanın uygulaması büyük ölçüde aynı şeyi yapabilir, ancak sadece biraz farklı bir bükülme ile; örneğin, günlük kaydı farklı olabilir. Veya tam olarak aynı şeyi yapsalar bile, belirli bilgileri yalnızca argümanların belirtildiği sıradan otomatik olarak toplayabilirsiniz. Teknik olarak, geçirilen bağımsız değişkenlerin her birinin türünü belirlemek için sözde anahtar deyimlerini kullanabilirsiniz, ancak bu dağınık hale gelir.
Peki bu bir sonraki örnek kötü programlama uygulaması mı?
bool stringIsTrue(int arg)
{
if (arg.toString() == "0")
{
return false;
}
else
{
return true;
}
}
bool stringIsTrue(Object arg)
{
if (arg.toString() == "0")
{
return false;
}
else
{
return true;
}
}
bool stringIsTrue(string arg)
{
if (arg == "0")
{
return false;
}
else
{
return true;
}
}
Evet, genel olarak. Bu özel örnekte, birisinin bunu belirli ilkel türlere uygulamaya çalışmasını ve beklenmedik davranışları geri kazanmasını engelleyebilir (ki bu iyi bir şey olabilir); ancak diyelim ki yukarıdaki kodu kısalttım ve aslında tüm ilkel tipler ve Object
s için aşırı yüklemelere sahipsiniz . O zaman bu sonraki kod parçası gerçekten daha uygundur:
bool stringIsTrue(untyped arg)
{
if (arg.toString() == "0")
{
return false;
}
else
{
return true;
}
}
Ama bunu sadece int
s ve string
s için kullanmanız gerekiyorsa ve ya daha basit veya daha karmaşık koşullara göre doğru dönmesini istiyorsanız ne olur? Sonra aşırı yüklemeyi kullanmak için iyi bir nedeniniz var:
bool appearsToBeFirstFloor(int arg)
{
if (arg.digitAt(0) == 1)
{
return true;
}
else
{
return false;
}
}
bool appearsToBeFirstFloor(string arg)
{
string firstCharacter = arg.characterAt(0);
if (firstCharacter.isDigit())
{
return appearsToBeFirstFloor(int(firstCharacter));
}
else if (firstCharacter.toUpper() == "A")
{
return true;
}
else
{
return false;
}
}
Ama hey, neden bu işlevlere iki farklı isim vermiyorsunuz? Hala aynı miktarda ince taneli kontrole sahipsiniz, değil mi?
Çünkü, daha önce belirtildiği gibi, bazı oteller rakamlar kullanır, bazıları harf kullanır ve bazıları rakam ve harflerden oluşan bir karışım kullanır:
appearsToBeFirstFloor(roomNumber[someSortOfKey]);
// will treat ints and strings differently, without you having to write extra code
// every single spot where the function is being called
Bu hala gerçek hayatta kullanacağım kodun aynısı değil, ama gayet iyi yaptığım noktayı göstermeli.
Ama ... İşte bu yüzden çağdaş dillerde sözdizimsel şekerden daha fazlası değil.
Falco, yorumlarda mevcut dillerin temelde aynı adımda yöntem aşırı yüklemesi ve dinamik işlev seçimini karıştırmadığı noktasını dile getirdi. Daha önce belirli dilleri çalışmak için anladığım yol appearsToBeFirstFloor
, yukarıdaki örnekte aşırı yüklenebilmenizdi ve dil, çalışma zamanında, türlenmemiş değişkenin çalışma zamanı değerine bağlı olarak, işlevin hangi sürümünün çağrılacağını belirleyecekti. Bu karışıklık kısmen, belirli bir kod satırında hangi fonksiyonun çalışma zamanında çağrıldığını kolayca rastgele ayarlayabileceğiniz ActionScript 3.0 gibi ECMA türleriyle çalışmaktan kaynaklanmıştır.
Bildiğiniz gibi, ActionScript 3 yöntem aşırı yüklemesini desteklemez. VB.NET'e gelince, bir türü açıkça atamadan değişkenleri bildirebilir ve ayarlayabilirsiniz, ancak bu değişkenleri aşırı yüklenmiş yöntemlere bağımsız değişken olarak geçirmeye çalıştığınızda, hangi yöntemi çağırmak istediğinizi belirlemek için çalışma zamanı değerini okumak istemez; bunun yerine, tür argümanları olan Object
veya olmayan türler veya buna benzer başka bir yöntem bulmak ister . Dolayısıyla, yukarıdaki int
vs. string
örneği de bu dilde çalışmaz. C ++, boş bir işaretçi veya bunun gibi başka bir mekanizma kullandığınızda olduğu gibi benzer sorunlara sahiptir, yine de derleme zamanında türü el ile ayırmanızı gerektirir.
İlk başlığın dediği gibi ...
Çağdaş diller için, sadece sözdizimsel şeker; tamamen dilden bağımsız bir şekilde, bundan daha fazlası. Yukarıdaki örnekte olduğu gibi yöntem aşırı yüklemesini daha kullanışlı ve alakalı hale getirmek, aslında mevcut bir dile eklemek için iyi bir özellik olabilir (AS3 için yaygın olarak talep edildiği gibi) veya aynı zamanda birçok farklı temel sütun arasında yeni bir prosedür / nesne yönelimli dil oluşturulması.