Prenons l'exemple d'une liste de contacts (VoIP un jour, VoIP toujours!), dans laquelle on peut sélectionner un contact. Le XML sera utilisé pour remplir cette liste, et un certain nombre d'actions peuvent être effectuées sur les contacts, mais la liste reste le seul moyen d'avoir des contacts: en gros, il est impossible de créer un contact via un constructeur de type new Contact(...).

L'utilisation conjointe des classes internes et des interfaces nous donnerai ceci: Une interface contact

package {

        /**
         * Contact public interface
         *
         * @author LAlex
         */

        public interface Contact {
                function sendMail(text:String) : void;
                function get firstName() : String;
                function get lastName() : String;
        }
}

Une classe ContactList et son implémentation de l'interface en tant que classe interne

package {

        /**
         * @author LAlex
         */

        public class ContactList {

                private var _contacts:Array = [];               
                private var _selectedContactPosition : int = -1;
               
                function ContactList(dP:XML = null) {
                        if (dP != null) {
                                setDataProvider(dP);
                        }
                }
               
                // Methods
               
                public function setDataProvider(x : XML) : void {
                        for each (var contactNode:XML in x.contacts.contact) {
                                _contacts.push(new ContactImpl(contactNode));
                        }
                }
               
                public function selectContactAt(ind : int = -1) : void {
                        if (ind < _contacts.length) {
                                _selectedContactPosition = ind;
                        }
                }
               
                public function get selectedContact() : Contact {
                        if (_selectedContactPosition != -1) {
                                return _contacts[_selectedContactPosition] as Contact;
                        }
                        return null;
                }
               
        }
}

// Contact interface implementation
internal class ContactImpl
        implements Contact {
       
        private var _firstName:String;
        private var _lastName:String;
       
        function ContactImpl(x : XML) {
                _firstName = x.@first;
                _lastName = x.@last;
                // Other initiation
        }
       
        public function sendMail(text : String) : void {
                // Mail sending implementation
        }
       
        public function get firstName() : String {
                return _firstName;
        }
       
        public function get lastName() : String {
                return _lastName;
        }
}

L'utilisation de cette classe donnerait:

var list : ContactList = new ContactList(<dataprovider><contacts><contact first="Alexandre" last="LEGOUT" /><contact first="Gérard" last="DUPONT" /></contacts></dataprovider>);
list.selectContactAt(1);

var selected : Contact = list.selectedContact;
trace(selected.firstName + " " + selected.lastName);

Et voilà, on a accès depuis l'extérieur de la classe à tous les comportements "publics" d'un contact, sans avoir accés à son implémentation! 8-)
Alors je sais que c'est justement le but des interfaces, mais j'ai trouvé cette utilisation intéressante, et assez représentative de l'utilité des interfaces, au cas où vous ne seriez pas encore convaincus... ;)