XML ad alanları hakkında bilginiz varsa, ActionScript uygulamasının sözdizimi ve ayrıntıları XML'dekinden biraz daha farklı olsa da, burada ele alınan konuların çoğu size yabancı gelmeyecektir. Daha önce hiç ad alanlarıyla çalışmadıysanız, kavramın kendisi oldukça anlaşılırdır ancak uygulama için öğrenmeniz gereken belirli terminolojiler vardır.
Ad alanlarının nasıl çalıştığını anlamak için, özellik veya yöntem adının her zaman tanımlayıcı ve ad alanı olmak üzere iki bölüm içerdiğinin bilinmesi yardımcı olacaktır. Tanımlayıcı, genellikle ad olarak düşündüğünüz şeydir. Örneğin, aşağıdaki sınıf tanımında bulunan tanımlayıcılar
sampleGreeting ve sampleFunction() şeklindedir:
class SampleCode
{
var sampleGreeting:String;
function sampleFunction () {
trace(sampleGreeting + " from sampleFunction()");
}
}
Tanımların önünde bir ad alanı niteliği olmadığında, tanımların adları varsayılan olarak internal ad alanı şeklinde nitelendirilir, başka bir deyişle bunlar yalnızca aynı paketteki çağıranlara görünür. Derleyici katı moda ayarlanırsa, derleyici, ad alanı niteliği olmayan tüm tanımlayıcılara internal ad alanının uygulandığına dair bir uyarı yayınlar. Bir tanımlayıcının her yerde kullanılabilir olmasını sağlamak için, tanımlayıcı adının başına özel olarak public niteliğini getirmeniz gerekir. Önceki örnek kodda, hem sampleGreeting hem de sampleFunction(), internal ad alanı değerine sahiptir.
Ad alanları kullanılırken izlenmesi gereken üç temel adım vardır. İlk olarak, namespace anahtar sözcüğünü kullanarak ad alanını tanımlamanız gerekir. Örneğin, aşağıdaki kod version1 ad alanını tanımlar:
namespace version1;
İkinci olarak, ad alanınızı bir özellik veya yöntem bildiriminde erişim denetimi belirticisinin yerine kullanarak uygularsınız. Aşağıdaki örnek, version1 ad alanına myFunction() adında bir işlev yerleştirir:
version1 function myFunction() {}
Üçüncü olarak, ad alanını uyguladıktan sonra, use direktifiyle veya bir tanımlayıcının adını bir ad alanıyla niteleyerek bu ad alanına başvurabilirsiniz. Aşağıdaki örnek, use direktifi yoluyla myFunction() işlevine başvurur:
use namespace version1;
myFunction();
Aşağıdaki örnekte gösterildiği gibi, myFunction() işlevine başvurmak için nitelendirilmiş bir ad da kullanabilirsiniz:
version1::myFunction();
Ad alanlarını tanımlama
Ad alanları, bazen ad alanı adı olarak da adlandırılan tek bir değer (Uniform Resource Identifier (URI)) içerir. URI, ad alanı tanımınızın benzersiz olmasını sağlamanıza yardımcı olur.
İki yöntemden birini kullanarak bir ad alanı tanımı bildirip bir ad alanı oluşturursunuz. Bir XML ad alanı tanımlayacağınızdan, açık bir URI ile bir ad alanını tanımlayabilir veya URI'yi atabilirsiniz. Aşağıdaki örnek, URI kullanılarak bir ad alanının nasıl tanımlanabildiğini gösterir:
namespace flash_proxy = "http://www.adobe.com/flash/proxy";
URI, o ad alanı için benzersiz bir kimlik dizesi görevi görür. Aşağıdaki örnekteki gibi, URI'yi atarsanız, derleyici URI yerine benzersiz bir dahili kimlik dizesi oluşturur. Bu dahili kimlik dizesine erişiminiz olmaz.
namespace flash_proxy;
Siz URI ile veya URI olmadan bir ad alanını tanımladıktan sonra, o ad alanı aynı kapsamda yeniden tanımlanamaz. Aynı kapsamda önceden tanımlanmış bir ad alanını tanımlama girişimi, bir derleyici hatasına yol açar.
Bir paket veya sınıf içinde bir ad alanı tanımlanırsa, uygun erişim denetimi belirticileri kullanılmadığı sürece, söz konusu ad alanı, o paket veya sınıf dışındaki koda görünmeyebilir. Örneğin, aşağıdaki kod, flash.utils paketinde tanımlanan flash_proxy ad alanını gösterir. Aşağıdaki örnekte, erişim denetimi belirticisinin olmaması, flash_proxy ad alanının yalnızca flash.utils paketindeki koda görüneceği ve bu paket dışındaki kodlara görünmeyeceği anlamına gelir:
package flash.utils
{
namespace flash_proxy;
}
Aşağıdaki kod, flash_proxy ad alanını paket dışındaki kodlara görünür duruma getirmek için public niteliğini kullanır:
package flash.utils
{
public namespace flash_proxy;
}
Ad alanlarını uygulama
Ad alanı uygulanması, bir ad alanına bir tanımın yerleştirilmesi anlamına gelir. Ad alanlarına yerleştirilebilen tanımlar arasında, işlevler, değişkenler ve sabitler yer alır. (Özel bir ad alanına sınıf yerleştiremezsiniz.)
Örneğin, public erişim denetimi ad alanı kullanılarak bildirilen bir işlevi göz önünde bulundurun. Bir işlev tanımında public niteliği kullanıldığında, o işlev genel ad alanına yerleştirilir ve böylece işlev, tüm kod için kullanılabilir olur. Bir ad alanını tanımladıktan sonra, tanımladığınız ad alanını public niteliğiyle aynı şekilde kullanabilirsiniz ve tanım da özel ad alanınıza başvurabilen kod için kullanılabilir olur. Örneğin, bir example1 ad alanını tanımlarsanız, aşağıdaki örnekte gösterildiği gibi, nitelik olarak example1 öğesini kullanıp myFunction() adında bir yöntemi ekleyebilirsiniz:
namespace example1;
class someClass
{
example1 myFunction() {}
}
Nitelik olarak example1 ad alanı kullanılarak myFunction() yönteminin bildirilmesi, yöntemin example1 ad alanına ait olduğu anlamına gelir.
Ad alanlarını uygularken aşağıdakileri göz önünde bulundurmanız gerekir:
Her bildirime yalnızca bir ad alanı uygulayabilirsiniz.
Aynı anda birden çok tanıma bir ad alanı niteliği uygulanamaz. Başka bir deyişle, ad alanınızı on farklı işleve uygulamak istiyorsanız, on işlev tanımının her birine nitelik olarak ad alanınızı eklemeniz gerekir.
Ad alanları ve erişim denetimi belirticileri birbirini dışladığından, bir ad alanı uygularsanız, bir erişim denetimi belirticisi de belirtemezsiniz. Başka bir deyişle, bir işlevi veya özelliği ad alanınıza uygulamanın yanı sıra public, private, protected ya da internal olarak bildiremezsiniz.
Ad alanlarına başvurma
public, private, protected ve internal gibi herhangi bir erişim denetimi ad alanıyla bildirilmiş bir yöntem veya özellik kullandığınızda, ad alanına açıkça başvurulmasına gerek yoktur. Bunun nedeni, bu özel ad alanlarına erişimin bağlama göre denetlenmesidir. Örneğin, private ad alanına yerleştirilen tanımlar, aynı sınıf içindeki kod için otomatik olarak kullanılabilir olur. Ancak tanımladığınız ad alanları için böyle bir bağlam duyarlılığı yoktur. Özel bir ad alanına yerleştirdiğiniz bir yöntem veya özelliği kullanmak için, ad alanına başvurmanız gerekir.
use namespace direktifiyle ad alanlarına başvurabilir veya ad niteleyicisi (::) işaretini kullanarak ad alanıyla adı niteleyebilirsiniz. use namespace direktifiyle bir ad alanına başvurulması, ad alanını “açar”, böylece ad alanı nitelendirilmiş olmayan herhangi bir tanımlayıcıya uygulanabilir. Örneğin, example1 ad alanını tanımladıysanız, use namespace example1 direktifini kullanarak o ad alanındaki adlara erişebilirsiniz:
use namespace example1;
myFunction();
Aynı anda birden çok ad alanı açabilirsiniz. Siz use namespace direktifiyle bir ad alanını açtıktan sonra, bu ad alanı, açıldığı kod bloğu boyunca açık kalır. Ad alanını açıkça kapatmanın bir yolu yoktur.
Ancak birden çok ad alanının açılması, ad çakışması olma olasılığını artırır. Bir ad alanını açmamayı tercih derseniz, yöntem veya özellik adını ad alanı ve ad niteleyicisi işaretiyle niteleyerek use namespace direktifini önleyebilirsiniz. Örneğin, aşağıdaki kod, myFunction() adını example1 ad alanıyla nasıl niteleyebileceğinizi gösterir:
example1::myFunction();
Ad alanlarını kullanma
ActionScript 3.0'ın parçası olan flash.utils.Proxy sınıfında ad çakışmalarını önlemek için kullanılan bir gerçek ad alanı örneğini bulabilirsiniz. ActionScript 2.0'daki Object.__resolve özelliğinin yerini alan Proxy sınıfı, bir hata oluşmadan önce tanımsız özellik veya yöntemlere yapılan başvuruları önlemenize yardımcı olur. Ad çakışmalarını önlemek için, Proxy sınıfının tüm yöntemleri, flash_proxy ad alanında bulunur.
flash_proxy ad alanının nasıl kullanıldığını daha iyi anlamak için, Proxy sınıfının nasıl kullanıldığını anlamanız gerekir. Proxy sınıfının işlevselliği, yalnızca Proxy sınıfından miras alan sınıflar için kullanılabilir durumdadır. Başka bir deyişle, bir nesnede Proxy sınıfının yöntemlerini kullanmak isterseniz, nesnenin sınıf tanımının, Proxy sınıfını genişletmesi gerekir. Örneğin, tanımsız bir yöntemi çağırma girişimlerinin tümünü önlemek istiyorsanız, Proxy sınıfını genişletir ve daha sonra Proxy sınıfının callProperty() yöntemini geçersiz kılarsınız.
Ad alanlarının uygulanmasının genellikle ad alanını tanımlama, uygulama ve ad alanına başvurma olmak üzere üç adımlık bir işlem olduğunu hatırlayabilirsiniz. Ancak, Proxy sınıfı yöntemlerinden herhangi birini asla açıkça çağırmadığınızdan, flash_proxy ad alanı yalnızca tanımlanır ve uygulanır fakat bu ad alanına asla başvurulmaz. ActionScript 3.0, flash_proxy ad alanını tanımlar ve bunu Proxy sınıfında uygular. Kodunuzun yalnızca Proxy sınıfını genişleten sınıflara flash_proxy ad alanını uygulaması gerekir.
flash_proxy ad alanı, flash.utils paketinde aşağıdakine benzer şekilde tanımlanır:
package flash.utils
{
public namespace flash_proxy;
}
Aşağıdaki Proxy sınıfı alıntısında gösterildiği gibi, ad alanı, Proxy sınıfının yöntemlerine uygulanır:
public class Proxy
{
flash_proxy function callProperty(name:*, ... rest):*
flash_proxy function deleteProperty(name:*):Boolean
...
}
Aşağıdaki kodda gösterildiği gibi, ilk olarak hem Proxy sınıfını hem de flash_proxy ad alanını içe aktarmanız gerekir. Daha sonra, Proxy sınıfını genişletecek şekilde sınıfınızı bildirmeniz gerekir. (Katı modda derleme yapıyorsanız, ayrıca dynamic niteliğini de eklemeniz gerekir.) callProperty() yöntemini geçersiz kıldığınızda, flash_proxy ad alanını kullanmanız gerekir.
package
{
import flash.utils.Proxy;
import flash.utils.flash_proxy;
dynamic class MyProxy extends Proxy
{
flash_proxy override function callProperty(name:*, ...rest):*
{
trace("method call intercepted: " + name);
}
}
}
MyProxy sınıfının bir örneğini oluşturur ve aşağıdaki örnekte çağrılan testing() yöntemi gibi tanımsız bir yöntem çağırırsanız, Proxy nesneniz yöntem çağrısını önler ve geçersiz kılınan callProperty() yönteminin içinde deyimleri çalıştırır (bu durumda, basit bir trace() deyimi).
var mySample:MyProxy = new MyProxy();
mySample.testing(); // method call intercepted: testing
flash_proxy ad alanının içinde Proxy sınıfı yöntemlerinden birinin bulunmasının iki avantajı vardır. İlk olarak, ayrı bir ad alanının bulunması, Proxy sınıfını genişleten herhangi bir sınıfın genel arabiriminde karmaşıklığı azaltır. (Proxy sınıfında, geçersiz kılabileceğiniz yaklaşık bir düzine yöntem vardır ve bunların hiçbiri doğrudan çağrılmak üzere tasarlanmamıştır. Bunların tümünün genel ad alanına yerleştirilmesi kafa karıştırıcı olabilir.) İkinci olarak, flash_proxy ad alanının kullanılması, Proxy alt sınıfınızın herhangi bir Proxy sınıfı yöntemiyle eşleşen adlara sahip örnek yöntemler içermesi durumunda ad çakışmalarını önler. Örneğin, kendi yöntemlerinizden birine callProperty() adını vermek isteyebilirsiniz. callProperty() yöntemi sürümünüz farklı bir ad alanında olduğundan, aşağıdaki kod kabul edilebilir:
dynamic class MyProxy extends Proxy
{
public function callProperty() {}
flash_proxy override function callProperty(name:*, ...rest):*
{
trace("method call intercepted: " + name);
}
}
Dört erişim denetimi belirticisiyle (public, private, internal ve protected) gerçekleştirilemeyecek şekilde yöntemlere veya özelliklere erişim sağlamak istediğinizde de ad alanları yardımcı olabilir. Örneğin, birçok pakete yayılmış birkaç yardımcı program yönteminiz olabilir. Bu yöntemlerin, tüm paketleriniz için kullanılabilir olmasını ancak genel olarak herkese açık olmamasını istersiniz. Bunu yapmak için, yeni bir ad alanı oluşturabilir ve bunu kendi özel erişim denetimi belirticiniz olarak kullanabilirsiniz.
Aşağıdaki örnek, farklı paketlerde bulunan iki işlevi birlikte gruplandırmak için kullanıcı tanımlı bir ad alanı kullanır. Bunları aynı ad alanında gruplandırarak tek bir use namespace deyimini kullanıp her iki işlevi bir sınıf veya paket için görünebilir duruma getirebilirsiniz.
Bu örnekte tekniği göstermek için dört dosya kullanılmaktadır. Tüm dosyaların sınıf yolunuzda yazılması gerekir. Birinci dosya olan myInternal.as, myInternal ad alanını tanımlamak için kullanılır. Dosya, example adındaki bir pakette bulunduğundan, dosyayı example adındaki bir klasöre yerleştirmeniz gerekir. Ad alanı, diğer paketlere içe aktarılabilmesi için public olarak işaretlenir.
// myInternal.as in folder example
package example
{
public namespace myInternal = "http://www.adobe.com/2006/actionscript/examples";
}
İkinci ve üçüncü dosyalar olan Utility.as ve Helper.as, diğer paketler için kullanılabilir olması gereken yöntemlerin bulunduğu sınıfları tanımlar. Utility sınıfı, example.alpha paketindedir, başka bir deyişle, example klasörünün alt klasörü olan alpha adında bir klasörün içine dosyanın yerleştirilmesi gerekir. Helper sınıfı, example.beta paketindedir, başka bir deyişle, example klasörünün alt klasörü olan beta adında bir klasörün içine dosyanın yerleştirilmesi gerekir. Bu her iki example.alpha ve example.beta paketinin de ad alanını kullanmadan önce içe aktarması gerekir.
// Utility.as in the example/alpha folder
package example.alpha
{
import example.myInternal;
public class Utility
{
private static var _taskCounter:int = 0;
public static function someTask()
{
_taskCounter++;
}
myInternal static function get taskCounter():int
{
return _taskCounter;
}
}
}
// Helper.as in the example/beta folder
package example.beta
{
import example.myInternal;
public class Helper
{
private static var _timeStamp:Date;
public static function someTask()
{
_timeStamp = new Date();
}
myInternal static function get lastCalled():Date
{
return _timeStamp;
}
}
}
Dördüncü dosya olan NamespaceUseCase.as, ana uygulama sınıfı olup example klasörünün bir eşdüzeyi olması gerekir. Adobe Flash CS4 Professional'da bu sınıf, FLA'nın belge sınıfı olarak kullanılır. NamespaceUseCase sınıfı ayrıca myInternal ad alanını içe aktarır ve diğer paketlerde bulunan iki statik yöntemi çağırmak için bu ad alanını kullanır. Bu örnek yalnızca kodu basitleştirmek için statik yöntemleri kullanır. myInternal ad alanına hem statik yöntemler hem de örnek yöntemleri yerleştirilebilir.
// NamespaceUseCase.as
package
{
import flash.display.MovieClip;
import example.myInternal; // import namespace
import example.alpha.Utility;// import Utility class
import example.beta.Helper;// import Helper class
public class NamespaceUseCase extends MovieClip
{
public function NamespaceUseCase()
{
use namespace myInternal;
Utility.someTask();
Utility.someTask();
trace(Utility.taskCounter); // 2
Helper.someTask();
trace(Helper.lastCalled); // [time someTask() was last called]
}
}
}
0 yorum:
Yorum Gönder