Voici une implémentation qui a le mérite de verrouiller l'accès au constructeur de notre Singleton :

// Logger.as
package iteratif.logging {
	public var Logger:LoggerImpl = new LoggerImpl();
}
 
// Nous mettons la classe à l'exterieur du package mais dans le fichier 
// Logger.as, cette classe est déclarée comme interne
internal class LoggerImpl {
	public function LoggerImpl() {
 
	}
 
	public function log(msg:String):void {
		trace(msg);
	}
}

Nous avons le droit de mettre autant de classes internes que nous voulons dans un fichier .as, ce qui implique que nous avons uniquement accés a ces classes qu'a partir de ce même fichier.

Cette implémentation n'empêche pas la suppression de cet objet, pour y remédier nous allons déclarer Logger comme une constante :

package iteratif.logging {
	public const Logger:LoggerImpl = new LoggerImpl();
}

Résultat obtenu dans Flex Builder 3:

Le compilateur empêche toute compilation puisque nous tentons de supprimer une constante.

Par contre le simple fait que seul le fichier Logger.as connaît la classe LoggerImpl empêche toute forme d'héritage.

Utiliser le metadata [ExcludeClass]

Une autre implémentation du Singleton en AS3 peut-être envisagée sans mettre la classe à l'extérieure du package mais en utilisant un metadata, a savoir le metadata ExcludeClass. Nous permettant si le cas se présent d'hériter du singleton :

// Fichier LoggerImpl.as
package formation.iteratif.logging
{
	[ExcludeClass]
	public class LoggerImpl {
		public function LoggerImpl() {
 
		}
 
		public function log(msg:String):void {
			trace(msg);
		}
	}
}
 
// Fichier Logger.as
package iteratif.logging {
	public const Logger:LoggerImpl = new LoggerImpl();
}

Le metadata ne fait qu'exclure la classe de la complétion de code de l'éditeur Flex builder, bien entendu si vous connaissez le chemin vers cette classe, rien ne vous empêches de l'instancier.

Mise a jour de l'implémentation du Singleton

Il est possible aussi d'utiliser le namespace internal pour réduire la visibilité d'une classe à un package, du coup plus besoin d'un metadata propre au compilateur Flex, ex :

// Fichier LoggerImpl.as
package formation.iteratif.logging
{
	internal class LoggerImpl {
		public function LoggerImpl() {
 
		}
 
		public function log(msg:String):void {
			trace(msg);
		}
	}
}

Cette classe est uniquement visible depuis le package formation.iteratif.logging.

Conclusion

Il est important de prendre en compte les spécificités du langage que vous utilisez et ce qui a été fait dans un langage ne l'est pas forcément pour un autre (mais tellement plus facile, n'est-ce pas…).